Docker Conteneurisation
Toutes les commandes Docker essentielles pour construire, déployer et orchestrer vos conteneurs.
Docker repose sur une architecture client-serveur. Le daemon Docker tourne en arrière-plan et gère les objets Docker (images, conteneurs, volumes, réseaux). Le client Docker communique avec le daemon via une API REST.
| Concept | Description |
|---|---|
Image | Modèle en lecture seule (template) contenant le système de fichiers et la configuration pour créer un conteneur. Construite depuis un Dockerfile. |
Conteneur | Instance en cours d'exécution d'une image. Isolé du système hôte, possède son propre système de fichiers (couche en écriture au-dessus de l'image). |
Dockerfile | Fichier texte décrivant les instructions pour construire une image, étape par étape. |
Volume | Mécanisme de persistance des données géré par Docker. Survit à la suppression du conteneur. |
Réseau | Couche d'isolation réseau permettant aux conteneurs de communiquer entre eux et avec l'extérieur. |
Registry | Dépôt de stockage et de distribution d'images (ex: Docker Hub, GitHub Container Registry). |
Docker Compose | Outil pour définir et gérer des applications multi-conteneurs via un fichier YAML. |
Un conteneur passe par plusieurs états : created (créé mais pas démarré), running (en cours d'exécution), paused, stopped (arrêté mais les données persistent), removed (supprimé).
| État | Commande | Description |
|---|---|---|
created | docker create | Conteneur créé, non démarré |
running | docker start / run | Processus en cours d'exécution |
paused | docker pause | Processus suspendu (SIGSTOP) |
stopped | docker stop | Processus arrêté (SIGTERM puis SIGKILL) |
removed | docker rm | Conteneur supprimé définitivement |
docker imageLes images sont des templates immuables stockés en couches (layers). Chaque instruction du Dockerfile crée une nouvelle couche, ce qui permet la mise en cache et le partage entre images.
docker images # Lister les images locales
docker image ls # Équivalent moderne
docker image ls -a # Inclure les images intermédiaires
docker pull nginx # Télécharger l'image officielle nginx (tag :latest)
docker pull nginx:1.25-alpine # Version spécifique avec tag
docker image inspect nginx # Détails complets d'une image (JSON)
docker image history nginx # Afficher les couches d'une image
docker image rm nginx # Supprimer une image
docker rmi nginx nginx:1.25-alpine # Supprimer plusieurs images
docker image prune # Supprimer les images orphelines (dangling)
docker image prune -a # Supprimer toutes les images non utilisées
docker buildConstruit une image à partir d'un Dockerfile. Le contexte de build (dernier argument) est le dossier envoyé au daemon Docker. Utilisez .dockerignore pour en exclure des fichiers.
docker build . # Build depuis le dossier courant
docker build -t mon-app:1.0 . # Nommer et tagger l'image
docker build -t mon-app:latest -f Dockerfile.prod . # Dockerfile personnalisé
docker build --no-cache -t mon-app . # Forcer la reconstruction sans cache
docker build --build-arg ENV=prod . # Passer un argument de build
# Exemple complet : build d'une app Node.js
docker build -t mon-app-node:1.0 --build-arg NODE_ENV=production .
Un tag identifie une version d'une image. Le format complet est registre/utilisateur/image:tag. Sans registre, Docker Hub est utilisé par défaut.
docker tag mon-app:1.0 monuser/mon-app:1.0 # Tagger pour Docker Hub
docker tag mon-app:1.0 mon-app:latest # Ajouter le tag latest
docker push monuser/mon-app:1.0 # Pousser vers Docker Hub
docker push monuser/mon-app:latest
# Avec GitHub Container Registry
docker tag mon-app:1.0 ghcr.io/monuser/mon-app:1.0
docker push ghcr.io/monuser/mon-app:1.0
docker rundocker run combine docker create + docker start. C'est la commande principale pour lancer un conteneur. Si l'image n'est pas présente localement, Docker la télécharge automatiquement.
docker run nginx # Lancer nginx (foreground, bloque le terminal)
docker run -d nginx # Mode détaché (arrière-plan)
docker run -d --name mon-nginx nginx # Nommer le conteneur
docker run -d -p 8080:80 nginx # Mapper port hôte:conteneur
docker run -d -p 8080:80 -p 443:443 nginx # Plusieurs ports
docker run -it ubuntu bash # Mode interactif avec terminal
docker run --rm ubuntu echo "hello" # Supprimer le conteneur après exécution
docker run -d -e APP_ENV=prod nginx # Définir une variable d'environnement
docker run -d --env-file .env nginx # Charger les variables depuis un fichier
docker run -d -v /host/data:/app/data nginx # Monter un dossier hôte (bind mount)
docker run -d -v mon-volume:/app/data nginx # Monter un volume nommé
docker run -d --network mon-reseau nginx # Connecter à un réseau
docker run -d --restart unless-stopped nginx # Redémarrage automatique
# Exemple complet : app Node.js
docker run -d \
--name api-prod \
-p 3000:3000 \
-e NODE_ENV=production \
-e DB_URL=mongodb://mongo:27017/mydb \
--network app-network \
--restart unless-stopped \
mon-app-node:1.0
docker run| Option | Description |
|---|---|
-d | Mode détaché (arrière-plan) |
-it | Mode interactif + pseudo-terminal (pour bash, sh) |
--rm | Supprime le conteneur automatiquement à l'arrêt |
--name | Donne un nom au conteneur (sinon généré aléatoirement) |
-p hôte:conteneur | Mappe un port de l'hôte vers le conteneur |
-P | Mappe automatiquement tous les ports EXPOSE |
-e VAR=valeur | Définit une variable d'environnement |
--env-file fichier | Charge les variables depuis un fichier |
-v src:dst | Monte un volume ou un bind mount |
--network | Connecte à un réseau Docker |
--restart | no | always | on-failure | unless-stopped |
--memory | Limite la mémoire (ex: --memory 512m) |
--cpus | Limite les CPU (ex: --cpus 1.5) |
docker ps # Lister les conteneurs en cours d'exécution
docker ps -a # Tous les conteneurs (y compris arrêtés)
docker ps -q # Seulement les IDs
docker start mon-nginx # Démarrer un conteneur arrêté
docker stop mon-nginx # Arrêter proprement (SIGTERM, puis SIGKILL)
docker stop -t 5 mon-nginx # Timeout avant SIGKILL (5 secondes)
docker kill mon-nginx # Arrêt forcé immédiat (SIGKILL)
docker restart mon-nginx # Redémarrer
docker pause mon-nginx # Suspendre les processus
docker unpause mon-nginx # Reprendre
docker rm mon-nginx # Supprimer un conteneur arrêté
docker rm -f mon-nginx # Forcer la suppression (même si en cours)
docker rm $(docker ps -aq) # Supprimer tous les conteneurs arrêtés
Accédez aux logs, exécutez des commandes à l'intérieur d'un conteneur, ou copiez des fichiers entre l'hôte et le conteneur.
# Logs
docker logs mon-nginx # Afficher les logs
docker logs -f mon-nginx # Suivre les logs en temps réel (follow)
docker logs --tail 50 mon-nginx # 50 dernières lignes
docker logs --since 1h mon-nginx # Logs de la dernière heure
# Exécuter une commande dans un conteneur actif
docker exec mon-nginx ls /etc/nginx
docker exec -it mon-nginx bash # Ouvrir un shell interactif
docker exec -it mon-nginx sh # Si bash n'est pas disponible (alpine)
docker exec -e VAR=val mon-nginx env # Avec une variable d'environnement
# Copier des fichiers
docker cp mon-nginx:/etc/nginx/nginx.conf ./nginx.conf # Conteneur → hôte
docker cp ./mon-fichier.conf mon-nginx:/etc/nginx/ # Hôte → conteneur
# Inspecter
docker inspect mon-nginx # Toutes les infos (JSON)
docker inspect --format '{{.NetworkSettings.IPAddress}}' mon-nginx # IP du conteneur
docker stats # CPU, mémoire, réseau en temps réel
docker stats mon-nginx # Stats d'un seul conteneur
docker top mon-nginx # Processus en cours dans le conteneur
docker port mon-nginx # Mappings de ports
Un Dockerfile est un script décrivant les étapes de construction d'une image. Chaque instruction crée une nouvelle couche dans l'image.
| Instruction | Description |
|---|---|
FROM | Image de base (obligatoire, en premier). Ex: FROM node:20-alpine |
WORKDIR | Définit le répertoire de travail pour les instructions suivantes |
COPY | Copie des fichiers du contexte de build vers l'image |
ADD | Comme COPY mais supporte les URLs et l'extraction d'archives tar (préférer COPY) |
RUN | Exécute une commande pendant la construction (crée une couche) |
ENV | Définit une variable d'environnement persistante dans l'image |
ARG | Variable disponible uniquement pendant le build (pas dans le conteneur final) |
EXPOSE | Documente le port écouté (ne publie pas réellement le port) |
CMD | Commande par défaut au démarrage du conteneur (peut être remplacée) |
ENTRYPOINT | Point d'entrée du conteneur (difficile à remplacer, CMD devient des arguments) |
VOLUME | Déclare un point de montage pour un volume |
USER | Définit l'utilisateur pour les instructions suivantes et le conteneur |
LABEL | Ajoute des métadonnées à l'image (auteur, version, description) |
HEALTHCHECK | Définit une commande pour vérifier la santé du conteneur |
Exemple complet pour une application Node.js avec les bonnes pratiques : utilisateur non-root, couches optimisées, image légère.
# Image de base légère
FROM node:20-alpine
# Métadonnées
LABEL maintainer="dev@exemple.fr"
LABEL version="1.0"
# Définir le répertoire de travail
WORKDIR /app
# Copier d'abord les fichiers de dépendances (optimise le cache)
COPY package*.json ./
# Installer les dépendances
RUN npm ci --only=production
# Copier le reste du code source
COPY . .
# Variable d'environnement
ENV NODE_ENV=production
ENV PORT=3000
# Créer un utilisateur non-root pour la sécurité
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# Documenter le port
EXPOSE 3000
# Vérification de santé
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \
CMD wget -qO- http://localhost:3000/health || exit 1
# Commande de démarrage
CMD ["node", "src/index.js"]
Les builds multi-étapes permettent de construire dans un environnement complet et de ne copier que le résultat final dans une image légère. Idéal pour les langages compilés (Go, Java) ou les frameworks frontend.
# ===== ÉTAPE 1 : Build =====
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build # Génère le dossier dist/
# ===== ÉTAPE 2 : Production =====
FROM nginx:1.25-alpine AS production
# Copier uniquement le résultat du build
COPY --from=builder /app/dist /usr/share/nginx/html
# Copier la configuration nginx personnalisée
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Similaire à .gitignore, ce fichier exclut des fichiers et dossiers du contexte de build pour réduire la taille et éviter d'envoyer des données sensibles au daemon Docker.
node_modules/
npm-debug.log
.git/
.gitignore
.env
.env.local
*.md
dist/
coverage/
.DS_Store
*.log
Ces deux instructions définissent le comportement au démarrage du conteneur, mais de manière différente.
| Instruction | Comportement | Remplacement |
|---|---|---|
CMD ["node","app.js"] | Commande par défaut | docker run image python app.py remplace complètement CMD |
ENTRYPOINT ["node"] | Exécutable fixe | docker run image app.js — app.js est ajouté comme argument à node |
ENTRYPOINT + CMD | Point d'entrée fixe avec arguments par défaut | CMD devient les arguments par défaut, remplaçables via docker run |
# Bonne pratique : ENTRYPOINT fixe l'exécutable, CMD les arguments par défaut
ENTRYPOINT ["node"]
CMD ["src/index.js"]
# docker run mon-app → node src/index.js
# docker run mon-app src/cli.js → node src/cli.js
Docker propose trois façons de persister et partager des données entre l'hôte et les conteneurs.
| Type | Syntaxe | Description |
|---|---|---|
| Volume nommé | -v mon-vol:/app/data | Géré par Docker, stocké dans /var/lib/docker/volumes/. Recommandé pour la production. |
| Bind mount | -v /host/path:/app/data | Lie un dossier de l'hôte. Utile en développement pour voir les modifications en temps réel. |
| tmpfs | --tmpfs /app/tmp | Stockage en mémoire RAM uniquement. Non persistant, pour les données sensibles temporaires. |
docker volume ls # Lister les volumes
docker volume create mon-volume # Créer un volume nommé
docker volume inspect mon-volume # Détails d'un volume (emplacement, etc.)
docker volume rm mon-volume # Supprimer un volume
docker volume prune # Supprimer les volumes non utilisés
# Utiliser un volume avec un conteneur
docker run -d \
-v mon-volume:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=secret \
--name postgres-db \
postgres:16-alpine
# Bind mount en développement (code source synchronisé)
docker run -d \
-v $(pwd):/app \
-v /app/node_modules \
-p 3000:3000 \
mon-app-node:dev
# Volume en lecture seule
docker run -d -v mon-volume:/app/data:ro nginx
| Driver | Description | Usage |
|---|---|---|
bridge | Réseau privé isolé sur l'hôte. Les conteneurs se voient par nom (DNS interne). | Défaut pour les conteneurs standalone |
host | Partage le réseau de l'hôte directement. Aucune isolation réseau. | Performance maximale (Linux uniquement) |
none | Aucune interface réseau. Conteneur complètement isolé. | Sécurité maximale, batch jobs |
overlay | Communication entre conteneurs sur plusieurs hôtes (Docker Swarm). | Orchestration multi-hôtes |
Dans un réseau bridge personnalisé, les conteneurs peuvent se joindre par leur nom (DNS automatique). Ce n'est pas le cas dans le réseau bridge par défaut.
docker network ls # Lister les réseaux
docker network create app-network # Créer un réseau bridge
docker network create --driver bridge --subnet 172.20.0.0/16 app-network
docker network inspect app-network # Détails du réseau
docker network rm app-network # Supprimer un réseau
docker network prune # Supprimer les réseaux inutilisés
# Connecter des conteneurs à un réseau
docker run -d --name api --network app-network mon-api
docker run -d --name db --network app-network postgres:16-alpine
# L'API peut maintenant joindre la DB via le nom "db" :
# postgresql://db:5432/mydb
# Connecter/déconnecter un conteneur existant
docker network connect app-network mon-nginx
docker network disconnect app-network mon-nginx
# Utiliser le réseau hôte (Linux)
docker run -d --network host nginx
docker-compose.ymlDocker Compose permet de définir et gérer des applications multi-conteneurs dans un fichier YAML. Tous les services partagent automatiquement un réseau et peuvent se joindre par leur nom de service.
services:
# Service API Node.js
api:
build:
context: .
dockerfile: Dockerfile
args:
NODE_ENV: production
image: mon-api:latest
container_name: mon-api
restart: unless-stopped
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DB_URL=mongodb://mongo:27017/mydb
- REDIS_URL=redis://redis:6379
env_file:
- .env
depends_on:
mongo:
condition: service_healthy
redis:
condition: service_started
volumes:
- ./logs:/app/logs
networks:
- app-network
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
interval: 30s
timeout: 5s
retries: 3
# Base de données MongoDB
mongo:
image: mongo:7-jammy
container_name: mon-mongo
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: secret
volumes:
- mongo-data:/data/db
- ./mongo-init.js:/docker-entrypoint-initdb.d/init.js:ro
networks:
- app-network
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 10s
timeout: 5s
retries: 5
# Cache Redis
redis:
image: redis:7-alpine
container_name: mon-redis
restart: unless-stopped
volumes:
- redis-data:/data
networks:
- app-network
volumes:
mongo-data:
redis-data:
networks:
app-network:
driver: bridge
docker compose up # Démarrer tous les services (foreground)
docker compose up -d # Mode détaché (arrière-plan)
docker compose up --build # Rebuild les images avant de démarrer
docker compose up -d --build # Rebuild + démarrage en arrière-plan
docker compose up api # Démarrer uniquement le service "api"
docker compose down # Arrêter et supprimer les conteneurs + réseaux
docker compose down -v # + supprimer les volumes
docker compose down --rmi all # + supprimer les images buildées
docker compose stop # Arrêter les conteneurs (sans les supprimer)
docker compose start # Redémarrer les conteneurs stoppés
docker compose restart # Redémarrer tous les services
docker compose restart api # Redémarrer un service spécifique
docker compose ps # État des services
docker compose logs # Logs de tous les services
docker compose logs -f api # Suivre les logs du service "api"
docker compose logs --tail 50 api
docker compose exec api bash # Shell dans le service "api"
docker compose exec api node --version # Exécuter une commande
docker compose build # Construire les images sans démarrer
docker compose pull # Télécharger les dernières images
docker compose config # Valider et afficher la config résolue
docker compose top # Processus dans chaque service
# Scaler un service (plusieurs instances)
docker compose up -d --scale api=3
Il est courant d'avoir un fichier de base et des fichiers de surcharge selon l'environnement. Le fichier docker-compose.override.yml est automatiquement mergé avec docker-compose.yml.
# Utiliser plusieurs fichiers (mergés dans l'ordre)
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# Fichiers courants
# docker-compose.yml → config de base
# docker-compose.override.yml → dev (chargé auto)
# docker-compose.prod.yml → production
# docker-compose.override.yml (développement)
services:
api:
build:
target: development
volumes:
- .:/app # Code source synchronisé
- /app/node_modules
environment:
- NODE_ENV=development
command: npm run dev # Remplace CMD du Dockerfile
Docker Hub est le registry public par défaut. Vous pouvez aussi utiliser des registries privés (GitHub Container Registry, GitLab Registry, AWS ECR, etc.).
# Authentification
docker login # Docker Hub (interactif)
docker login -u monuser # Spécifier le nom d'utilisateur
docker login ghcr.io # GitHub Container Registry
docker logout # Se déconnecter
# Chercher des images sur Docker Hub
docker search nginx
docker search --filter is-official=true nginx
# Nommer et pousser une image
docker tag mon-app:1.0 monuser/mon-app:1.0
docker push monuser/mon-app:1.0
docker push monuser/mon-app:latest
# Télécharger une image spécifique
docker pull monuser/mon-app:1.0
# Sauvegarder/charger une image en fichier tar (sans registry)
docker save -o mon-app.tar mon-app:1.0
docker load -i mon-app.tar
# Exporter/importer un conteneur (système de fichiers uniquement)
docker export mon-conteneur -o snapshot.tar
docker import snapshot.tar mon-app:snapshot
Docker peut accumuler beaucoup de données inutilisées (images, conteneurs arrêtés, volumes orphelins, cache de build). Ces commandes permettent de récupérer de l'espace disque.
# Nettoyage ciblé
docker container prune # Supprimer tous les conteneurs arrêtés
docker image prune # Supprimer les images dangling (sans tag)
docker image prune -a # Supprimer toutes les images non utilisées
docker volume prune # Supprimer les volumes non attachés
docker network prune # Supprimer les réseaux inutilisés
docker builder prune # Supprimer le cache de build
# Nettoyage global (tout en une commande)
docker system prune # Conteneurs + réseaux + images dangling
docker system prune -a # + toutes les images non utilisées
docker system prune -a --volumes # + volumes (ATTENTION : perte de données)
# Inspecter l'espace utilisé
docker system df # Résumé de l'espace disque Docker
docker system df -v # Détails par objet
Une image optimisée est plus rapide à construire, à télécharger et plus sécurisée. Voici les principales règles à suivre.
| Pratique | Description |
|---|---|
| Images de base légères | Préférer alpine ou slim (ex: node:20-alpine) plutôt que les images complètes |
| Minimiser les couches | Chaîner les commandes RUN avec && pour n'en créer qu'une seule couche |
| Ordonner les instructions | Placer les instructions qui changent rarement en premier (ex: dépendances avant le code source) pour bénéficier du cache |
| Multi-stage build | Séparer build et runtime pour exclure les outils de compilation de l'image finale |
| Utilisateur non-root | Toujours créer et utiliser un utilisateur dédié avec USER pour la sécurité |
| .dockerignore | Exclure node_modules, .git, .env, logs du contexte de build |
| Tags explicites | Éviter :latest en production, utiliser des tags de version précis |
| Secrets | Ne jamais inclure de secrets dans l'image, utiliser les variables d'environnement ou Docker secrets |
# === DÉVELOPPEMENT ===
# 1. Démarrer l'environnement de dev (avec hot-reload)
docker compose up -d
# 2. Voir les logs en temps réel
docker compose logs -f api
# 3. Ouvrir un shell dans le conteneur
docker compose exec api bash
# 4. Relancer uniquement un service après modification
docker compose restart api
# === MISE EN PRODUCTION ===
# 1. Build de l'image avec tag de version
docker build -t monuser/mon-app:2.1.0 -t monuser/mon-app:latest .
# 2. Tester l'image localement
docker run --rm -p 3000:3000 monuser/mon-app:2.1.0
# 3. Pousser vers le registry
docker push monuser/mon-app:2.1.0
docker push monuser/mon-app:latest
# 4. Déployer sur le serveur
docker compose -f docker-compose.yml -f docker-compose.prod.yml pull
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# 5. Vérifier le déploiement
docker compose ps
docker compose logs --tail 20 api
# 6. Nettoyer les anciennes images
docker image prune -f
| Commande | Description |
|---|---|
docker build -t app:1.0 . | Construire une image depuis le dossier courant |
docker run -d -p 80:80 app:1.0 | Lancer un conteneur en arrière-plan |
docker ps | Lister les conteneurs en cours d'exécution |
docker logs -f nom | Suivre les logs en temps réel |
docker exec -it nom bash | Ouvrir un shell dans le conteneur |
docker stop nom | Arrêter proprement un conteneur |
docker rm nom | Supprimer un conteneur |
docker compose up -d --build | Rebuild et démarrer tous les services |
docker compose down -v | Arrêter et supprimer conteneurs + volumes |
docker system prune -a | Nettoyage complet de Docker |
Aucun résultat pour votre recherche.