Blocco A · Fondamenta Docker — Modulo 3 di 16
Dockerfile avanzato
e hardening delle immagini
Obiettivi di oggi
- Multi-stage build; base image slim e pinnate
- Utente non-root, HEALTHCHECK, .dockerignore
- Da ~1 GB a ~180 MB: la stessa API, immagine da standard dell'Ente
Perché "piccolo" = "sicuro"
- Ogni pacchetto nell'immagine è superficie d'attacco e CVE potenziale da gestire
python:3.12 ≈ 1 GB (compilatori, tool, librerie che non servono)
python:3.12-slim ≈ 130 MB di base: solo il necessario
- I sistemisti manterranno l'elenco delle base image approvate
Multi-stage: build separata dal runtime
FROM python:3.12-slim AS deps
COPY requirements.txt .
RUN pip install --prefix=/install -r requirements.txt
FROM python:3.12-slim # stage finale PULITO
RUN useradd --create-home app
COPY --from=deps /install /usr/local
COPY app.py .
USER app # mai root
HEALTHCHECK CMD python -c "..." # Docker sa se sono vivo
CMD ["gunicorn", "-b", "0.0.0.0:5000", "app:app"]
Le regole dell'Ente (nascono oggi)
- Base image pinnata (
3.12-slim), MAI latest
- Utente non-root sempre · HEALTHCHECK sempre · .dockerignore sempre
- Multi-stage dove c'è una fase di build
- Server applicativo vero (gunicorn), non quello di sviluppo
Queste righe finiranno identiche nelle Linee guida e nel blueprint (M15).
Laboratorio (2h)
- Misura l'immagine del Modulo 2, poi riscrivi il Dockerfile: multi-stage, slim, non-root, healthcheck, gunicorn
- Confronto: dimensioni,
whoami, stato (healthy) in docker ps
Riepilogo e prossimo passo
- L'immagine API è ora quella "vera": piccola, non-root, osservabile
- Ma le pratiche create spariscono a ogni riavvio…
- Modulo 4: database, reti tra container e dati persistenti