4c84d2fb96
CI / test (push) Successful in 31s
CI / lint (push) Successful in 27s
CI / secrets-scan (push) Successful in 5s
CI / vuln-scan (push) Successful in 13s
CI / sast (push) Successful in 9s
CI / build-images (push) Successful in 1m51s
CI / image-scan (push) Successful in 44s
CI / push (push) Successful in 32s
The deployed backend was crashing at startup with `Node.js 20 detected without native WebSocket support` from @supabase/realtime-js. Native WebSocket landed in Node 22.4 — bumping the base image is cleaner than shimming `ws` as a transport (no extra dep, no constructor wrapper). Bumped in three places to keep everything aligned: - tehriehlbudget-backend/Dockerfile (runtime + build stages) - tehriehlbudget-frontend/Dockerfile (build stage; nginx runtime unaffected) - .gitea/workflows/ci.yml (test + lint jobs use the same Node) @types/node is already on ^22.10.7, so no type-side changes needed. Bump backend and frontend to 0.1.6 (frontend forced by per-service push gate; no functional change). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
57 lines
2.5 KiB
Docker
57 lines
2.5 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
ARG NODE_VERSION=22
|
|
|
|
FROM node:${NODE_VERSION}-alpine AS builder
|
|
RUN apk add --no-cache libc6-compat openssl
|
|
RUN corepack enable && corepack prepare pnpm@9 --activate
|
|
WORKDIR /repo
|
|
# Hoisted layout so `prisma generate` writes to predictable paths
|
|
# (/repo/node_modules/{@prisma,.prisma}/) instead of into .pnpm/<hash>/.
|
|
# Local dev keeps the isolated layout — this .npmrc only exists in the
|
|
# build context.
|
|
RUN echo "node-linker=hoisted" > /repo/.npmrc
|
|
|
|
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./
|
|
COPY tehriehlbudget-backend/ tehriehlbudget-backend/
|
|
COPY tehriehlbudget-frontend/package.json tehriehlbudget-frontend/
|
|
|
|
RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store \
|
|
pnpm install --frozen-lockfile --filter tehriehlbudget-backend...
|
|
|
|
RUN pnpm --filter tehriehlbudget-backend exec prisma generate
|
|
RUN pnpm --filter tehriehlbudget-backend run build
|
|
|
|
# pnpm deploy produces a self-contained prod-only bundle for the backend:
|
|
# only the dependencies the runtime actually needs, no frontend tooling,
|
|
# no devDeps. Drops vite, vitest, react, the whole NestJS CLI etc. that
|
|
# were leaking into the runtime via the workspace's hoisted node_modules.
|
|
RUN pnpm --filter tehriehlbudget-backend --prod deploy /deploy
|
|
|
|
# pnpm deploy pulls a fresh @prisma/client from the pnpm store, which ships
|
|
# with an unpopulated `.prisma/client/index.js` stub (it throws "did not
|
|
# initialize yet" if loaded). Re-run `prisma generate` against the deploy
|
|
# tree so the schema-specific client (enums, models, etc.) lands in
|
|
# /deploy/node_modules/.prisma/client. The CLI is a devDep so it's not in
|
|
# /deploy — invoke it from /repo where the full install still has it.
|
|
RUN cd /deploy && /repo/node_modules/.bin/prisma generate \
|
|
--schema=./prisma/schema.prisma
|
|
|
|
FROM node:${NODE_VERSION}-alpine AS runtime
|
|
RUN apk add --no-cache libc6-compat openssl tini \
|
|
# Remove the npm CLI that ships with node:alpine. We use pnpm via
|
|
# corepack at build time and `node dist/main` at runtime — npm is
|
|
# never invoked. Its bundled deps (cross-spawn, glob, minimatch,
|
|
# tar) are the source of 11 of the 12 HIGH/CRITICAL CVEs Trivy flags
|
|
# in the image, and they're all in code paths we never execute.
|
|
&& rm -rf /usr/local/lib/node_modules/npm \
|
|
/usr/local/bin/npm \
|
|
/usr/local/bin/npx
|
|
WORKDIR /app
|
|
RUN addgroup -S nodeapp && adduser -S nodeapp -G nodeapp
|
|
ENV NODE_ENV=production
|
|
COPY --from=builder --chown=nodeapp:nodeapp /deploy/ ./
|
|
USER nodeapp
|
|
EXPOSE 3000
|
|
ENTRYPOINT ["/sbin/tini", "--"]
|
|
CMD ["node", "dist/main"]
|