$devtoolkit.sh/examples/config/dockerfile-python

Dockerfile for a Python Application

Python Docker images benefit from using a virtual environment inside the container to isolate dependencies cleanly, and from a slim base image to reduce size. This example pins the Python version, uses python:3.12-slim for a minimal footprint, and installs dependencies from requirements.txt before copying application code. The layer ordering ensures that pip install is only re-run when requirements.txt changes, not on every code edit. Set PYTHONDONTWRITEBYTECODE and PYTHONUNBUFFERED for cleaner container logging.

Example
FROM python:3.12-slim

ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1

WORKDIR /app

RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY --chown=appuser:appgroup . .

USER appuser
EXPOSE 8000
HEALTHCHECK --interval=30s CMD curl -f http://localhost:8000/health || exit 1
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000", "--workers", "2"]
[ open in Dockerfile Generator → ]

FAQ

What does PYTHONDONTWRITEBYTECODE do?
It prevents Python from writing .pyc bytecode cache files to disk. In a container, these files add unnecessary size and are regenerated each time the container starts anyway.
Should I use python:slim or python:alpine?
python:slim (based on Debian) is generally preferred over alpine for Python because many Python packages compile native extensions that require glibc, which Alpine (using musl libc) does not provide without extra workarounds.
How do I reduce pip install time in CI/CD?
Use --no-cache-dir in pip install to avoid storing the pip cache in the image. For CI speed, mount the pip cache as a Docker build cache using --mount=type=cache,target=/root/.cache/pip.

Related Examples

/examples/config/dockerfile-pythonv1.0.0