# syntax=docker/dockerfile:1
# Pin the runtime to the supported engine; update both stages deliberately.
FROM node:26.8.1-alpine AS migrations
WORKDIR /app
ENV NEXT_TELEMETRY_DISABLED=1
# Keep the bootstrap aligned with package.json packageManager.
RUN apk add --no-cache git \
    && npm install -g pnpm@11.25.0
# pnpm-workspace.yaml + .npmrc must be present too: the lockfile records the
# overrides from pnpm-workspace.yaml, and --frozen-lockfile rejects a build
# where the workspace config is absent (ERR_PNPM_LOCKFILE_CONFIG_MISMATCH).
COPY package.json pnpm-lock.yaml* pnpm-workspace.yaml* .npmrc* ./
# pnpm fetch: download all deps into $PNPM_STORE first, so only the lockfile
# change (not source changes) invalidates the network-heavy download layer.
RUN pnpm fetch --ignore-scripts
RUN pnpm install --frozen-lockfile --ignore-scripts --offline
COPY . .
FROM migrations AS builder
ARG NEXT_DEPLOYMENT_ID="unknown"
ENV NEXT_DEPLOYMENT_ID="$NEXT_DEPLOYMENT_ID"
# Fixture values exist only for this build command; production secrets are runtime-only.
RUN DATABASE_URL="mysql://build:build@127.0.0.1:9/build" \
    HOTEL_NAME="Build fixture" APP_URL="http://localhost:3002" \
    AUTH_SECRET="build-fixture-not-for-runtime-use-000000000000" \
    pnpm run build

FROM node:26.8.1-alpine AS runner
ARG NEXT_DEPLOYMENT_ID="unknown"
LABEL org.opencontainers.image.revision="$NEXT_DEPLOYMENT_ID"
WORKDIR /app
ENV NODE_ENV=production \
    NEXT_TELEMETRY_DISABLED=1 \
    PORT=3002 \
    HOSTNAME=0.0.0.0
RUN apk add --no-cache tini \
    && addgroup -g 33 -S nextjs && adduser -u 33 -S -G nextjs nextjs \
    && mkdir -p /app/storage /app/public/nitro-assets /app/public/swf /var/www/Gamedata \
    && chown -R 33:33 /app/storage /app/public /var/www/Gamedata
COPY --from=builder --chown=nextjs:nextjs /app/public ./public
COPY --from=builder --chown=nextjs:nextjs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nextjs /app/.next/static ./.next/static
COPY --chown=nextjs:nextjs scripts/docker-start.mjs ./docker-start.mjs
USER nextjs
EXPOSE 3002
# Self-contained healthcheck so `docker run` (ci-deploy) also gets Docker-level
# health; docker-compose overrides this with its own probe if needed.
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
    CMD ["node", "-e", "fetch('http://127.0.0.1:'+(process.env.PORT||'3002')+'/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "docker-start.mjs"]