mirror of
https://github.com/bdnugget/rs-sdk.git
synced 2026-11-07 09:07:30 +00:00
The gateway can also listen on GATEWAY_PUBLIC_PORT (on Fly: wss://rs-sdk-demo.fly.dev:7443 -> 7781) with permessage-deflate. On live bot state frames that is ~16% of the uncompressed bytes at ~6 ms CPU per MB, spent in the gateway process rather than on the game server's tick thread. The main port is unchanged and uncompressed, so the engine's /gateway relay and every existing SDK and runner behave exactly as before. SDK connect() and the lite runner check the direct port (3 s) and use it when it answers, otherwise they keep wss://.../gateway; a failed connect checks again. GATEWAY_DIRECT=false opts out. HTTP endpoints keep the relayed origin. GATEWAY_HOSTNAME lets a fleet run a private loopback gateway (sdk/README.md). sdk/chat.ts and the MCP server now honor a bot.env GATEWAY_URL, as cli.ts and runScript already did. The Dockerfile sed that forced 0.0.0.0 is replaced by that option's default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
119 lines
4.0 KiB
Docker
119 lines
4.0 KiB
Docker
# syntax=docker/dockerfile:1
|
|
FROM oven/bun:debian
|
|
|
|
# Install system deps with cache mount
|
|
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
|
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
|
apt update && apt install -y --no-install-recommends \
|
|
git ca-certificates bash sqlite3
|
|
|
|
WORKDIR /opt/server
|
|
|
|
# === DEPENDENCY LAYER (cached unless package files change) ===
|
|
|
|
# Copy only package files first
|
|
COPY server/engine/package.json server/engine/bun.lock /opt/server/engine/
|
|
COPY server/gateway/package.json server/gateway/bun.lock /opt/server/gateway/
|
|
COPY server/webclient/package.json server/webclient/bun.lock /opt/server/webclient/
|
|
|
|
# Install engine deps with bun cache mount
|
|
WORKDIR /opt/server/engine
|
|
RUN --mount=type=cache,target=/root/.bun/install/cache \
|
|
bun install
|
|
|
|
# Install gateway deps with bun cache mount
|
|
WORKDIR /opt/server/gateway
|
|
RUN --mount=type=cache,target=/root/.bun/install/cache \
|
|
bun install
|
|
|
|
# Install webclient deps with bun cache mount
|
|
WORKDIR /opt/server/webclient
|
|
RUN --mount=type=cache,target=/root/.bun/install/cache \
|
|
bun install
|
|
|
|
# === SOURCE LAYER (rebuilds on code changes, but deps cached) ===
|
|
|
|
WORKDIR /opt/server
|
|
|
|
# Copy source code
|
|
COPY server/content /opt/server/content
|
|
COPY server/webclient /opt/server/webclient
|
|
COPY server/engine /opt/server/engine
|
|
COPY server/gateway /opt/server/gateway
|
|
COPY sdk /opt/sdk
|
|
|
|
# Build webclient bundle (out/standard, out/bot, out/viewer). out/ is gitignored and
|
|
# NOT shipped from the local build context (see .dockerignore), so it must be built
|
|
# here — otherwise the engine would serve a stale or missing client. The engine serves
|
|
# this from ../webclient/out relative to its CWD (i.e. /opt/server/webclient/out).
|
|
WORKDIR /opt/server/webclient
|
|
RUN bun run build
|
|
|
|
# Patch and build engine
|
|
# 274 removed .env.example; runtime config now comes from process.env (overlaid in
|
|
# Environment.ts) / data/config/world.json, so no .env file is needed at build time.
|
|
WORKDIR /opt/server/engine
|
|
RUN sed -i 's/port: Environment.WEB_PORT,/port: Environment.WEB_PORT, hostname: "0.0.0.0",/' src/web/index.ts && \
|
|
BUILD_VERIFY=false bun run build
|
|
|
|
WORKDIR /opt/server
|
|
|
|
EXPOSE 8080/tcp
|
|
EXPOSE 43594/tcp
|
|
EXPOSE 7780/tcp
|
|
|
|
# Entrypoint script to ensure persistent data is on the volume
|
|
COPY --chmod=755 <<'EOF' /opt/server/entrypoint.sh
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
# === DATABASE ===
|
|
# Symlink db.sqlite to persistent volume
|
|
if [ ! -L /opt/server/engine/db.sqlite ]; then
|
|
rm -f /opt/server/engine/db.sqlite
|
|
ln -s /opt/server/data/db.sqlite /opt/server/engine/db.sqlite
|
|
fi
|
|
|
|
# Run migrations (idempotent - only applies pending migrations)
|
|
echo "Running database migrations..."
|
|
cd /opt/server/engine && bun run sqlite:migrate
|
|
|
|
# === PLAYER SAVES ===
|
|
# Create players directory on volume if it doesn't exist
|
|
mkdir -p /opt/server/data/players
|
|
|
|
# If there are existing player saves in ephemeral storage, move them to volume
|
|
if [ -d /opt/server/engine/data/players ] && [ ! -L /opt/server/engine/data/players ]; then
|
|
# Copy any existing saves to volume (won't overwrite existing)
|
|
cp -rn /opt/server/engine/data/players/* /opt/server/data/players/ 2>/dev/null || true
|
|
rm -rf /opt/server/engine/data/players
|
|
fi
|
|
|
|
# Create symlink for player saves
|
|
mkdir -p /opt/server/engine/data
|
|
if [ ! -L /opt/server/engine/data/players ]; then
|
|
rm -rf /opt/server/engine/data/players
|
|
ln -s /opt/server/data/players /opt/server/engine/data/players
|
|
fi
|
|
|
|
# === START GATEWAY SERVICE ===
|
|
# Supervised: the engine runs as PID 1, so if the gateway dies the container stays
|
|
# "healthy" while SDK connectivity is silently dead until a redeploy. Respawn it
|
|
# instead, with a short backoff so a crash-on-boot can't spin the CPU.
|
|
echo "Starting gateway service on port 7780..."
|
|
(
|
|
cd /opt/server/gateway
|
|
while true; do
|
|
bun run gateway.ts
|
|
echo "[entrypoint] Gateway exited (code $?), restarting in 2s..." >&2
|
|
sleep 2
|
|
done
|
|
) &
|
|
|
|
# === START GAME SERVER ===
|
|
cd /opt/server/engine
|
|
exec bun run src/app.ts
|
|
EOF
|
|
|
|
CMD ["/opt/server/entrypoint.sh"]
|