Dockerfile
Le Dockerfile est la recette de construction d'une image. Chaque instruction a des implications sur la taille de l'image, le cache de build, la sécurité et les performances à l'exécution. Les écrire correctement dès le départ évite des problèmes en production.
Instructions essentielles
FROM debian:13-slim
# Métadonnées OCI standard
LABEL maintainer="equipe@exemple.fr"
LABEL org.opencontainers.image.source="https://github.com/org/repo"
# Variable de build (remplaçable via --build-arg)
ARG APP_VERSION=1.0.0
# Variable d'environnement (visible dans le container)
ENV APP_ENV=production APP_PORT=8080
# Répertoire de travail
WORKDIR /app
# Installation de dépendances (une seule couche, nettoyage dans le même RUN)
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates && rm -rf /var/lib/apt/lists/*
# Copier un fichier
COPY requirements.txt .
# Copier plusieurs fichiers ou répertoires
COPY src/ ./src/
# Exposer un port (documentation, pas de mapping automatique)
EXPOSE 8080
# Utilisateur non-root
USER nobody
# Point d'entrée principal
ENTRYPOINT ["python3", "-m", "gunicorn"]
# Arguments par défaut (remplacables via docker run)
CMD ["--bind", "0.0.0.0:8080", "app:create_app()"]CMD vs ENTRYPOINT
- ENTRYPOINT : commande principale, non remplacée par les arguments de
docker run - CMD : arguments par défaut, remplacés par ce qui suit
docker run IMAGE
# Pattern recommandé : ENTRYPOINT fixe + CMD pour les options
ENTRYPOINT ["nginx"]
CMD ["-g", "daemon off;"]
# docker run nginx:custom -g "daemon off;" -c /etc/nginx/custom.confToujours utiliser la forme JSON (tableau) pour ENTRYPOINT et CMD. La forme shell (CMD nginx -g "daemon off;") lance via /bin/sh -c et le processus ne reçoit pas les signaux Unix correctement (SIGTERM ignoré).
COPY vs ADD
Préférer COPY dans tous les cas sauf deux :
ADDdécompresse automatiquement les archives tar localesADDpeut télécharger depuis une URL (maiscurl+COPYest plus explicite)
.dockerignore
.git
.env
*.log
node_modules/
__pycache__/
*.pyc
dist/
.DS_StoreSans .dockerignore, le contexte de build envoie tout le répertoire courant au daemon, y compris .git et node_modules. Résultat : builds lents et invalidation de cache inutile.
Bonnes pratiques
- Un seul
RUN apt-get update && apt-get install && rm -rf /var/lib/apt/lists/*par Dockerfile - Épingler les versions (
nginx:1.27-alpineplutôt quenginx:latest) - Utiliser
--no-install-recommendsavec apt pour éviter les paquets superflus - Ne jamais stocker de secrets dans le Dockerfile (ils restent dans les layers)
- Terminer avec un utilisateur non-root