# syntax=docker/dockerfile:1 FROM python:3.12-slim AS base # --------------------------------------------------------------------------- # System dependencies: # - libpq-dev / gcc: build psycopg / cryptography wheels if no binary match # - WeasyPrint runtime deps: libpango, libcairo, libgdk-pixbuf, fonts, harfbuzz # - poppler-utils: pdftotext, used by tests and optional admin PDF verification # --------------------------------------------------------------------------- RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ libpq-dev \ libpango-1.0-0 \ libpangocairo-1.0-0 \ libcairo2 \ libgdk-pixbuf-2.0-0 \ libffi-dev \ libjpeg62-turbo \ shared-mime-info \ fonts-liberation \ fonts-dejavu-core \ poppler-utils \ curl \ && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY requirements.txt ./ RUN pip install --no-cache-dir --upgrade pip \ && pip install --no-cache-dir -r requirements.txt COPY . . RUN mkdir -p /app/uploads /app/static/generated \ && useradd -m -u 1000 appuser \ && chown -R appuser:appuser /app USER appuser ENV PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 EXPOSE 8000 HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ CMD curl -f http://localhost:8000/api/health || exit 1 # Default command runs the API with gunicorn+uvicorn workers. # docker-compose overrides this for the `worker` service (celery) and # `migrate` one-shot service (alembic upgrade head). CMD ["gunicorn", "app.main:app", \ "-k", "uvicorn.workers.UvicornWorker", \ "--bind", "0.0.0.0:8000", \ "--workers", "2", \ "--timeout", "60", \ "--access-logfile", "-", \ "--error-logfile", "-"]