# Dockerfile # Use an official Python runtime as a parent image # Choose a specific version for reproducibility, slim variants are smaller FROM python:3.11-slim # Set environment variables for Python ENV PYTHONDONTWRITEBYTECODE 1 # Prevents python creating .pyc files ENV PYTHONUNBUFFERED 1 # Force stdout/stderr streams to be unbuffered # Set the working directory in the container WORKDIR /app # Install system dependencies if needed (e.g., for libraries like Pillow or specific DB drivers) # RUN apt-get update && apt-get install -y --no-install-recommends some-package && rm -rf /var/lib/apt/lists/* # For basic SQLite and common libraries, often no extra system packages are needed. # Create a non-root user and group for security RUN addgroup --system --gid 1001 appgroup && \ adduser --system --uid 1001 --gid 1001 appuser # RUN chown -R appuser:appgroup /app # Optional: Set ownership early if needed # Copy the requirements file first to leverage Docker cache COPY requirements.txt . # Install dependencies # Upgrade pip and install requirements RUN pip install --upgrade pip && \ pip install --no-cache-dir -r requirements.txt # Copy the application code into the container under /app # Ensure correct ownership if copying files after creating the user COPY --chown=appuser:appgroup ./milk_app ./milk_app # Copy .env file if you rely on it INSIDE the container (less secure for secrets) # COPY --chown=appuser:appgroup .env . # Set Flask environment variables for production # FLASK_APP points to the factory function ENV FLASK_APP=milk_app.app:create_app() # Ensure Debug mode is OFF for production ENV FLASK_DEBUG=0 # Set Database URL to use a path inside the container (ideally mounted as a volume) # Using /app/instance ensures it's within our workdir and owned by appuser if volume isn't mounted yet ENV DATABASE_URL=sqlite:////app/instance/milk_tracker.db # IMPORTANT: Set FLASK_SECRET_KEY and JWT_SECRET_KEY via runtime environment variables (-e flags or docker-compose) # DO NOT hardcode secrets here! # Example placeholders (WILL NOT WORK unless overridden at runtime): # ENV FLASK_SECRET_KEY=your_flask_secret_key_at_runtime # ENV JWT_SECRET_KEY=your_jwt_secret_key_at_runtime # Ensure the instance folder exists and has correct permissions for the non-root user # Gunicorn/Flask will run as appuser and needs to write the DB here if it doesn't exist # The directory creation is handled in create_app now, but setting ownership is good. RUN mkdir -p /app/instance && chown -R appuser:appgroup /app/instance # Switch to the non-root user USER appuser # Expose the port Gunicorn will run on EXPOSE 5000 # Define the command to run the application using Gunicorn # Listen on 0.0.0.0 inside the container # Number of workers can be adjusted or passed as runtime ENV var CMD ["gunicorn", "--workers", "3", "--bind", "0.0.0.0:5000", "milk_app.app:create_app()"]