The runner stage ships the npm CLI bundled in node:22-alpine, whose
vendored dependencies carry known vulnerabilities that trivy flags on the
published postgresql-latest image:
usr/local/lib/node_modules/npm/node_modules/...
- sigstore 3.1.0 CVE-2026-48815 (HIGH)
- picomatch 4.0.3 CVE-2026-33671 (HIGH)
- @sigstore/core 2.0.0 CVE-2026-48758
- brace-expansion 2.0.2 CVE-2026-33750
- ip-address 10.1.0 CVE-2026-42338
- tar 7.5.11 CVE-2026-53655
npm is only a build-time bootstrap for pnpm; it is not needed at runtime.
Install pnpm with it, then remove npm in the same layer so none of these
vendored packages are present in the final image, and run the container
via pnpm instead of npm. pnpm (and corepack) remain and were never flagged.
The curl/libcurl/c-ares HIGH findings are resolved by rebuilding alone,
since Alpine 3.24 already serves curl 8.21.0-r0 / c-ares 1.34.8-r0 (the
published image is simply stale).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The container CMD ran `npm run start-docker`, i.e. `npm-run-all check-db
update-tracker start-server`. After the one-shot tasks exit, three Node VMs
stay resident for the container lifetime (npm -> npm-run-all -> npm ->
node server.js), each holding tens of MiB of anonymous memory for nothing.
Replace it with a small start script that runs the one-shot steps and then
`exec node server.js`, so the server becomes PID 1 and no launcher wrappers
remain. On a dev 3.2.0 build under realistic load the container RSS dropped
~28% (memory.stat anon 255 MiB -> 183 MiB); migrations still apply and
/api/heartbeat serves normally.