mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-25 17:12:43 +00:00
c55ea6bb5a
## What Game creation no longer requires the caller to pick the `gameID` or compute its owning worker. The client POSTs to a prefix-less `/api/create_game`; **nginx (prod) and the vite dev proxy randomly route it to a worker**, which **mints an id that hashes back to itself** and returns it along with its `workerIndex`. ## Why it stays correct The minted id still hashes to the creating worker (via the existing `generateGameIdForWorker`), so everything downstream that derives the worker from the gameID — websocket connect, share URL, join flow — keeps working unchanged. The only thing that moved is *who picks the id and worker*. ## Changes - **`src/server/Worker.ts`** — factor create into a shared `createGameForId`; add `POST /api/create_game` (no id) that mints a self-owned id and returns `gameInfo` + `workerIndex`/`workerPath`. The existing `POST /api/create_game/:id` stays. - **`nginx.conf`** — `location = /api/create_game` proxies to a `random` worker upstream. - **`generate-nginx-upstream.sh` + `Dockerfile`** — the entrypoint generates that upstream from `NUM_WORKERS` at container **start** time. `NUM_WORKERS` isn't known at image build time (the image is built once and deployed with different env), so it can't be baked into `nginx.conf` — hence runtime generation of exactly the live worker ports (no dead-server padding). - **`vite.config.ts`** — dev-only middleware forwards `POST /api/create_game` to a random worker. Vite's `http-proxy` can't pick a per-request random target, so this is a small middleware plugin (same pattern as the existing `serveProprietaryDir`), registered before the `/api` proxy. - **`src/client/HostLobbyModal.ts`** — stop generating the id client-side; use the server's. ## Behavior change to note The host's share link used to be copied **instantly** from a client-generated id. Now the id comes from the server, so the copy waits one create round-trip — I moved the URL build/copy into the create `.then` (and kept the failure path that clears the clipboard). Brief empty-link state in the modal until create resolves. ## Verification - tsc + eslint clean; full suite green (1543 tests). - nginx additions validated with `nginx -t` in isolation (the full file references container-only paths like `/etc/nginx/mime.types`); upstream + `proxy_pass` resolve. - `generate-nginx-upstream.sh` tested with `NUM_WORKERS` set and unset (defaults to 1). Not yet exercised live end-to-end (needs a dev-server restart — `vite.config.ts` + `Worker.ts` changes aren't hot-reloaded). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
94 lines
2.5 KiB
Docker
94 lines
2.5 KiB
Docker
# Use an official Node runtime as the base image
|
|
FROM node:24-slim AS base
|
|
WORKDIR /usr/src/app
|
|
|
|
# Build stage - install ALL dependencies and build
|
|
FROM base AS build
|
|
ENV HUSKY=0
|
|
# Copy package files first for better caching
|
|
COPY package*.json ./
|
|
RUN --mount=type=cache,target=/root/.npm \
|
|
npm ci
|
|
|
|
# Copy only what's needed for build
|
|
COPY tsconfig.json ./
|
|
COPY vite.config.ts ./
|
|
COPY eslint.config.js ./
|
|
COPY index.html ./
|
|
COPY resources ./resources
|
|
COPY proprietary ./proprietary
|
|
COPY src ./src
|
|
|
|
ARG GIT_COMMIT=unknown
|
|
ENV GIT_COMMIT="$GIT_COMMIT"
|
|
RUN npm run build-prod
|
|
|
|
# Production dependencies stage - separate from build
|
|
FROM base AS prod-deps
|
|
ENV HUSKY=0
|
|
ENV NPM_CONFIG_IGNORE_SCRIPTS=1
|
|
COPY package*.json ./
|
|
RUN --mount=type=cache,target=/root/.npm \
|
|
npm ci --omit=dev
|
|
|
|
# Final production image
|
|
FROM base
|
|
|
|
# Install system dependencies
|
|
RUN apt-get update && apt-get install -y \
|
|
nginx \
|
|
curl \
|
|
wget \
|
|
supervisor \
|
|
apache2-utils \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Update worker_connections in nginx.conf
|
|
RUN sed -i 's/worker_connections [0-9]*/worker_connections 8192/' /etc/nginx/nginx.conf
|
|
|
|
# Setup supervisor configuration
|
|
RUN mkdir -p /var/log/supervisor
|
|
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
|
|
|
# Copy Nginx configuration
|
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
|
RUN rm -f /etc/nginx/sites-enabled/default
|
|
|
|
# Script that generates the create-game worker upstream at container start.
|
|
COPY generate-nginx-upstream.sh /usr/local/bin/generate-nginx-upstream.sh
|
|
RUN chmod +x /usr/local/bin/generate-nginx-upstream.sh
|
|
|
|
# Copy production node_modules from prod-deps stage (cached separately from build)
|
|
COPY --from=prod-deps /usr/src/app/node_modules ./node_modules
|
|
COPY package*.json ./
|
|
|
|
# Copy built artifacts from build stage
|
|
COPY --from=build /usr/src/app/static ./static
|
|
|
|
COPY resources ./resources
|
|
|
|
# Remove maps because they are not used by the server.
|
|
RUN rm -rf ./resources/maps
|
|
COPY tsconfig.json ./
|
|
COPY src ./src
|
|
|
|
|
|
ARG GIT_COMMIT=unknown
|
|
RUN echo "$GIT_COMMIT" > static/commit.txt
|
|
|
|
ENV GIT_COMMIT="$GIT_COMMIT"
|
|
|
|
RUN <<'EOF' tee /usr/local/bin/start.sh
|
|
#!/bin/sh
|
|
# Generate the create-game nginx upstream from NUM_WORKERS before nginx starts.
|
|
/usr/local/bin/generate-nginx-upstream.sh
|
|
|
|
if [ "$DOMAIN" = openfront.dev ] && [ "$SUBDOMAIN" != main ]; then
|
|
exec timeout 25h /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
|
|
else
|
|
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
|
|
fi
|
|
EOF
|
|
RUN chmod +x /usr/local/bin/start.sh
|
|
ENTRYPOINT ["/usr/local/bin/start.sh"]
|