- Add .dockerignore for backend and frontend (DC-1: eliminates node_modules/ and .env from build context) - Delete start.sh with --reload flag (DC-2: superseded by Dockerfile CMD) - Create entrypoint.sh with exec uvicorn (DW-5: proper PID 1 signal handling) - Pin base images to patch-level tags (DW-1: reproducible builds) - Reorder Dockerfile: create appuser before COPY, use --chown (DW-2) - Switch to npm ci for lockfile-enforced installs (DW-3) - Add network segmentation: backend_net + frontend_net (DW-4: db unreachable from frontend container) - Add deploy.resources limits to all services (DW-6: OOM protection) - Refactor proxy-params.conf to include security headers, deduplicate from nginx.conf location blocks (DW-7) - Add image/svg+xml to gzip_types (DS-1) - Add wget healthcheck for frontend service (DS-2) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
36 lines
1.1 KiB
Docker
36 lines
1.1 KiB
Docker
# ── Build stage: compile C extensions ──────────────────────────────────
|
|
FROM python:3.12.9-slim-bookworm AS builder
|
|
|
|
WORKDIR /build
|
|
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
gcc \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
COPY requirements.txt .
|
|
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
|
|
|
|
# ── Runtime stage: lean production image ───────────────────────────────
|
|
FROM python:3.12.9-slim-bookworm
|
|
|
|
# Create non-root user first, then copy with correct ownership (DW-2)
|
|
RUN useradd -m -u 1000 appuser
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy pre-built Python packages from builder
|
|
COPY --from=builder /install /usr/local
|
|
|
|
# Copy application code with correct ownership — avoids redundant chown layer
|
|
COPY --chown=appuser:appuser . .
|
|
|
|
# Make entrypoint executable
|
|
RUN chmod +x entrypoint.sh
|
|
|
|
USER appuser
|
|
|
|
EXPOSE 8000
|
|
|
|
# Use entrypoint with exec so uvicorn runs as PID 1 and receives signals (DW-5)
|
|
ENTRYPOINT ["./entrypoint.sh"]
|