Files
0pt/Dockerfile
T
SIAX Foundation Bot bd5e309851
CI (SIAX Cloud) / quality (push) Failing after 34s
CI (SIAX Cloud) / security (push) Failing after 36s
chore(foundation): Wave 1 scaffolding — CI gate / Dockerfile / .env.example
2026-07-20 00:01:37 +02:00

72 lines
3.2 KiB
Docker

# =============================================================================
# 0pt web console -- Dockerfile for Coolify (SIAX Cloud)
# =============================================================================
# This repo's deployable service is the Next.js 16 app at the repo root
# (package.json `start` == `next start`, liveness at GET /api/health). Unlike
# the tsx backend services elsewhere in the fleet (aud0/n0d/api0), a Next app
# needs a real build step, so this is a multi-stage build: install+build, then
# a slim runtime that runs the built output as the non-root `node` user.
#
# node:24-alpine matches the tag already proven in ../aud0 and ../api0. `wget`
# is added to the runtime stage so Coolify's container healthcheck has a binary
# to hit /api/health (bare node:*-alpine ships neither curl nor wget).
#
# next.config.mjs does NOT set `output: "standalone"` (that would be a source
# change, out of Wave-1 scope), so the runtime stage carries node_modules + the
# .next build output and runs `next start` directly.
# =============================================================================
# ---- build stage ------------------------------------------------------------
FROM node:24-alpine AS builder
WORKDIR /app
ENV NEXT_TELEMETRY_DISABLED=1
# Enable corepack (pnpm@9 pinned below to match pnpm-lock.yaml lockfileVersion 9.0).
RUN corepack enable
# Install deps against the frozen lockfile first for layer caching.
# --ignore-workspace: the repo's pnpm-workspace.yaml is a v0-export artifact that
# carries only an `allowBuilds:` block and NO `packages:` field, which makes pnpm
# abort with "packages field missing or empty". There are no real workspace
# members (only the root package.json), so ignoring the workspace file is
# semantically a no-op and lets the frozen install resolve the root deps cleanly.
COPY package.json pnpm-lock.yaml .npmrc ./
RUN corepack prepare pnpm@9 --activate && pnpm install --frozen-lockfile --ignore-workspace
# Build the app. The lib/* clients (db, stripe, ...) are lazy + env-guarded, so
# `next build` succeeds without any runtime secrets present.
# --ignore-workspace again here: `COPY . .` reintroduces the v0 pnpm-workspace.yaml,
# and `pnpm run` re-parses it (same "packages field missing" abort) unless ignored.
COPY . .
RUN pnpm --ignore-workspace run build
# ---- runtime stage ----------------------------------------------------------
FROM node:24-alpine AS runtime
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV HOSTNAME=0.0.0.0
ENV PORT=3000
RUN apk add --no-cache wget
# Built artifacts + resolved dependencies from the build stage. .next is chowned
# so `next start` can write its runtime cache as the non-root user.
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder --chown=node:node /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/next.config.mjs ./next.config.mjs
USER node
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD wget -qO- http://127.0.0.1:3000/api/health >/dev/null 2>&1 || exit 1
# Invoke the next binary directly (pnpm/corepack are not set up in this stage).
CMD ["node_modules/.bin/next", "start"]