Initial PHP rebuild of the app
This commit is contained in:
690 files changed
+33944
-12046
No files matched your search
@@ -0,0 +1,82 @@
|
||||
# Multi-stage build. NextChair is the internal project/image name only —
|
||||
# see docs/phase-8-summary.md's white-label section for why that's fine
|
||||
# here (Docker/package names are explicitly "internal and acceptable")
|
||||
# even though the running application never shows that name to a user.
|
||||
#
|
||||
# Prisma 7 uses driver adapters (@prisma/adapter-mariadb), not a native
|
||||
# Rust query-engine binary — the generated client is pure JS, so this
|
||||
# image needs no special native-binary handling the way older Prisma
|
||||
# versions on Alpine sometimes did.
|
||||
#
|
||||
# `output: "standalone"` in next.config.ts was deliberately NOT enabled:
|
||||
# this image runs `prisma migrate deploy` (and, for the optional seed
|
||||
# service, `tsx prisma/seed.ts`) at container start, both of which need
|
||||
# the full `prisma`/`tsx` CLIs and their dependencies present — a pruned
|
||||
# standalone bundle would need those re-added anyway, so a single
|
||||
# `npm ci` (full dependencies, including the small set of dev tools this
|
||||
# image actually runs) is simpler and no less correct. See
|
||||
# docs/phase-8-summary.md, "Docker image quality" for this trade-off.
|
||||
|
||||
FROM node:22-alpine AS deps
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
|
||||
FROM node:22-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
# `npm run build` runs `prisma generate` itself (see package.json — needed
|
||||
# so a plain Vercel/`npm run build` deploy generates the client too, not
|
||||
# just this Docker path, which used to have its own separate `prisma
|
||||
# generate` step here).
|
||||
# `next build`'s page-data collection step imports every route module
|
||||
# (including /api/health) to inspect it — that pulls in
|
||||
# src/lib/db/prisma.ts, which requires DATABASE_HOST/NAME/USER/PASSWORD
|
||||
# just to construct its connection-pool config object, even though nothing
|
||||
# actually connects at build time. These placeholders only exist to
|
||||
# satisfy that check; the real values are supplied at container runtime
|
||||
# via env_file (see docker-compose.local.yaml) and these are never used to
|
||||
# connect to anything or baked into a layer that matters.
|
||||
RUN DATABASE_HOST="localhost" \
|
||||
DATABASE_PORT="3306" \
|
||||
DATABASE_NAME="build" \
|
||||
DATABASE_USER="build" \
|
||||
DATABASE_PASSWORD="build" \
|
||||
npm run build
|
||||
|
||||
FROM node:22-alpine AS runner
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
|
||||
# Non-root — see the brief's "Docker image quality: non-root user."
|
||||
RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nextchair
|
||||
|
||||
COPY --from=builder --chown=nextchair:nodejs /app/node_modules ./node_modules
|
||||
COPY --from=builder --chown=nextchair:nodejs /app/.next ./.next
|
||||
COPY --from=builder --chown=nextchair:nodejs /app/public ./public
|
||||
COPY --from=builder --chown=nextchair:nodejs /app/generated ./generated
|
||||
COPY --from=builder --chown=nextchair:nodejs /app/prisma ./prisma
|
||||
COPY --from=builder --chown=nextchair:nodejs /app/src ./src
|
||||
COPY --from=builder --chown=nextchair:nodejs /app/scripts ./scripts
|
||||
COPY --from=builder --chown=nextchair:nodejs /app/package.json ./package.json
|
||||
COPY --from=builder --chown=nextchair:nodejs /app/prisma.config.ts ./prisma.config.ts
|
||||
COPY --from=builder --chown=nextchair:nodejs /app/next.config.ts ./next.config.ts
|
||||
COPY --from=builder --chown=nextchair:nodejs /app/tsconfig.json ./tsconfig.json
|
||||
COPY --chown=nextchair:nodejs docker/entrypoint.sh ./docker/entrypoint.sh
|
||||
RUN chmod +x ./docker/entrypoint.sh
|
||||
# Media Manager uploads (Phase 10) — storage/media (NOT public/) is a
|
||||
# named volume mount point (see docker-compose.local.yaml). Served by
|
||||
# src/app/api/media/[...path]/route.ts, not Next's static handling for
|
||||
# public/ — verified against a real production build that runtime-added
|
||||
# public/ files 404 (Next resolves public assets at build time, not from
|
||||
# a live filesystem check). Creating this here, owned by the non-root
|
||||
# user, before the volume first attaches means Docker initializes the
|
||||
# volume with this ownership rather than root's.
|
||||
RUN mkdir -p ./storage/media && chown -R nextchair:nodejs ./storage
|
||||
|
||||
USER nextchair
|
||||
EXPOSE 3000
|
||||
ENV PORT=3000
|
||||
|
||||
ENTRYPOINT ["./docker/entrypoint.sh"]
|
||||
Reference in new issue
Block a user