# Docker ## Python Slim Image ```dockerfile FROM python:3.11-slim WORKDIR /app RUN apt-get update && apt-get install -y --no-install-recommends \ gcc \ libpq-dev \ && rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD ["python", "main.py"] ``` Key flags: - `--no-install-recommends` — skip non-essential packages - `rm -rf /var/lib/apt/lists/*` — clean apt cache - `pip install --no-cache-dir` — don't store pip cache in image ## Multi-Stage Build Build dependencies (gcc, etc.) don't end up in the final image: ```dockerfile FROM python:3.11-slim AS builder WORKDIR /app RUN apt-get update && apt-get install -y --no-install-recommends \ gcc libpq-dev && rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir --user -r requirements.txt FROM python:3.11-slim WORKDIR /app COPY --from=builder /root/.local /root/.local COPY . . ENV PATH=/root/.local/bin:$PATH CMD ["python", "main.py"] ``` ## .dockerignore ```text __pycache__/ *.pyc *.log *.md tests/ .git/ .gitignore .env *.db ``` ## Best Practices 1. **Order layers by change frequency** — deps before code (`COPY requirements.txt` before `COPY . .`) 2. **Pin versions** — `python:3.11.9-slim`, not `latest` 3. **Run as non-root**: ```dockerfile RUN useradd -m -u 1000 appuser USER appuser ``` 4. **Use COPY, not ADD** — `ADD` has implicit extraction behavior