FROM node:22-alpine AS builder # Add build arguments ARG CACHEBUST=1 ARG BUILD_DATE ARG VCS_REF ARG VERSION # Add labels for GitHub Container Registry LABEL org.opencontainers.image.source="https://github.com/PicPeak/picpeak" LABEL org.opencontainers.image.description="PicPeak Backend Service" LABEL org.opencontainers.image.licenses="MIT" WORKDIR /app # Copy package files COPY package*.json ./ # Install dependencies (--omit=dev replaces deprecated --only=production) RUN npm ci --omit=dev # Copy application files COPY . . # Production stage FROM node:22-alpine WORKDIR /app # knexfile.js picks its config block by NODE_ENV, and the `development` block # defaults to sqlite3. Leaving NODE_ENV unset here meant every deployment that # doesn't go through our compose files — Kubernetes, Helm, plain `docker run` — # silently ran on SQLite and ignored DB_HOST/DB_USER/DB_PASSWORD, while # wait-for-db.sh (shell, reads DB_HOST directly) reported "PostgreSQL is up" in # the same log. The compose files still override this, so nothing changes for # compose users. See #1038. ENV NODE_ENV=production # Redeclare CACHEBUST — ARGs don't cross stage boundaries, so the builder # stage's declaration never reached this stage. Consuming it in the RUN below # busts that layer's cache every CI run (CACHEBUST=github.run_number), so the # image always picks up current Alpine security updates instead of reusing a # stale cached upgrade layer. ARG CACHEBUST=1 # Upgrade all packages to fix security vulnerabilities (OpenSSL, libexpat, BusyBox CVEs) RUN echo "cachebust=${CACHEBUST}" && apk upgrade --no-cache # Remove the npm CLI from the final image. Nothing runs npm here: the # entrypoint is node, runtime deps are COPY'd from the builder stage, and # wait-for-db.sh invokes the migration runners via node directly. npm's # bundled node_modules kept tripping Trivy (sigstore, tar 7.5.19, # brace-expansion 5.0.7 — even npm 12.0.1 still ships the vulnerable # copies), so shipping no npm ends that alert class instead of chasing # per-release patches. Note: `docker exec … npm run