batchCooking/apps/api/Dockerfile
Nicolas fff8c0da26 fix(api): seed reference data (diets/allergies) on container start
Found on http://batch.dev.kyuno.fr/: GET /reference/diets and
/reference/allergies both returned [] — onboarding's "régime
alimentaire" step and the profile's food-preferences tab had nothing to
show. Cause: the Docker image's CMD only ran `prisma migrate deploy`
(schema), never the seed that populates Diet/Category/Allergy.

Adds src/scripts/seed-runtime.ts — a runtime-only seed entry point
(distinct from prisma/seed.ts, the dev-time one wired to `prisma db
seed`/`prisma migrate reset` via tsx importing from ../src, which isn't
shipped in the runtime image). This one lives under src/ so tsc compiles
it into dist/ alongside everything else, and runs via plain `node`,
reusing the same idempotent seedReferenceData() (upserts by unique name)
already used by prisma/seed.ts and test-support/reset-db.ts.

Dockerfile CMD now runs it between migrate deploy and starting the
server — safe on every container start/restart, confirmed idempotent
locally (no duplicates, no error on a second run against an
already-seeded database).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 00:04:14 +02:00

49 lines
2.6 KiB
Docker

# Debian-based (not alpine) on purpose: avoids musl-vs-glibc native binding
# surprises for argon2/Prisma's engine binaries. Same base image family for
# build and runtime stages, so "native" binaries built in `build` are
# guaranteed compatible with `runtime`.
FROM node:22-slim AS base
# Prisma's query engine needs OpenSSL to be present to detect the right
# binary target; without it, it silently defaults to a guess (openssl-1.1.x)
# that may not match what's actually on the image and fail at runtime.
RUN apt-get update && apt-get install -y --no-install-recommends openssl && rm -rf /var/lib/apt/lists/*
RUN corepack enable
WORKDIR /repo
# Single image serving both the API and the built frontend (apps/web) — one
# process, one container, no separate nginx/static host. Builds both so the
# runtime stage below can copy each app's build output independently.
FROM base AS build
COPY . .
RUN pnpm install --frozen-lockfile
RUN pnpm --filter api build
RUN pnpm --filter web build
# Copies the monorepo structure as-is (not a flattened single package) so
# pnpm's symlinked node_modules (root node_modules/.pnpm <- apps/api/node_modules)
# stay valid — paths must match exactly between build and runtime stages.
FROM base AS runtime
ENV NODE_ENV=production
# Tells the API where to find the built frontend — see FRONTEND_DIST_DIR's
# doc comment in apps/api/src/config/env.ts.
ENV FRONTEND_DIST_DIR=/repo/apps/web/dist
COPY --from=build /repo/node_modules ./node_modules
COPY --from=build /repo/package.json ./package.json
COPY --from=build /repo/pnpm-workspace.yaml ./pnpm-workspace.yaml
COPY --from=build /repo/packages/shared ./packages/shared
COPY --from=build /repo/packages/error-tools ./packages/error-tools
COPY --from=build /repo/packages/express-tools ./packages/express-tools
COPY --from=build /repo/packages/date-tools ./packages/date-tools
COPY --from=build /repo/apps/api/node_modules ./apps/api/node_modules
COPY --from=build /repo/apps/api/dist ./apps/api/dist
COPY --from=build /repo/apps/api/prisma ./apps/api/prisma
COPY --from=build /repo/apps/api/package.json ./apps/api/package.json
COPY --from=build /repo/apps/web/dist ./apps/web/dist
WORKDIR /repo/apps/api
EXPOSE 3000
# Applies pending migrations, then seeds the reference data (Diet/Category/
# Allergy — see src/scripts/seed-runtime.ts) before starting. Both steps are
# safe to repeat on every container start: migrate deploy only applies
# pending migrations, and the seed upserts by unique name.
CMD ["sh", "-c", "node_modules/.bin/prisma migrate deploy && node dist/scripts/seed-runtime.js && node dist/server.js"]