
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- daemon.json : emplacement, structure, options principales
- Storage drivers : overlay2, btrfs, zfs, choix et configuration
- Logging drivers : json-file, journald, fluentd, splunk
- Registries : mirrors, insecure registries, authentification
- Ressources : limites par défaut, cgroups, ulimits
- Production : live restore, userland proxy, metrics
Introduction
Section intitulée « Introduction »Le fichier daemon.json regroupe la configuration de Docker Engine. Il permet de personnaliser le comportement du daemon sans modifier les arguments de ligne de commande systemd. Ce guide couvre toutes les options importantes pour configurer Docker en production : du choix du storage driver à l'exposition des métriques Prometheus.
Prérequis
Section intitulée « Prérequis »Emplacement du fichier daemon.json
Section intitulée « Emplacement du fichier daemon.json »Le fichier de configuration du daemon Docker varie selon le système d'exploitation.
| Système | Emplacement |
|---|---|
| Linux | /etc/docker/daemon.json |
| Windows | C:\ProgramData\docker\config\daemon.json |
| macOS (Docker Desktop) | ~/.docker/daemon.json |
Création du fichier sur Linux :
# Créer le répertoire si nécessairesudo mkdir -p /etc/docker
# Créer le fichier avec une configuration minimalesudo tee /etc/docker/daemon.json << 'EOF'{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" }}EOF
# Redémarrer Dockersudo systemctl restart dockerStructure et syntaxe
Section intitulée « Structure et syntaxe »Le fichier daemon.json utilise le format JSON standard. Chaque option doit respecter la syntaxe JSON stricte.
Règles de syntaxe :
- Pas de virgule après le dernier élément
- Les chaînes entre guillemets doubles (
") - Les booléens en minuscules (
true,false) - Pas de commentaires (JSON ne les supporte pas)
Exemple de structure :
{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" }, "default-ulimits": { "nofile": { "Name": "nofile", "Hard": 65535, "Soft": 65535 } }, "live-restore": true, "debug": false}Validation de la syntaxe
Section intitulée « Validation de la syntaxe »Validez toujours le fichier avant de redémarrer Docker :
# Validation par dockerdsudo dockerd --validate
# Alternative simple avec jqjq . /etc/docker/daemon.jsonStorage drivers
Section intitulée « Storage drivers »Le storage driver gère le système de fichiers des images et conteneurs. Le choix du driver impacte les performances et la compatibilité.
Choisir le bon storage driver
Section intitulée « Choisir le bon storage driver »Avant de choisir un driver, il faut savoir quel magasin d'images votre démon utilise. Les deux n'emploient pas le même vocabulaire, et Docker a changé de défaut en cours de route.
| Magasin d'images | Ce que docker info affiche | Où on le rencontre |
|---|---|---|
| classique | Storage Driver: overlay2 | installations montées de version, et daemons en userns-remap |
| containerd | Storage Driver: overlayfs avec driver-type: io.containerd.snapshotter.v1 | installations neuves de Docker Engine 29 |
Les notes de version de Docker Engine 29 sont explicites sur deux points que l'on
confond souvent : le magasin containerd devient le défaut des installations
neuves seulement, une machine mise à jour conservant le sien, et le
changement ne s'applique pas aux démons configurés en userns-remap.
Les noms se ressemblent et désignent deux mécanismes distincts : overlay2
est l'ancien graph driver de Docker, overlayfs est un snapshotter
de containerd. Confondre les deux mène à écrire une configuration qui ne
s'applique pas.
Ce que la commande rend réellement. Sur une machine dont le daemon.json ne
contient aucun storage-driver, mesuré le 19 septembre 2026 sous Docker
Engine 29.1.3 :
docker info | grep -A1 "Storage Driver" Storage Driver: overlayfs driver-type: io.containerd.snapshotter.v1Le démon a donc choisi le magasin containerd tout seul, sans qu'on le lui
demande. Une conséquence visible immédiatement : docker image ls --tree
liste les images par plateforme, ce que le magasin classique ne sait pas
faire.
Faut-il déclarer un storage driver ?
Section intitulée « Faut-il déclarer un storage driver ? »Non, dans le cas général. Forcer "storage-driver": "overlay2" sur une
installation récente revient à demander l'ancien magasin d'images, et donc à
perdre ce que le nouveau apporte : images multi-plateformes en local,
attestations, SBOM et provenance rattachés à l'image.
Les drivers du tableau ci-dessous restent utiles pour lire une machine existante, pas pour en configurer une neuve :
| Driver | Ce que sa présence signifie |
|---|---|
overlayfs | magasin containerd, le défaut d'une installation Docker 29 |
overlay2 | magasin classique, installation héritée ou driver forcé |
btrfs, zfs | le stockage de la machine impose déjà ce système de fichiers |
devicemapper, aufs | machine ancienne : ces drivers ne sont plus maintenus |
vfs | aucune copie sur écriture, très lent, réservé au débogage |
Partition dédiée /var/lib/docker
Section intitulée « Partition dédiée /var/lib/docker »En production, utilisez une partition dédiée pour les données Docker. Cela permet :
- D'isoler l'espace disque Docker
- D'utiliser un filesystem adapté (ext4, xfs)
- De faciliter les sauvegardes et migrations
-
Créer et monter la partition
Fenêtre de terminal # Formater la partition (exemple: /dev/sdb1)sudo mkfs.ext4 /dev/sdb1# Créer le point de montagesudo mkdir -p /mnt/docker-data# Monter la partitionsudo mount /dev/sdb1 /mnt/docker-data# Ajouter au fstab pour montage automatiqueecho '/dev/sdb1 /mnt/docker-data ext4 defaults 0 2' | sudo tee -a /etc/fstab -
Migrer les données existantes
Fenêtre de terminal # Arrêter Dockersudo systemctl stop docker# Copier les donnéessudo rsync -aP /var/lib/docker/ /mnt/docker-data/# Sauvegarder l'ancien répertoiresudo mv /var/lib/docker /var/lib/docker.bak -
Configurer daemon.json
{"data-root": "/mnt/docker-data"} -
Redémarrer et vérifier
/mnt/docker-data sudo systemctl start dockerdocker info | grep "Docker Root Dir"
Logging drivers
Section intitulée « Logging drivers »Docker supporte plusieurs backends pour les logs des conteneurs. Le choix dépend de votre infrastructure de centralisation.
json-file (défaut)
Section intitulée « json-file (défaut) »Le driver par défaut stocke les logs en JSON dans /var/lib/docker/containers/<id>/<id>-json.log.
{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3", "compress": "true", "labels": "production_status,team" }}| Option | Description | Exemple |
|---|---|---|
max-size | Taille max par fichier | 10m, 100k |
max-file | Nombre de fichiers en rotation | 3, 5 |
compress | Compresser les fichiers rotés | true |
labels | Labels à inclure dans les logs | env,team |
Consulter les logs :
# Via docker logsdocker logs mycontainer
# Fichier directcat /var/lib/docker/containers/<id>/<id>-json.log | jqjournald
Section intitulée « journald »Le driver journald envoie les logs au journal systemd. Intégration native avec les outils système Linux.
{ "log-driver": "journald", "log-opts": { "tag": "{{.Name}}/{{.ID}}" }}Avantages :
- Rotation automatique par journald
- Métadonnées enrichies
- Intégration
journalctl
Consulter les logs :
# Tous les conteneursjournalctl -u docker.service
# Un conteneur spécifiquejournalctl CONTAINER_NAME=mycontainer
# Avec l'IDjournalctl CONTAINER_ID=abc123Drivers centralisés
Section intitulée « Drivers centralisés »Pour les environnements de production, envoyez les logs vers un système centralisé.
{ "log-driver": "fluentd", "log-opts": { "fluentd-address": "localhost:24224", "tag": "docker.{{.Name}}", "fluentd-async": "true" }}| Option | Description |
|---|---|
fluentd-address | Adresse du collecteur Fluentd |
tag | Tag pour le routage |
fluentd-async | Mode asynchrone (recommandé) |
{ "log-driver": "splunk", "log-opts": { "splunk-url": "https://splunk.example.com:8088", "splunk-token": "your-hec-token", "splunk-index": "docker", "splunk-insecureskipverify": "false" }}{ "log-driver": "gelf", "log-opts": { "gelf-address": "udp://graylog.example.com:12201", "tag": "docker-{{.Name}}" }}Configuration des registries
Section intitulée « Configuration des registries »Le daemon décide seul d'où viennent les images et à quelles conditions il fait confiance à une source. Trois réglages couvrent ce périmètre : un cache pour éviter de retélécharger les mêmes images, une liste d'exceptions TLS pour les registries internes, et le stockage des identifiants. Les deux premiers vivent dans daemon.json, le troisième non.
Registry mirrors
Section intitulée « Registry mirrors »Un registry mirror est un cache local des images de Docker Hub. Il réduit la bande passante consommée et évite d'atteindre les quotas de téléchargement appliqués aux comptes anonymes et gratuits.
{ "registry-mirrors": [ "https://mirror.gcr.io", "https://registry.example.com" ]}Fonctionnement :
docker pull nginxinterroge d'abord le mirror- Si l'image est en cache, téléchargement local (rapide)
- Sinon, le mirror télécharge depuis Docker Hub et met en cache
Vérifier la configuration :
docker info | grep -A5 "Registry Mirrors"Insecure registries
Section intitulée « Insecure registries »Pour les registries internes sans HTTPS ou avec certificats auto-signés :
{ "insecure-registries": [ "registry.local:5000", "192.168.1.100:5000" ]}Authentification par défaut
Section intitulée « Authentification par défaut »L'authentification aux registries est stockée dans ~/.docker/config.json (par utilisateur, pas dans daemon.json).
# Connexion interactivedocker login registry.example.com
# Vérifier les credentials stockéscat ~/.docker/config.jsonCredential helpers pour stockage sécurisé :
{ "credHelpers": { "gcr.io": "gcloud", "*.dkr.ecr.*.amazonaws.com": "ecr-login" }}Optimisations production
Section intitulée « Optimisations production »Les options qui suivent ne changent rien au fonctionnement de Docker sur un poste de développement : elles répondent à des contraintes d'exploitation. Continuité de service pendant une mise à jour, supervision des métriques, limites de ressources appliquées à tous les conteneurs, performances réseau. Chacune se teste isolément, car certaines modifient des comportements dont vos applications dépendent peut-être sans que vous le sachiez.
Live restore
Section intitulée « Live restore »Live restore maintient les conteneurs en fonctionnement pendant un redémarrage du daemon Docker.
{ "live-restore": true}Cas d'usage :
- Mise à jour de Docker sans interruption de service
- Récupération après crash du daemon
- Maintenance du daemon
Limitations :
- Ne fonctionne pas si arrêt manuel (
systemctl stop docker) - Les options de runtime ne doivent pas changer entre les versions
Vérification :
# Redémarrer le daemonsudo systemctl restart docker
# Les conteneurs doivent toujours tournerdocker psMetrics Prometheus
Section intitulée « Metrics Prometheus »Exposez les métriques Docker au format Prometheus pour le monitoring.
{ "metrics-addr": "0.0.0.0:9323", "experimental": true}Métriques disponibles :
| Métrique | Description |
|---|---|
engine_daemon_container_states_containers | Conteneurs par état |
engine_daemon_image_actions_seconds | Durée des opérations images |
engine_daemon_network_actions_seconds | Durée des opérations réseau |
process_cpu_seconds_total | CPU utilisé par le daemon |
Accès aux métriques :
curl http://localhost:9323/metricsConfiguration Prometheus (prometheus.yml) :
scrape_configs: - job_name: 'docker' static_configs: - targets: ['docker-host:9323']Ressources par défaut
Section intitulée « Ressources par défaut »Définissez des limites appliquées à tous les conteneurs par défaut.
{ "default-ulimits": { "nofile": { "Name": "nofile", "Hard": 65535, "Soft": 65535 }, "nproc": { "Name": "nproc", "Hard": 4096, "Soft": 4096 } }, "default-shm-size": "64M"}| Option | Description |
|---|---|
nofile | Limite de descripteurs de fichiers |
nproc | Limite de processus |
default-shm-size | Taille de /dev/shm |
Surcharge par conteneur :
docker run --ulimit nofile=1024:2048 myappUserland proxy
Section intitulée « Userland proxy »Le userland proxy gère le port forwarding en espace utilisateur. Le désactiver améliore les performances mais peut causer des problèmes avec localhost.
{ "userland-proxy": false}Avantages désactivé :
- Meilleures performances réseau
- Moins de processus (pas de docker-proxy)
Inconvénients :
- Problèmes avec connexions localhost vers conteneurs
- Incompatibilité avec certains scénarios hairpin
Activez le support IPv6 natif pour les conteneurs. L'option porte sur le réseau bridge par défaut et rend les conteneurs bi-pile : ils conservent leur adresse IPv4 et reçoivent en plus une adresse IPv6 prise dans la plage déclarée.
{ "ipv6": true, "fixed-cidr-v6": "2001:db8:1::/64"}| Option | Description |
|---|---|
ipv6 | Active IPv6 sur le bridge par défaut |
fixed-cidr-v6 | Plage d'adresses IPv6 pour les conteneurs |
Vérification :
docker run --rm alpine ip -6 addr show eth0Validation et rechargement
Section intitulée « Validation et rechargement »Une erreur dans daemon.json ne se manifeste qu'au redémarrage du daemon, c'est-à-dire au moment où tous les conteneurs sont déjà arrêtés. D'où la règle : on valide d'abord, on applique ensuite. Reste à choisir comment appliquer, car toutes les options ne se rechargent pas à chaud.
Valider avant d'appliquer
Section intitulée « Valider avant d'appliquer »Ces trois commandes vont du plus superficiel au plus complet : jq ne vérifie que la syntaxe JSON, alors que dockerd --validate contrôle aussi que les options existent et sont compatibles entre elles.
# Validation complète par dockerdsudo dockerd --validate
# Validation JSON simplejq . /etc/docker/daemon.json
# Valider et voir les valeurs par défautsudo dockerd --config-file /etc/docker/daemon.json --validateRechargement à chaud vs redémarrage
Section intitulée « Rechargement à chaud vs redémarrage »Certaines options peuvent être appliquées sans redémarrer le daemon (rechargement à chaud via SIGHUP), tandis que d'autres nécessitent un redémarrage complet. Cette distinction est importante en production pour minimiser les interruptions.
| Option | Reload (SIGHUP) | Restart |
|---|---|---|
debug | ✅ | ✅ |
labels | ✅ | ✅ |
live-restore | ✅ | ✅ |
max-concurrent-downloads | ✅ | ✅ |
max-concurrent-uploads | ✅ | ✅ |
shutdown-timeout | ✅ | ✅ |
storage-driver | ❌ | ✅ |
data-root | ❌ | ✅ |
log-driver | ❌ | ✅ |
default-runtime | ❌ | ✅ |
# Reload (options compatibles)sudo systemctl reload docker# ousudo kill -SIGHUP $(pidof dockerd)
# Restart (toutes les options)sudo systemctl restart dockerExemple complet daemon.json production
Section intitulée « Exemple complet daemon.json production »Voici une configuration de référence pour un environnement de production :
{ "data-root": "/mnt/docker-data", "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "5", "compress": "true" }, "live-restore": true, "userland-proxy": false, "no-new-privileges": true, "default-ulimits": { "nofile": { "Name": "nofile", "Hard": 65535, "Soft": 65535 } }, "default-shm-size": "64M", "registry-mirrors": [ "https://mirror.gcr.io" ], "metrics-addr": "127.0.0.1:9323", "experimental": true, "max-concurrent-downloads": 10, "max-concurrent-uploads": 5}Points clés de cette configuration :
- overlay2 : storage driver performant
- data-root : partition dédiée
- Rotation logs : évite de remplir le disque
- live-restore : continuité de service
- no-new-privileges : sécurité par défaut
- Métriques : monitoring Prometheus (localhost uniquement)
Dépannage
Section intitulée « Dépannage »Quand Docker refuse de démarrer après une modification, l'information utile n'est pas dans docker ps, qui ne répond plus, mais dans le journal systemd du service. Le message d'erreur y désigne presque toujours la ligne ou l'option fautive de daemon.json.
Logs du daemon
Section intitulée « Logs du daemon »La première commande affiche le journal du service en continu, la seconde lance le daemon au premier plan en mode bavard pour voir sa configuration effective au démarrage.
# Logs systemdjournalctl -u docker.service -f
# Mode debugsudo dockerd --debugErreurs courantes
Section intitulée « Erreurs courantes »Les erreurs de configuration du daemon empêchent généralement Docker de démarrer. Voici les messages d'erreur les plus fréquents et leurs solutions.
| Erreur | Cause | Solution |
|---|---|---|
invalid character | Erreur JSON | Valider avec jq |
unable to configure the Docker daemon with file | Option invalide | Vérifier la documentation |
Error starting daemon: error initializing graphdriver | Storage driver incompatible | Supprimer /var/lib/docker |
daemon not running | Erreur de config | Consulter journalctl -u docker |
permission denied | Droits fichier | chmod 644 daemon.json |
Réinitialiser la configuration
Section intitulée « Réinitialiser la configuration »En cas de blocage, écarter le fichier ramène Docker à ses valeurs par défaut et permet de le redémarrer. Renommez plutôt que de supprimer : vous garderez la configuration fautive pour la corriger option par option.
# Arrêter Dockersudo systemctl stop docker
# Sauvegarder et supprimer la configsudo mv /etc/docker/daemon.json /etc/docker/daemon.json.bak
# Redémarrer avec config par défautsudo systemctl start dockerÀ retenir
Section intitulée « À retenir »- daemon.json se trouve dans
/etc/docker/sur Linux et n'existe pas par défaut - Le magasin d'images se lit, il ne se force pas :
overlayfssur une installation Docker 29 récente,overlay2sur une machine héritée - Rotation des logs obligatoire avec
max-sizeetmax-file - registry-mirrors accélèrent les pulls et évitent les rate limits
- live-restore maintient les conteneurs pendant les redémarrages daemon
- Validez toujours avec
dockerd --validateavant de redémarrer - Certaines options nécessitent un restart complet, d'autres supportent reload
- Partition dédiée pour
/var/lib/dockeren production
Contrôle des connaissances
Section intitulée « Contrôle des connaissances »Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Gérer les secrets : Ce que la configuration du démon ne doit jamais contenir.
- Protéger la socket avec un proxy : La suite logique quand un outil tiers réclame l'accès au démon.
- Ce qui se passe sous le capot : Ce que chaque option de
daemon.jsondéclenche côté noyau.