Harden the container: non-root, no build tools, read-only, stdout logging
The app ran as root, and the production image contained gcc, vim, wget and gnupg. Code execution in the container would have allowed changing the app code and fetching or compiling further tools. - Multi-stage build: the wheels (psycopg2) are built in a build stage. The runtime image only contains libpq5, postgresql-client and wait-for-it (724 MB -> 298 MB). - The app runs as the system user max (uid/gid 10001). The code is owned by root and precompiled, the user has no writable directory. - Log to stdout only; docker collects it. The log file under /app/log was lost on every container recreation anyway. - docker-compose: read-only filesystem (tmpfs for /tmp), no capabilities, no-new-privileges and log rotation (5 x 10 MB). - Add a .dockerignore and set MAX_ORIGIN in docker-compose.yml. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7ac4e6c3a7
commit
931243dd60
6 files changed
+55
-32
No files matched your search
+26
-7
@@ -1,20 +1,39 @@
|
||||
# Build stage: compile the wheels (psycopg2 needs gcc and libpq-dev)
|
||||
FROM python:3.15-slim-trixie AS build
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-recommends -y gcc libc-dev libpq-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /build
|
||||
COPY requirements.txt .
|
||||
RUN pip wheel --no-cache-dir --wheel-dir /wheels -r requirements.txt
|
||||
|
||||
# Runtime stage: no compiler and no tools besides what db-setup.sh needs
|
||||
FROM python:3.15-slim-trixie
|
||||
|
||||
RUN apt -y update && apt -y upgrade && \
|
||||
apt install --no-install-recommends -y wait-for-it lsb-release wget gnupg2 gcc libpq-dev libc-dev vim postgresql-client && apt clean all
|
||||
RUN apt-get update && apt-get upgrade -y && \
|
||||
apt-get install --no-install-recommends -y libpq5 postgresql-client wait-for-it && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY --from=build /wheels /wheels
|
||||
RUN pip install --no-cache-dir /wheels/* && rm -rf /wheels
|
||||
|
||||
RUN groupadd --system --gid 10001 max && \
|
||||
useradd --system --uid 10001 --gid max --no-create-home --shell /usr/sbin/nologin max
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install -U -r requirements.txt
|
||||
|
||||
RUN mkdir log
|
||||
|
||||
ENV PYTHONPATH=/app/
|
||||
ENV FLASK_APP=max.app
|
||||
|
||||
# Owned by root, so the app cannot modify its own code
|
||||
COPY max/ ./max
|
||||
COPY scripts/prod/ .
|
||||
# Precompile, since the app cannot write __pycache__ at runtime
|
||||
RUN python -m compileall -q max
|
||||
|
||||
USER max
|
||||
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
CMD ["gunicorn", "-w", "1", "-b", "0.0.0.0:8000", "max.app:app"]
|
||||
Reference in new issue
Block a user