Optimisation des images Docker Python : réduction de la taille de 43 à 57 %
Les builds multi-étapes et les images Python slim peuvent réduire la taille de l'image d'exécution de 895 Mo à 508 Mo (-43 %). Le temps de build après modifications du code passe de 56 à 16 secondes. Cela accélère les déploiements Kubernetes, économise le stockage et réduit le trafic.
L'optimisation aborde des problèmes clés : la mise à l'échelle rapide des pods lors des pics de trafic et la réduction de la latence utilisateur. Les dépendances sont gérées avec Poetry, et les tests s'exécutent dans l'étape de build.
.dockerignore et images Slim
Excluez les tests et fichiers inutiles via .dockerignore. Les tests ne sont nécessaires que pendant l'étape de build.
Passez à python:3.13-slim-bookworm. L'image complète ajoute des centaines de Mo.
Désactivez le cache pip/Poetry avec les drapeaux :
- pip :
--no-cache-dir - Poetry :
poetry cache clear --all pypi
Build multi-étapes : analyse du Dockerfile
L'étape builder installe Poetry, les dépendances et exécute pytest. L'étape runtime copie uniquement les site-packages, les binaires (gunicorn, uvicorn) et le code.
# Étape builder
FROM python:3.13-slim-bookworm AS builder
ENV PYTHONUNBUFFERED=1 \
LANG=C.UTF-8 \
PYTHONDONTWRITEBYTECODE=1
RUN apt-get update -qq && \
apt-get install -y --no-install-recommends \
curl \
gcc \
libc-dev \
&& pip install --no-cache-dir 'poetry==2.3.2' \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
WORKDIR /code
COPY pyproject.toml poetry.lock* ./
RUN poetry config virtualenvs.create false \
&& poetry install --no-root --no-dev --no-interaction --no-ansi \
&& poetry cache clear --all pypi --no-interaction || true \
&& rm -rf ~/.cache/pip
COPY . .
RUN pytest
# Étape runtime
FROM python:3.13-slim-bookworm
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
LANG=C.UTF-8
WORKDIR /code
COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
COPY --from=builder /usr/local/bin/gunicorn /usr/local/bin/gunicorn
COPY --from=builder /usr/local/bin/uvicorn /usr/local/bin/uvicorn
COPY --from=builder /code /code
Résultats d'optimisation de base :
| Métrique | Avant | Après | Changement |
|---------|------|-------|-----------|
| Taille image, Mo | 894,84 | 508 | -43 % |
| Temps build complet, s | 58 | 315 | +443 % |
| Temps build après modifications, s | 56 | 16 | -71 % |
Le premier build est plus lent à cause des couches builder, mais le cache accélère les itérations.
Méthodes avancées : Chainguard et analyse manuelle
Images Chainguard
Chainguard exclut le shell, apt/apk, minimisant la surface d'attaque. Pas de CVE dans les images de base. Économies : 50–150 Mo.
Inconvénients :
- Débogage sans shell
- Gratuit uniquement pour le tag latest
- Versions payantes coûteuses
Adapté aux projets haute sécurité.
Analyse manuelle avec dive
Analysez les couches :
docker history --format "{{.CreatedBy}}: {{.Size}}" image:tag
docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive:latest image:tag
Concentrez-vous sur les grandes couches runtime. Réduisez les répertoires (Shift+Espace), supprimez les libs inutiles. Requiert expertise Linux, rarement rentable.
Optimisation extrême : scratch
Runtime sur scratch—copiez uniquement la libc requise. Taille réduite à 384 Mo (-57 % par rapport à l'original, -24 % par rapport au multi-étapes).
Inconvénients :
- Débogage impossible
- Nouvelles dépendances nécessitent ajout manuel de libs
- Temps de débogage : 1+ heure
Pertinent pour des milliers de pods, Serverless (Knative, Fargate). Plus difficile en Python qu'en Go.
Comparaison de taille :
- Sans multi-étapes : 894 → 384 Mo (-57 %)
- Multi-étapes : 508 → 384 Mo (-24 %)
Optimisation du temps de build
Copiez pyproject.toml/poetry.lock AVANT le code :
- COPY pyproject.toml poetry.lock* ./
- RUN poetry install
- COPY . .
- RUN pytest
Le cache des dépendances persiste avec les changements de code. Accélération : 58 → 14 s (x4).
Points clés à retenir
- Multi-étapes + slim : -43 % taille, -71 % temps d'itération.
- .dockerignore + no-cache : exclut tests et cache du runtime.
- Ordre COPY : dépendances mises en cache séparément du code.
- Scratch : -57 %, mais pour cas extrêmes (milliers de pods).
- Chainguard/dive : pour sécurité et réglage fin.
— Editorial Team
Aucun commentaire pour le moment.