# 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