Files
EventSnap/frontend/Dockerfile
MechaCat02 a895bebdc2 harden(deploy): close public DB exposure + make JWT prod guard effective
Two HIGH deployment fixes found in the go-live review, plus two cheap backstops.

HIGH 1 — Postgres was published to the public internet. The committed,
auto-merged docker-compose.override.yml mapped 5432:5432 on 0.0.0.0 (and a
Docker publish bypasses ufw), so a `docker compose up` on the prod host exposed
the DB with the .env password. Bind the dev port to 127.0.0.1 so it's reachable
only from the host's loopback even when the override lands in prod. .env.example
also stops shipping `secret` as the DB password (now CHANGE_ME_*).

HIGH 2 — the JWT-secret production guard was inert. APP_ENV was never set to
production (defaulted to development), so the guard never ran; and it only
matched one stale dev sentinel, not the `.env.example` placeholder that an
operator is most likely to leave in place. Now: docker-compose.yml forces
APP_ENV=production on the app service, and config.rs refuses to boot in
production on any placeholder (change/example/placeholder/replace) or any secret
< 64 chars. Verified: placeholder and short secrets are rejected; a 128-char
secret passes. This turns "looks protected" into actually protected.

Backstops:
- frontend container now runs as the non-root `node` user (the backend was
  already hardened; the frontend wasn't).
- app gets mem_limit 3g so a miss in the in-app upload RAM caps OOM-kills the
  container instead of the 8 GB host.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 17:35:57 +02:00

26 lines
530 B
Docker

# --- Build stage ---
FROM node:22-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
# --- Runtime stage ---
FROM node:22-alpine
WORKDIR /app
COPY --from=builder /app/build ./build
COPY --from=builder /app/package.json ./
RUN npm install --omit=dev
# Run as the image's built-in unprivileged `node` user (defense-in-depth). The
# adapter-node server only reads from /app, so no chown is needed.
USER node
EXPOSE 3001
ENV PORT=3001 HOST=0.0.0.0
CMD ["node", "build"]