bac97674a1
CI / test (push) Successful in 25s
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 11s
CI / build-images (push) Successful in 1m47s
CI / push (push) Successful in 30s
CI / image-scan (push) Successful in 43s
Two production-only failures the CI scan didn't catch: Backend: the running container was crashing with `Cannot find module '/app/dist/main'`. nest build was emitting `dist/src/main.js` instead of `dist/main.js` because tsconfig.json had no rootDir, so tsc inferred it as `.` and preserved the src/ subdirectory in the output. Set `rootDir: "./src"` to flatten the output. Also exclude prisma/ from tsconfig.build.json so prisma/seed.ts (a ts-node script that lives outside src/) doesn't trip the rootDir check during builds. Frontend: containers came up but were marked unhealthy because the deployment's healthcheck targeted port 80 — which nginx-unprivileged can't bind. Add a HEALTHCHECK directive to the image pointing at 8080 so any orchestrator inherits a working default. Compose-level overrides still need to be updated independently. Also clean up build-artifact gitignore patterns: *.tsbuildinfo and compiled prisma/seed.* (a stale tsc invocation against the old build config emitted them locally; they shouldn't ever be committed). Bump backend and frontend to 0.1.3 — the broken 0.1.2 images are now occupying those tags in Harbor. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
39 lines
2.0 KiB
Docker
39 lines
2.0 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
ARG NODE_VERSION=20
|
|
|
|
FROM node:${NODE_VERSION}-alpine AS deps
|
|
RUN corepack enable && corepack prepare pnpm@9 --activate
|
|
WORKDIR /repo
|
|
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./
|
|
COPY tehriehlbudget-backend/package.json 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-frontend...
|
|
|
|
FROM deps AS build
|
|
WORKDIR /repo
|
|
COPY tehriehlbudget-frontend/ tehriehlbudget-frontend/
|
|
# Build with no VITE_* env: import.meta.env values resolve to "" so the bundle
|
|
# carries no compile-time secrets. window.__RUNTIME_CONFIG__ supplies them.
|
|
RUN pnpm --filter tehriehlbudget-frontend run build
|
|
|
|
FROM nginxinc/nginx-unprivileged:1.27-alpine AS runtime
|
|
USER root
|
|
# Pull current Alpine package patches before adding anything else. The
|
|
# base image lags behind upstream Alpine's security backports (openssl,
|
|
# libxml2, libpng, musl, etc. were all flagged HIGH/CRITICAL on the
|
|
# stock 3.21.3 packages). `apk upgrade` picks up the fixed -r versions
|
|
# without bumping the nginx version itself.
|
|
RUN apk upgrade --no-cache && apk add --no-cache gettext
|
|
COPY --from=build --chown=nginx:nginx /repo/tehriehlbudget-frontend/dist /usr/share/nginx/html
|
|
COPY --chown=nginx:nginx tehriehlbudget-frontend/nginx.conf /etc/nginx/conf.d/default.conf
|
|
COPY --chown=nginx:nginx tehriehlbudget-frontend/docker-entrypoint.sh /docker-entrypoint.d/40-render-config.sh
|
|
RUN chmod +x /docker-entrypoint.d/40-render-config.sh
|
|
USER nginx
|
|
EXPOSE 8080
|
|
# nginx-unprivileged can't bind privileged ports; the image listens on 8080,
|
|
# so a healthcheck targeting :80 will always fail. Bake in a sensible default
|
|
# that any orchestrator (compose, k8s, Portainer) inherits unless overridden.
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
CMD wget -qO /dev/null http://127.0.0.1:8080/ || exit 1
|