From 95fb688910ef7d08c41f6147d6543ee66ee6731d Mon Sep 17 00:00:00 2001 From: pavel444-byte Date: Wed, 19 Aug 2026 14:43:50 +0500 Subject: [PATCH] Add Dockerfile to build and run the project in Docker Co-authored-by: multica-agent --- Dockerfile | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c079679 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,77 @@ +# syntax=docker/dockerfile:1 +# +# Dungeons & Ground — production image. +# +# Build: docker build -t dungeons-ground . +# Run: docker run --env-file .env -p 3000:3000 dungeons-ground +# +# Required env vars at runtime (see .env.example): +# NUXT_PUBLIC_SUPABASE_URL, SUPABASE_URL, NUXT_PUBLIC_SUPABASE_ANON_KEY, +# SUPABASE_SERVICE_ROLE_KEY, plus the AI provider key (OPENROUTER_API_KEY +# or DEEPSEEK_API_KEY). REDIS_URL is optional. +# The Supabase schema is NOT created by the container; install +# supabase/bootstrap.sql (or run `pnpm db:ensure` with SUPABASE_DB_URL set) +# in your Supabase project before starting. + +FROM node:18.20.8-slim AS base + +ENV PNPM_HOME=/pnpm +ENV PATH=$PNPM_HOME:$PATH +RUN corepack enable && corepack prepare pnpm@10.15.0 --activate + +WORKDIR /app + +# ---------- Dependencies ---------- +FROM base AS deps + +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ +COPY apps/web/package.json apps/web/package.json +COPY apps/worker/package.json apps/worker/package.json +COPY packages/shared/package.json packages/shared/package.json +COPY packages/game-engine/package.json packages/game-engine/package.json + +RUN pnpm install --frozen-lockfile + +# ---------- Build ---------- +FROM deps AS build + +COPY . . +# The web build explicitly loads ../../.env (--dotenv); an empty file keeps +# the build hermetic — all real values come from container env at runtime. +RUN touch .env && pnpm --filter @dng/web build + +# ---------- Runtime ---------- +FROM base AS runtime + +ENV NODE_ENV=production +ENV HOST=0.0.0.0 +ENV PORT=3000 + +WORKDIR /app + +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ +COPY apps/web/package.json apps/web/package.json +COPY apps/worker/package.json apps/worker/package.json +COPY packages/shared/package.json packages/shared/package.json +COPY packages/game-engine/package.json packages/game-engine/package.json + +COPY --from=deps /app/node_modules node_modules +COPY --from=build /app/apps/web/.output apps/web/.output +COPY --from=build /app/apps/worker apps/worker +COPY --from=build /app/packages/shared packages/shared +COPY --from=build /app/packages/game-engine packages/game-engine + +EXPOSE 3000 + +HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ + CMD node -e "fetch('http://127.0.0.1:3000/').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))" + +# The Nuxt web server reads its config through Nuxt runtimeConfig, which is +# baked at build time and overridden at runtime only by NUXT_-prefixed env +# vars; the worker reads plain names (SUPABASE_URL, OPENROUTER_API_KEY, ...) +# directly. The entrypoint maps the plain .env.example names onto the NUXT_ +# runtime overrides so `docker run --env-file .env` works for both processes. +# The web server runs in the foreground (PID 1); the AI worker runs alongside +# it in the background. Stop the container with `docker stop` — both die with +# it. +CMD ["sh", "-c", "export NUXT_SUPABASE_URL=\"${NUXT_SUPABASE_URL:-${SUPABASE_URL:-}}\" NUXT_SUPABASE_SERVICE_ROLE_KEY=\"${NUXT_SUPABASE_SERVICE_ROLE_KEY:-${SUPABASE_SERVICE_ROLE_KEY:-}}\" NUXT_AI_PROVIDER=\"${NUXT_AI_PROVIDER:-${AI_PROVIDER:-}}\" NUXT_OPENROUTER_API_KEY=\"${NUXT_OPENROUTER_API_KEY:-${OPENROUTER_API_KEY:-}}\" NUXT_OPENROUTER_MODEL=\"${NUXT_OPENROUTER_MODEL:-${OPENROUTER_MODEL:-}}\" NUXT_OPENROUTER_API_ENDPOINT=\"${NUXT_OPENROUTER_API_ENDPOINT:-${OPENROUTER_API_ENDPOINT:-}}\" NUXT_DEEPSEEK_API_KEY=\"${NUXT_DEEPSEEK_API_KEY:-${DEEPSEEK_API_KEY:-}}\" NUXT_DEEPSEEK_MODEL=\"${NUXT_DEEPSEEK_MODEL:-${DEEPSEEK_MODEL:-}}\" NUXT_DEEPSEEK_API_ENDPOINT=\"${NUXT_DEEPSEEK_API_ENDPOINT:-${DEEPSEEK_API_ENDPOINT:-}}\" NUXT_REDIS_URL=\"${NUXT_REDIS_URL:-${REDIS_URL:-}}\"; pnpm --filter @dng/worker start & exec node apps/web/.output/server/index.mjs"]