# Multi-stage build: install → build web → slim runtime (docs/11-deployment-ops.md) FROM oven/bun:1.3 AS build WORKDIR /app COPY package.json bun.lock bunfig.toml tsconfig.base.json ./ COPY packages ./packages COPY apps ./apps RUN bun install --frozen-lockfile RUN cd apps/web && bunx vite build # Production-only dependencies (no vite/typescript/playwright in the runtime image). FROM oven/bun:1.3 AS deps WORKDIR /app COPY package.json bun.lock bunfig.toml ./ COPY packages/engine/package.json packages/engine/ COPY packages/shared/package.json packages/shared/ COPY packages/games/package.json packages/games/ COPY apps/server/package.json apps/server/ COPY apps/web/package.json apps/web/ RUN bun install --frozen-lockfile --production --filter '@bg/server' FROM oven/bun:1.3-slim WORKDIR /app ENV NODE_ENV=production PORT=3000 DB_PATH=/data/app.db TRUST_PROXY=1 COPY --from=deps /app/node_modules ./node_modules COPY --from=build /app/package.json ./package.json COPY --from=build /app/packages ./packages COPY --from=build /app/apps/server ./apps/server COPY --from=build /app/apps/web/dist ./apps/web/dist RUN mkdir -p /data && chown bun:bun /data USER bun VOLUME ["/data"] EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=3s --retries=3 CMD bun -e "fetch('http://localhost:3000/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))" STOPSIGNAL SIGTERM CMD ["bun", "apps/server/src/index.ts"]