# Help Service - Bulletproof Production Dockerfile # Security-hardened, multi-stage build # ============================================================================= # Stage 1: Build dependencies # ============================================================================= FROM python:3.13-slim-bookworm AS builder WORKDIR /build COPY requirements.txt . RUN pip install --no-cache-dir --user --no-warn-script-location -r requirements.txt # ============================================================================= # Stage 2: Production image # ============================================================================= FROM python:3.13-slim-bookworm # OCI Labels LABEL org.opencontainers.image.title="Help Service" LABEL org.opencontainers.image.description="Documentation help service for Kurs-Booking" LABEL org.opencontainers.image.vendor="webideas24" LABEL org.opencontainers.image.version="1.0.0" LABEL org.opencontainers.image.source="https://git.islandpferde-melanieworbs.de/webideas24/help-service" # Security: Install tini and minimal runtime dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ tini \ curl \ ca-certificates \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ && rm -rf /root/.cache WORKDIR /app # Copy Python packages from builder COPY --from=builder /root/.local /home/helpuser/.local # Security: Create non-root user with no shell RUN groupadd -r -g 1000 helpuser && \ useradd -r -u 1000 -g helpuser -s /usr/sbin/nologin -d /home/helpuser helpuser && \ chown -R helpuser:helpuser /app /home/helpuser # Copy application files COPY --chown=helpuser:helpuser app.py ./ COPY --chown=helpuser:helpuser content/ ./content/ COPY --chown=helpuser:helpuser templates/ ./templates/ COPY --chown=helpuser:helpuser static/ ./static/ # Switch to non-root user USER helpuser # Environment ENV PATH=/home/helpuser/.local/bin:$PATH \ PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ PIP_NO_CACHE_DIR=1 EXPOSE 5000 STOPSIGNAL SIGTERM HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \ CMD curl -fsS http://localhost:5000/health || exit 1 ENTRYPOINT ["/usr/bin/tini", "--"] CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "--threads", "4", "--timeout", "30", "--graceful-timeout", "10", "app:app"]