# ============================================================================ # Multi-Stage Dockerfile for Recticel Quality Application # Optimized for production deployment with minimal image size and security # ============================================================================ # ============================================================================ # Stage 1: Builder - Install dependencies and prepare application # ============================================================================ FROM python:3.10-slim AS builder # Prevent Python from writing pyc files and buffering stdout/stderr ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PIP_NO_CACHE_DIR=1 \ PIP_DISABLE_PIP_VERSION_CHECK=1 # Install build dependencies (will be discarded in final stage) RUN apt-get update && apt-get install -y --no-install-recommends \ gcc \ g++ \ default-libmysqlclient-dev \ pkg-config \ && rm -rf /var/lib/apt/lists/* # Create and use a non-root user for security RUN useradd -m -u 1000 appuser # Set working directory WORKDIR /app # Copy and install Python dependencies # Copy only requirements first to leverage Docker layer caching COPY py_app/requirements.txt . # Install Python packages in a virtual environment for better isolation RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" RUN pip install --upgrade pip setuptools wheel && \ pip install --no-cache-dir -r requirements.txt # ============================================================================ # Stage 2: Runtime - Minimal production image # ============================================================================ FROM python:3.10-slim AS runtime # Set Python environment variables ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ FLASK_APP=run.py \ FLASK_ENV=production \ PATH="/opt/venv/bin:$PATH" # Install only runtime dependencies (much smaller than build deps) RUN apt-get update && apt-get install -y --no-install-recommends \ default-libmysqlclient-dev \ mariadb-client \ curl \ ca-certificates \ && rm -rf /var/lib/apt/lists/* \ && apt-get clean # Create non-root user for running the application RUN useradd -m -u 1000 appuser # Set working directory WORKDIR /app # Copy virtual environment from builder stage COPY --from=builder /opt/venv /opt/venv # Copy application code COPY --chown=appuser:appuser py_app/ . # Copy entrypoint script COPY --chown=appuser:appuser docker-entrypoint.sh /docker-entrypoint.sh RUN chmod +x /docker-entrypoint.sh # Create necessary directories with proper ownership RUN mkdir -p /app/instance /srv/quality_recticel/logs && \ chown -R appuser:appuser /app /srv/quality_recticel # Switch to non-root user for security USER appuser # Expose the application port EXPOSE 8781 # Health check - verify the application is responding # Disabled by default in Dockerfile, enable in docker-compose if needed HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD curl -f http://localhost:8781/ || exit 1 # Use the entrypoint script for initialization ENTRYPOINT ["/docker-entrypoint.sh"] # Default command: run gunicorn with optimized configuration # Can be overridden in docker-compose.yml or at runtime CMD ["gunicorn", "--config", "gunicorn.conf.py", "wsgi:application"] # ============================================================================ # Build arguments for versioning and metadata # ============================================================================ ARG BUILD_DATE ARG VERSION ARG VCS_REF # Labels for container metadata LABEL org.opencontainers.image.created="${BUILD_DATE}" \ org.opencontainers.image.version="${VERSION}" \ org.opencontainers.image.revision="${VCS_REF}" \ org.opencontainers.image.title="Recticel Quality Application" \ org.opencontainers.image.description="Production-ready Docker image for Trasabilitate quality management system" \ org.opencontainers.image.authors="Quality Team" \ maintainer="quality-team@recticel.com"