Docker « Impossible de se connecter au daemon Docker » : corrections qui fonctionnent réellement

Cet article vous a aidé ?

L’erreur arrive toujours au pire moment : vous êtes en pleine mise en production, votre CI vient de passer en rouge, ou vous tentez d’exécuter une commande rapide avant une réunion.
Vous tapez docker ps et Docker répond par l’équivalent d’un haussement d’épaules :
Impossible de se connecter au daemon Docker.

Ce n’est pas un seul problème. C’est un symptôme. Parfois le daemon est arrêté. Parfois il tourne mais vous interrogez le mauvais socket.
Parfois vous n’avez pas le droit d’y accéder. Et parfois vous n’êtes même pas sur la machine que vous croyez. Corrigeons la bonne chose, rapidement,
sans rites de cargo-cultes « sudo sur tout ».

Ce que l’erreur signifie réellement (et pourquoi elle ment)

Le CLI Docker est un client. Le daemon Docker (dockerd) est un serveur. L’erreur « Impossible de se connecter » est le client qui dit :
« J’ai essayé d’atteindre le serveur à un certain endpoint et j’ai échoué. »

Cet endpoint est généralement un socket Unix sur Linux : /var/run/docker.sock. Sur Docker Desktop, c’est un socket proxifié via
l’application Desktop et une VM. Dans des configurations distantes, cela peut être du TCP avec TLS, ou du transport SSH. Si le client ne peut pas ouvrir le socket, ne peut pas
s’authentifier, ou se connecte au mauvais endroit, vous obtenez le même message générique.

Il y a quatre grandes catégories :

  • Le daemon n’est pas en fonctionnement (service arrêté, boucle de crash, mise à jour ratée).
  • Le daemon tourne mais est injoignable (mauvais chemin de socket, mauvais context, mauvais DOCKER_HOST, problèmes DNS/SSH/TLS).
  • Permission refusée (utilisateur non membre du groupe docker, mismatch rootless, permissions du socket).
  • Le daemon ne peut pas démarrer (disque plein, état corrompu, problèmes de driver de stockage, échecs cgroup/iptables, config incompatible).

Faits intéressants et courte histoire (parce que le passé continue de casser votre présent)

  1. Le choix par défaut original de Docker était un socket Unix local. L’« API distante sur TCP » est venue plus tard et reste un piège de sécurité.
  2. systemd a changé la donne pour la gestion des services Linux ; « Docker est arrêté » est devenu « systemd dit que c’est up, mais il n’est pas réactif » (problème différent).
  3. Docker Desktop utilise une VM sur macOS et Windows ; vous ne parlez jamais à un dockerd « natif » sur l’OS hôte.
  4. Le mode rootless existe pour éviter un daemon possédé par root, mais il change sockets, chemins et attentes—bonne idée, confusion fréquente.
  5. Le groupe docker équivaut pratiquement à root sur la plupart des systèmes. Il peut monter le système de fichiers hôte et sortir des conteneurs. Traitez-le comme sudo.
  6. OverlayFS est devenu le driver de stockage dominant sur Linux, remplaçant des drivers plus anciens comme AUFS ; les mises à jour peuvent révéler des bizarreries de système de fichiers latentes.
  7. L’adoption des cgroups v2 (maintenant courante) a modifié des hypothèses de contrôle des ressources ; des anciennes configs de daemon peuvent casser de façons étranges.
  8. La transition iptables/nftables a causé des années de surprises réseau pour les conteneurs ; un daemon peut « démarrer » mais échouer à configurer les règles NAT.
  9. Les contexts Docker ont été introduits pour gérer plusieurs endpoints proprement ; ils ont aussi rendu plus facile de parler accidentellement au mauvais daemon.

Un modèle mental utile : le CLI Docker ne « démarre » pas Docker. Il demande juste à Docker de faire des choses. Si la ligne téléphonique est coupée, vous pouvez crier plus fort
(sudo) mais vous criez toujours dans un récepteur muet.

Une citation à garder sur un post‑it, parce qu’elle évite des heures de débogage supersticieux :
Idée paraphrasée de Sidney Dekker : la fiabilité réside dans la façon dont les systèmes répondent aux surprises, pas dans l’absence de surprises.

Playbook de diagnostic rapide : premières/deuxièmes/troisièmes vérifications

Quand vous êtes d’astreinte, vous n’« explorez » pas. Vous resserrez le périmètre. Voici le chemin le plus court vers la vérité.

Premier : Quel endpoint le CLI tente-t-il d’utiliser ?

  • Vérifiez docker context et les variables d’environnement (DOCKER_HOST, DOCKER_CONTEXT).
  • Décision : si cela pointe vers distant, Desktop ou rootless, dépannez cette voie — pas systemctl sur l’hôte.

Second : Le daemon est‑il vivant et à l’écoute ?

  • Sur Linux : systemctl status docker et journalctl -u docker.
  • Décision : si le service est arrêté ou en boucle de crash, corrigez les erreurs de démarrage avant de toucher aux permissions.

Troisième : S’il est vivant, est‑ce un problème de permission ou de chemin de socket ?

  • Inspectez la propriété/mode de /var/run/docker.sock, confirmez vos groupes utilisateur.
  • Décision : si c’est un « permission denied », corrigez l’appartenance au groupe (ou utilisez rootless correctement). Évitez « chmod 666 » comme la peste.

Quatrième (seulement si nécessaire) : Le daemon échoue‑t‑il à cause de ressources ou de configuration ?

  • Espace disque/inodes. Driver de stockage. Cgroups/iptables. Proxy env. Certificats TLS.
  • Décision : choisissez la correction ciblée qui traite l’erreur dans les logs, pas celle dont vous vous souvenez de l’année dernière.

Blague #1 : Le dépannage Docker, c’est comme faire un espresso — la plupart des gens accusent la machine, alors que c’est généralement la mouture (votre endpoint).

Tâches pratiques : commandes, sorties, décisions (12+)

Chaque tâche ci‑dessous comporte trois parties : une commande à exécuter, ce que la sortie signifie généralement, et la décision à prendre.
C’est la section « arrêtez de deviner ».

Tâche 1 : Voir exactement où le CLI Docker essaie de se connecter

cr0x@server:~$ docker context ls
NAME        DESCRIPTION                               DOCKER ENDPOINT               ERROR
default *   Current DOCKER_HOST based configuration   unix:///var/run/docker.sock
prod        Production daemon over SSH                ssh://deploy@prod-host

Signification : L’astérisque marque le context actif. L’endpoint indique le transport et le socket/hôte.

Décision : Si le context actif n’est pas celui souhaité, changez de context avant toute autre action.

Tâche 2 : Afficher les variables d’environnement qui remplacent l’endpoint

cr0x@server:~$ env | egrep '^(DOCKER_HOST|DOCKER_CONTEXT|DOCKER_TLS_VERIFY|DOCKER_CERT_PATH)='
DOCKER_HOST=tcp://127.0.0.1:2375

Signification : Votre shell force Docker à utiliser TCP sur 2375 (souvent via un script ou profil ancien).

Décision : Désactivez-la (unset DOCKER_HOST) ou corrigez‑la pour l’endpoint voulu. Ne déboguez pas /var/run/docker.sock tant que cela n’est pas réglé.

Tâche 3 : Vérification rapide — le CLI atteint‑il le daemon ?

cr0x@server:~$ docker version
Client: Docker Engine - Community
 Version:           26.1.3
 API version:       1.45
 Go version:        go1.22.3
 Git commit:        9e34c2a
 OS/Arch:           linux/amd64

Server:
ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Signification : Le client est installé ; le serveur n’est pas joignable.

Décision : Passez aux vérifications service/socket. Ne réinstallez pas le client ; il est déjà là.

Tâche 4 : Sur Linux, vérifiez si systemd pense que Docker tourne

cr0x@server:~$ systemctl status docker --no-pager
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; preset: enabled)
     Active: active (running) since Tue 2026-01-02 09:14:03 UTC; 7min ago
TriggeredBy: ● docker.socket
       Docs: man:dockerd(8)
   Main PID: 1423 (dockerd)
      Tasks: 19
     Memory: 88.2M
        CPU: 1.268s
     CGroup: /system.slice/docker.service
             └─1423 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Signification : Le daemon tourne, donc « Impossible de se connecter » est probablement un mauvais endpoint ou un problème de permissions.

Décision : Passez aux vérifications de permissions du socket et de context/env, pas aux redémarrages.

Tâche 5 : Si Docker est arrêté, démarrez‑le et voyez s’il reste up

cr0x@server:~$ sudo systemctl start docker
cr0x@server:~$ systemctl is-active docker
active

Signification : Le service a démarré avec succès (pour l’instant).

Décision : Vérifiez immédiatement les logs s’il bascule. « Active » maintenant ne garantit pas qu’il le restera dans 30 secondes.

Tâche 6 : Lire les 100 dernières lignes des logs ; arrêtez de deviner

cr0x@server:~$ sudo journalctl -u docker --no-pager -n 100
Jan 02 09:12:41 server dockerd[1399]: failed to start daemon: error initializing graphdriver: no space left on device
Jan 02 09:12:41 server systemd[1]: docker.service: Main process exited, code=exited, status=1/FAILURE
Jan 02 09:12:41 server systemd[1]: docker.service: Failed with result 'exit-code'.

Signification : Pas un problème de permissions. Pas un problème de socket. Le daemon ne peut pas initialiser le stockage à cause d’un disque plein.

Décision : Corrigez l’espace disque/inodes d’abord. Redémarrer ne servira à rien.

Tâche 7 : Confirmer que le socket existe et qui en est propriétaire

cr0x@server:~$ ls -l /var/run/docker.sock
srw-rw---- 1 root docker 0 Jan  2 09:14 /var/run/docker.sock

Signification : Le socket existe, propriété root:docker, accessible aux membres du groupe docker.

Décision : Si vous n’êtes pas dans le groupe docker, soit ajoutez‑vous (en connaissance de cause) soit utilisez sudo/rootless correctement.

Tâche 8 : Confirmer que votre utilisateur est dans le groupe docker

cr0x@server:~$ id
uid=1001(cr0x) gid=1001(cr0x) groups=1001(cr0x),27(sudo)

Signification : Vous n’êtes pas dans docker.

Décision : Ajoutez l’utilisateur au groupe (ou décidez de ne pas accorder ce privilège et utilisez sudo).

Tâche 9 : Ajouter l’utilisateur au groupe docker en toute sécurité, puis vous reconnecter

cr0x@server:~$ sudo usermod -aG docker cr0x
cr0x@server:~$ newgrp docker
cr0x@server:~$ id
uid=1001(cr0x) gid=1001(cr0x) groups=1001(cr0x),27(sudo),999(docker)

Signification : Le shell courant a maintenant le groupe docker.

Décision : Retentez docker ps. Si votre organisation traite le groupe docker comme privilégié (ce qu’elle devrait), documentez et restreignez l’appartenance.

Tâche 10 : Détecter un mismatch rootless vs rootful

cr0x@server:~$ docker info 2>/dev/null | egrep 'Rootless|Docker Root Dir|Server Version'
 Server Version: 26.1.3
 Docker Root Dir: /var/lib/docker
 Rootless: false

Signification : Vous parlez à un daemon rootful (système global).

Décision : Si vous vouliez rootless, vous êtes sur le mauvais context ou le mauvais socket. Si vous vouliez rootful, continuez à dépanner permissions et santé du service.

Tâche 11 : Si le disque est plein, mesurez sérieusement (espace et inodes)

cr0x@server:~$ df -h /var/lib/docker
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p3  120G  120G  120M 100% /

cr0x@server:~$ df -i /var/lib/docker
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/nvme0n1p3  7.6M    7.6M    1.2K  100% /

Signification : Vous êtes à court de bytes et d’inodes. Les conteneurs et couches consomment beaucoup d’inodes.

Décision : Libérez de l’espace (prune images/containers) ou augmentez le stockage. Ne vous attendez pas à ce que le daemon démarre tant que les deux nombres ne sont pas raisonnables.

Tâche 12 : Trouver ce qui mange /var/lib/docker

cr0x@server:~$ sudo du -xhd1 /var/lib/docker | sort -h
1.2G    /var/lib/docker/containers
6.8G    /var/lib/docker/overlay2
8.1G    /var/lib/docker

Signification : Les couches overlay sont le principal consommateur. C’est normal ; la question est de savoir si c’est hors de contrôle.

Décision : Envisagez docker system df et le pruning, mais seulement après avoir confirmé que vous ne supprimerez pas d’images nécessaires en production.

Tâche 13 : Pruner en sécurité (et comprendre ce que vous supprimez)

cr0x@server:~$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          42        6         18.3GB    12.7GB (69%)
Containers      9         2         1.1GB     700MB (63%)
Local Volumes   16        8         9.4GB     2.2GB (23%)
Build Cache     88        0         6.5GB     6.5GB

cr0x@server:~$ docker system prune -f
Deleted Containers:
...
Total reclaimed space: 8.1GB

Signification : Vous avez récupéré de l’espace, principalement à partir d’images/caches inutilisés.

Décision : Si c’est en production, obtenez une approbation explicite ou utilisez un pruning ciblé (docker image prune) pour éviter de supprimer des couches mises en cache utiles pour le déploiement.

Tâche 14 : Vérifier que le daemon écoute là où vous le pensez

cr0x@server:~$ sudo ss -xlpn | egrep 'docker\.sock|containerd\.sock'
u_str LISTEN 0      4096   /run/docker.sock  22788            * 0    users:(("dockerd",pid=1423,fd=4))
u_str LISTEN 0      4096   /run/containerd/containerd.sock  22787 * 0 users:(("containerd",pid=961,fd=7))

Signification : dockerd écoute sur /run/docker.sock, pas nécessairement sur /var/run/docker.sock (souvent un symlink).

Décision : Si votre client pointe vers /var/run/docker.sock et que ce chemin est cassé, réparez le symlink ou corrigez l’endpoint.

Tâche 15 : Repérer un symlink /var/run cassé (oui, ça arrive)

cr0x@server:~$ ls -l /var/run/docker.sock
ls: cannot access '/var/run/docker.sock': No such file or directory

cr0x@server:~$ ls -ld /var/run
lrwxrwxrwx 1 root root 4 Jan  2 08:59 /var/run -> /run

Signification : Le répertoire runtime canonique est /run ; /var/run est un symlink. Si /run/docker.sock existe mais pas l’autre, quelque chose est incohérent.

Décision : Préférez unix:///run/docker.sock si votre système l’utilise. Réparez les chemins cassés plutôt que de chmod des fichiers au hasard.

Linux (systemd) : quand le service est arrêté ou malade

Sur les serveurs Linux, cette erreur est souvent simple : dockerd ne tourne pas. Mais « ne tourne pas » a des couches, comme tout bon incident de stockage.
Un service peut être arrêté, en boucle de crash, bloqué sur des dépendances, ou vivant mais incapable de répondre aux requêtes API parce qu’il est coincé dans des tâches de démarrage.

Commencez par la vue de systemd, puis confirmez la réalité

Si systemctl status indique « active (running) », vérifiez que le socket existe et que vous pouvez réellement interroger le daemon.
Si ça affiche « failed », ne touchez pas aux permissions. Regardez d’abord les logs.

Bloqueurs de démarrage courants que vous verrez dans les logs

  • Disque plein / exhaustion d’inodes : l’initialisation du graphdriver échoue ; Docker ne peut pas monter les couches overlay.
  • daemon.json invalide : une faute de frappe stoppe le daemon net.
  • problèmes iptables : Docker peut démarrer mais ne peut pas créer de réseaux ; parfois il échoue au démarrage selon la distro et la config.
  • mismatch cgroup : anciennes configs sur noyaux récents peuvent casser les hypothèses du runtime conteneur.
  • containerd down : dockerd dépend de containerd ; s’il est malade, Docker peut ne pas démarrer ou se comporter étrangement.

Validez daemon.json au lieu de vous disputer avec lui

cr0x@server:~$ sudo cat /etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": { "max-size": "10m", "max-file": "3" },
  "data-root": "/var/lib/docker",
  "iptables": true
}

cr0x@server:~$ sudo jq . /etc/docker/daemon.json >/dev/null
cr0x@server:~$ echo $?
0

Signification : Le JSON se parse correctement.

Décision : Si jq échoue, corrigez le JSON avant de redémarrer Docker. systemd redémarrera volontiers une config cassée indéfiniment.

Redémarrer avec intention, pas en panique

cr0x@server:~$ sudo systemctl restart docker
cr0x@server:~$ systemctl --no-pager -l status docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; preset: enabled)
     Active: active (running) since Tue 2026-01-02 10:02:19 UTC; 3s ago
       Docs: man:dockerd(8)

Signification : Docker a redémarré et est actuellement vivant.

Décision : Testez immédiatement docker ps. Si ça marche, vous avez terminé. Si ça échoue, le problème n’était pas « service arrêté ».

Si docker.service est « active » mais que le CLI ne peut toujours pas se connecter

C’est là que les professionnels perdent du temps s’ils ne ralentissent pas. Si le daemon tourne, « Impossible de se connecter » est presque toujours l’un de :
(a) mauvais endpoint, (b) permissions, ou (c) vous êtes dans un conteneur/namespace où le chemin du socket n’existe pas.

Vérifiez les arguments du processus pour voir sur quoi il écoute :

cr0x@server:~$ ps -ef | grep -E '[d]ockerd'
root      1423     1  0 09:14 ?        00:00:03 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Signification : -H fd:// signifie que l’activation de socket systemd est en jeu ; l’unité socket de Docker compte.

Décision : Inspectez docker.socket si le fichier socket n’apparaît pas.

cr0x@server:~$ systemctl status docker.socket --no-pager
● docker.socket - Docker Socket for the API
     Loaded: loaded (/lib/systemd/system/docker.socket; enabled; preset: enabled)
     Active: active (listening) since Tue 2026-01-02 09:13:58 UTC; 48min ago
   Triggers: ● docker.service
     Listen: /run/docker.sock (Stream)

Signification : L’unité socket écoute sur /run/docker.sock.

Décision : Assurez‑vous que votre endpoint client correspond (unix:///run/docker.sock) ou que le symlink /var/run est intact.

Permissions et groupes : docker.sock et l’habitude du « sudo »

La variante la plus courante de « Impossible de se connecter » est vraiment :
permission refusée lors de la tentative de connexion au socket du daemon Docker.
Docker imprime souvent les deux messages, mais les gens ne lisent que la première ligne et redémarrent les services comme si c’était une alerte incendie.

Comprenez ce que vous accordez

Ajouter un utilisateur au groupe docker est pratique. C’est aussi accorder un contrôle proche de root, parce que Docker peut monter le système de fichiers hôte
ou exécuter des conteneurs privilégiés. En environnement d’entreprise, cela devrait être traité comme un accès sudo.

Diagnostiquer les problèmes de permission proprement

cr0x@server:~$ docker ps
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.45/containers/json": dial unix /var/run/docker.sock: connect: permission denied

Signification : Le daemon tourne probablement ; votre utilisateur ne peut pas ouvrir le socket.

Décision : Corrigez l’appartenance au groupe ou utilisez sudo docker pour cet hôte (avec accord de la politique). Ne chmod pas le socket en world‑writable.

N’utilisez pas « chmod 666 /var/run/docker.sock »

Ça « corrige » l’erreur en rendant le socket de contrôle Docker accessible à tous. Ce n’est pas une correction. C’est laisser vos clés de serveur sous le paillasson
et ensuite être surpris d’avoir été cambriolé. De plus : systemd recréera le socket au redémarrage avec les permissions appropriées, donc votre « correction » est instable de toute façon.

Quand sudo est acceptable

Sur des machines de développement personnelles, d’accord. Sur des systèmes partagés, des runners CI, et tout ce qui contient des données clients, préférez fortement des schémas d’accès explicites :
appartenance contrôlée au groupe, Docker rootless, ou un agent de build dédié avec des privilèges minimaux.

Vérifiez à quoi devraient ressembler les permissions du socket

cr0x@server:~$ stat -c '%A %U:%G %n' /run/docker.sock
srw-rw---- root:docker /run/docker.sock

Signification : Seuls root et le groupe docker peuvent lire/écrire le socket.

Décision : Si le groupe n’est pas docker ou si le mode est inhabituel, vérifiez les overrides d’unité systemd ou les changements de packaging de la distro.

Mauvais endpoint : contexts Docker, DOCKER_HOST, SSH, TLS

Si Docker tourne et que les permissions sont correctes, le coupable suivant le plus probable est que vous vous connectez au mauvais endroit.
Les contexts ont rendu le travail multi‑environnements raisonnable. Ils ont aussi rendu facile de parler silencieusement à un daemon mort parce que votre shell se souvenait d’un choix.

Connaître les règles de priorité

  • DOCKER_HOST écrase presque tout.
  • DOCKER_CONTEXT sélectionne un context (et écrase le contexte « courant »).
  • Le « context courant » est ce que docker context use définit.
  • Docker Desktop configure souvent un context comme desktop-linux.

Changez de context explicitement et vérifiez

cr0x@server:~$ docker context use default
default
cr0x@server:~$ docker context inspect --format '{{.Name}} -> {{.Endpoints.docker.Host}}' default
default -> unix:///var/run/docker.sock

Signification : Vous êtes revenu au socket local.

Décision : Retestez la commande Docker. Si ça marche maintenant, vous venez de corriger une erreur humaine de mémoire, pas un bug du daemon.

Remote over SSH : diagnosez d’abord la jambe SSH

cr0x@server:~$ docker --context prod ps
Cannot connect to the Docker daemon at ssh://deploy@prod-host. Is the docker daemon running?

cr0x@server:~$ ssh -o BatchMode=yes -o ConnectTimeout=5 deploy@prod-host 'systemctl is-active docker'
active

Signification : Docker est actif sur la machine distante, et SSH fonctionne. Le problème restant peut être les permissions du socket distant ou un mismatch de config SSH.

Décision : Essayez d’exécuter une commande docker distante via SSH directement comme test de contrôle, ou vérifiez si l’utilisateur distant peut accéder au socket docker.

cr0x@server:~$ ssh deploy@prod-host 'docker ps'
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: connect: permission denied

Signification : L’utilisateur distant n’a pas les permissions.

Décision : Corrigez l’accès de l’utilisateur distant (groupe docker ou politique sudo). Ne continuez pas à manipuler les contexts localement.

Endpoints TCP : si vous devez, faites‑le sérieusement

Si vous voyez tcp:// dans DOCKER_HOST, soyez suspicieux. Le port 2375 est typiquement HTTP non chiffré. Le port 2376 est couramment TLS.
Docker API en TCP non protégé est un « shell root distant » si exposé. Bien pour les attaquants. Mauvais pour dormir.

cr0x@server:~$ echo "$DOCKER_HOST"
tcp://127.0.0.1:2375

cr0x@server:~$ curl -sS 127.0.0.1:2375/_ping
OK

Signification : Quelque chose écoute sur 2375 et répond comme Docker.

Décision : Si c’est inattendu, supprimez cette configuration. Si c’est voulu, assurez‑vous que c’est lié au loopback uniquement et, de préférence, protégé par TLS.

Docker Desktop : modes de défaillance sur macOS et Windows

Les environnements Desktop créent une confusion particulière : le CLI Docker est sur votre hôte, mais le daemon est dans une VM.
Quand Desktop casse, vous pouvez chasser des services Linux fantômes qui n’existent pas.

macOS : le daemon n’est pas un service launchd que vous pouvez « systemctl »

Sur macOS, Docker Desktop gère son propre backend. Si vous obtenez « Impossible de se connecter », vous avez généralement l’un des cas suivants :

  • L’application Desktop n’est pas lancée ou est bloquée au démarrage
  • context basculé hors de desktop-linux
  • état Desktop corrompu (rare, mais réel)
  • VPN/proxy/filtres réseau interférant avec la plomberie de la VM
cr0x@server:~$ docker context ls
NAME            DESCRIPTION                               DOCKER ENDPOINT               ERROR
default *       Current DOCKER_HOST based configuration   unix:///var/run/docker.sock
desktop-linux   Docker Desktop                            unix:///Users/cr0x/.docker/run/docker.sock

Signification : Vous êtes sur default mais Desktop attend desktop-linux.

Décision : Basculez vers desktop-linux et retentez. Si le chemin du socket sous votre répertoire personnel n’existe pas, le backend Desktop n’est pas actif.

Windows : WSL2 et confusion de contexts

Sur Windows avec WSL2, vous pouvez avoir au moins trois réalités différentes :
le CLI Docker dans PowerShell parlant à Docker Desktop,
le CLI Docker dans une distro WSL parlant via l’intégration Desktop,
ou un dockerd que vous avez installé dans WSL (ce que vous ne devriez probablement pas faire).

Si vous êtes dans WSL et que vous avez installé Docker Engine là‑dedans, il se peut que systemd manque (selon distro/settings) et que le service ne démarre jamais.
Si vous comptez sur l’intégration Desktop, votre distro WSL ne devrait pas exécuter son propre dockerd.

cr0x@server:~$ docker info 2>/dev/null | egrep 'Operating System|Docker Root Dir|Server Version'
 Server Version: 26.1.3
 Operating System: Docker Desktop
 Docker Root Dir: /var/lib/docker

Signification : Vous parlez au backend de Docker Desktop.

Décision : Si ça ne peut pas se connecter, corrigez Desktop (redémarrage, reset, résoudre l’intégration WSL). Ne déboguez pas systemd Linux dans WSL à moins de gérer votre propre moteur.

Blague #2 : Si Docker Desktop dit « Starting… » pendant 20 minutes, il ne démarre pas — il contemple vos choix de vie.

Docker rootless, runners CI et « ça marche sur mon laptop »

Docker rootless change l’emplacement du socket et le modèle de propriété. C’est le but. Cela casse aussi des hypothèses intégrées dans des scripts,
des jobs CI, et ce README que personne n’a mis à jour depuis la dernière réorganisation.

Reconnaître les sockets rootless

Docker rootless écoute généralement sur un socket possédé par l’utilisateur sous quelque chose comme /run/user/1001/docker.sock.
Votre CLI peut être toujours pointé vers /var/run/docker.sock, ce qui échouera (ou se connectera à un autre daemon).

cr0x@server:~$ ls -l /run/user/$(id -u)/docker.sock
srw-rw---- 1 cr0x cr0x 0 Jan  2 10:21 /run/user/1001/docker.sock

Signification : Le socket rootless existe pour votre utilisateur.

Décision : Pointez votre client vers lui (via un context ou DOCKER_HOST=unix:///run/user/1001/docker.sock) et arrêtez d’essayer de « réparer » /var/run.

Runners CI : éphémères, restreints, et parfois volontairement sans daemon

En CI, « Impossible de se connecter au daemon Docker » peut être un comportement attendu : vous êtes sur un runner qui ne fournit pas Docker‑in‑Docker, ou le conteneur de service
n’a pas été lancé. La bonne correction est d’aligner l’architecture du pipeline, pas d’ajouter le mode privilégié partout.

cr0x@server:~$ ls -l /var/run/docker.sock
ls: cannot access '/var/run/docker.sock': No such file or directory

Signification : Il n’y a pas de socket daemon local. En CI, cela signifie souvent que le job n’est pas censé utiliser Docker directement.

Décision : Montez le socket (si votre modèle de sécurité le permet), utilisez un builder distant, ou utilisez une chaîne d’outils rootless. N’installez pas Docker aveuglément.

Docker-in-Docker (DinD) : comprenez le compromis

DinD exécute typiquement un daemon séparé dans un conteneur. Si vous oubliez de le démarrer, ou s’il manque des privilèges/stockage requis, vous obtiendrez la même erreur.
C’est un pattern valide pour certains workloads CI. C’est aussi un compromis performance et sécurité.

cr0x@server:~$ docker run --rm docker:26.1-dind dockerd --version
Docker version 26.1.3, build 9e34c2a

Signification : L’image dind contient dockerd, mais cela ne signifie pas que votre environnement CI permettra son exécution.

Décision : Si vous avez besoin de DinD, assurez‑vous que le runner supporte les conteneurs privilégiés et fournit suffisamment d’I/O disque. Sinon utilisez un daemon distant ou une approche basée sur BuildKit.

Stockage et disque : quand le daemon ne peut pas respirer

Les pannes de stockage sont le cousin sournois de l’erreur « Impossible de se connecter ». Le CLI ne peut pas se connecter parce que le daemon n’a jamais atteint le point où il peut accepter des connexions.
Ou il accepte les connexions mais est inutilisable parce qu’il thrash le disque.

Disque plein n’est pas juste disque plein

Docker se soucie de :

  • Bytes (df -h)
  • Inodes (df -i)
  • Fonctionnalités du système de fichiers (attentes OverlayFS)
  • Amplification d’écriture (couches overlay plus logs volumineux = tristesse)

Identifier le driver de stockage et s’il est approprié

cr0x@server:~$ docker info 2>/dev/null | egrep 'Storage Driver|Backing Filesystem|Supports d_type'
 Storage Driver: overlay2
 Backing Filesystem: ext4
 Supports d_type: true

Signification : overlay2 sur ext4 avec support d_type est la bonne voie.

Décision : Si vous voyez Supports d_type: false ou un driver inattendu, attendez‑vous à des comportements étranges de couches et à des problèmes de démarrage ; corrigez le système de fichiers/config avant d’accuser Docker.

Quand des problèmes de performance ressemblent à des problèmes de connectivité

Parfois le daemon est « en fonctionnement » mais tellement coincé sur des I/O que le client dépasse le délai et rapporte un échec de connexion.
Vous verrez de longs retards, un docker ps bloqué, et des logs avec des timeouts parlant à containerd.

cr0x@server:~$ sudo iostat -xz 1 3
Linux 6.8.0 (server)  01/02/2026  _x86_64_  (8 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          10.23    0.00    6.12   58.90    0.00   24.75

Device            r/s     rkB/s   rrqm/s  %rrqm  r_await  w/s     wkB/s   w_await  aqu-sz  %util
nvme0n1         20.0    1200.0     0.0    0.0    2.10   900.0  64000.0   45.80   35.2   99.5

Signification : Le disque est saturé ; la latence d’écriture est élevée. Les opérations metadata Docker vont stagner.

Décision : Traitez cela comme un incident de ressources : réduisez la charge d’écriture (logs !), libérez de l’espace, déplacez data-root Docker vers un disque plus rapide, ou répartissez la charge.

Croissance des logs : le tueur silencieux de /var

Le logging par défaut json-file de Docker peut manger les disques quand des applications spamment les logs. Votre daemon ne se soucie pas que ce soit « juste des logs » ;
il se soucie de ne plus pouvoir écrire metadata et couches.

cr0x@server:~$ sudo find /var/lib/docker/containers -name '*-json.log' -printf '%s %p\n' | sort -n | tail -n 3
8246331120 /var/lib/docker/containers/1d9c.../1d9c...-json.log
9123341120 /var/lib/docker/containers/88af.../88af...-json.log
10322354112 /var/lib/docker/containers/a3b1.../a3b1...-json.log

Signification : Des logs de conteneurs individuels font plusieurs Go. Cela peut remplir le disque et empêcher dockerd de démarrer.

Décision : Mettez en place la rotation des logs via daemon.json (max-size, max-file) et/ou centralisez les logs. Puis tronquez les pires fichiers avec précaution.

Trois mini-histoires du monde corporate

1) L’incident causé par une mauvaise hypothèse : « le context default veut dire local »

Une entreprise de taille moyenne avait un setup propre : les développeurs utilisaient Docker Desktop localement, la production tournait sur des VM Linux, et l’équipe ops utilisait les contexts Docker pour gérer plusieurs environnements.
L’équipe avait un context « prod » configuré sur SSH pour les opérations. C’était pratique. Trop pratique.

Un matin, un ingénieur obtient « Impossible de se connecter au daemon Docker » sur son laptop. Il a supposé que Docker Desktop était mort. Donc il a fait ce que tout le monde fait :
redémarrer Docker Desktop, reboot du Mac, et l’erreur persistait. La frustration monte. Slack s’affole. Personne n’a regardé docker context ls.

Le vrai problème : son profil de shell exportait DOCKER_CONTEXT=prod depuis une intervention de la semaine précédente. Donc le CLI Docker du laptop n’essayait pas de se connecter localement.
Il tentait l’endpoint SSH de production. Sauf que la production avait tourné des host keys et la config SSH locale rejetait la connexion.
L’erreur du CLI était techniquement exacte mais émotionnellement inutile.

La correction a pris deux minutes une fois que quelqu’un a posé la question ennuyeuse : « Où te connectes‑tu ? »
Ils ont retiré l’export d’environnement, basculé le context vers Desktop, et documenté une politique d’équipe : ne jamais exporter des variables de context Docker persistantes dans les profils shell.
Utilisez des commandes explicites et des shells à courte durée pour le travail prod. La commodité est une taxe que vous payez plus tard.

2) L’optimisation qui a mal tourné : « Mettons Docker sur le gros filesystem partagé »

Une autre organisation a tenté d’optimiser l’usage disque. Leurs serveurs de build manquaient d’espace, et le stockage coûtait cher.
Quelqu’un a proposé de déplacer le data-root de Docker sur un filesystem réseau partagé monté sur chaque builder.
Une copie des couches, partagée entre machines. En PowerPoint, c’était la victoire.

Ils ont implémenté cela, mis à jour /etc/docker/daemon.json, redémarré Docker, et pendant quelques jours « ça marchait ».
Puis le premier incident réel : des « Impossible de se connecter au daemon Docker » intermittents sur des builders aléatoires. Pas tous en même temps ; un ici, un là.
systemd montrait docker.service « active », mais le CLI bloquait ou échouait. Les logs contenaient des timeouts containerd et des erreurs overlay.

Le retour de bâton venait de réalités qui ne figurent pas dans un tableau de coûts :
overlay2 et les métadonnées container sont extrêmement bavards. La latence compte. La sémantique de verrouillage compte. Les incidents réseau comptent.
Sous charge, le filesystem partagé a introduit de longs temps d’écriture ; dockerd devenait non réactif, et parfois plantait lors des scans de démarrage.

La correction finale n’a pas été héroïque. Elle a été architecturale : gardez les couches Docker inscriptibles sur des SSD locaux, utilisez un registry pour partager les images,
et laissez le cache se faire aux bons niveaux (cache de build, mirrors de registry) plutôt que de faire semblant qu’un filesystem partagé remplace un disque local.
L’« optimisation » essayait de partager la mauvaise chose.

3) La pratique ennuyeuse mais correcte qui a sauvé la mise : rotation des logs et marge disque

Une plateforme liée à la finance avait des exigences strictes de disponibilité et une équipe SRE pragmatique. Ils n’étaient pas des personnes excitantes en soirée.
Ils ont fait quelque chose d’impopulaire : ils ont imposé des politiques de marge disque et configuré la rotation des logs Docker partout, même en dev.

Un vendredi, une nouvelle version de service a été déployée avec un bug qui spammait les logs dans une boucle de retry. Dans d’autres organisations, c’est là que les disques se remplissent,
Docker s’arrête, et le week‑end disparaît. Ici, les logs des conteneurs ont tourné automatiquement. L’usage disque a monté, puis s’est stabilisé. Les alertes se sont déclenchées sur « logging inhabituel »,
pas sur « le système est mort ».

Les ingénieurs ont rollbacké, corrigé le bug, et sont rentrés chez eux. Pas de crash de daemon. Pas d’erreurs en cascade « Impossible de se connecter ». Pas de triage de système de fichiers à minuit.
La cause racine importait toujours, mais la plateforme avait suffisamment de garde‑fous pour empêcher la propagation de la panne.

La leçon est prévisible et ennuyeuse : les « valeurs par défaut ennuyeuses » ne le sont pas quand elles vous évitent de déboguer le stockage à 3h du matin.
Mettez des limites sur les logs. Gardez de la marge. Supposez que les humains vont livrer des logiciels bruyants.

Erreurs fréquentes : symptôme → cause racine → correction

1) « Impossible de se connecter… » après changement d’environnement

  • Symptôme : Ça marchait hier, ça échoue aujourd’hui ; systemctl status docker semble OK.
  • Cause racine : Mauvais Docker context ou DOCKER_HOST/DOCKER_CONTEXT défini dans le shell.
  • Correction : docker context ls, désactivez les overrides d’environnement, docker context use default ou le context Desktop correct.

2) « permission denied … /var/run/docker.sock »

  • Symptôme : L’erreur mentionne permission denied ; le service Docker est actif.
  • Cause racine : Utilisateur non membre du groupe docker, ou permissions inattendues du socket à cause d’un override d’unité.
  • Correction : Ajoutez l’utilisateur au groupe docker (selon la politique), reconnectez/reprenez un newgrp, vérifiez la propriété root:docker et le mode 660.

3) « No such file or directory » pour docker.sock

  • Symptôme : Chemin du socket manquant.
  • Cause racine : Daemon non démarré, docker.socket désactivé, ou vous êtes dans un namespace/conteneur sans bind mount du socket.
  • Correction : Démarrez/activez le service et la socket docker ; dans les conteneurs, montez /var/run/docker.sock intentionnellement ou utilisez un daemon distant.

4) Le service Docker ne démarre plus après un changement de config

  • Symptôme : systemctl start docker échoue ; les logs montrent des erreurs de parsing.
  • Cause racine : JSON invalide ou clé non prise en charge dans /etc/docker/daemon.json.
  • Correction : Validez avec jq, revenez à la dernière modification, redémarrez. Gardez les changements minimes et revus.

5) Docker « active » mais le CLI bloque ou timeoute

  • Symptôme : docker ps bloque ; finalement « Impossible de se connecter » ou timeouts ; forte charge.
  • Cause racine : Saturation I/O disque, containerd bloqué, ou énormes opérations de métadonnées/couches au démarrage.
  • Correction : Vérifiez iowait, espace libre, réduisez le spam de logs, envisagez de déplacer data-root vers un disque plus rapide, redémarrez containerd si nécessaire.

6) Docker Desktop : le CLI ne peut pas se connecter mais le débogage Linux ne montre rien

  • Symptôme : Sur macOS/Windows, vous essayez systemctl et c’est hors sujet.
  • Cause racine : Backend Desktop non lancé, état corrompu, ou mauvais context.
  • Correction : Basculez sur le context Desktop, redémarrez Desktop, vérifiez les paramètres d’intégration WSL (Windows), resettez l’état seulement si nécessaire.

7) Confusion rootless : le socket existe, mais le CLI pointe ailleurs

  • Symptôme : Vous avez /run/user/UID/docker.sock mais le CLI tente /var/run/docker.sock.
  • Cause racine : Le context/env pointe toujours vers l’endpoint rootful.
  • Correction : Définissez le context correct ou exportez DOCKER_HOST vers le socket rootless pour cette session.

8) Proxies d’entreprise : les commandes Docker échouent de façons qui ressemblent à des problèmes de daemon

  • Symptôme : « Impossible de se connecter » apparaît lors des pulls/builds, surtout avec des contexts distants.
  • Cause racine : Variables proxy appliquées de manière incohérente ; NO_PROXY manquant pour socket/hosts locaux ; MITM d’entreprise intercepte TLS.
  • Correction : Confirmez les variables proxy et NO_PROXY ; gardez la config proxy du daemon explicite plutôt que d’hériter d’un env shell aléatoire.

Checklists / plan étape par étape

Checklist A : Vous êtes sur Linux et vous avez juste besoin que Docker fonctionne maintenant

  1. Confirmez l’endpoint : docker context ls ; env | egrep '^DOCKER_'.
  2. Vérifiez le service : systemctl is-active docker.
  3. Si inactif : sudo systemctl start docker, puis sudo journalctl -u docker -n 100 en cas d’échec.
  4. Si actif mais en échec : vérifiez l’existence et les perms du socket : ls -l /run/docker.sock et id.
  5. Si permission refusée : définissez la politique (groupe docker vs sudo). Ajoutez le groupe seulement si acceptable.
  6. Si lié au disque : lancez df -h et df -i ; récupérez l’espace délibérément.

Checklist B : Vous suspectez un mauvais context/endpoint distant

  1. docker context ls : identifiez le context actif et l’endpoint.
  2. env | egrep '^(DOCKER_HOST|DOCKER_CONTEXT)=' : retirez les overrides.
  3. docker context use default (ou celui voulu).
  4. Retestez avec docker version pour voir sections client/serveur.
  5. Si vous utilisez SSH : testez SSH séparément ; puis exécutez ssh host docker ps pour isoler les permissions distantes.

Checklist C : Le service Docker ne démarre pas (ne forcez pas)

  1. sudo journalctl -u docker -n 200 : capturez la vraie erreur.
  2. Validez /etc/docker/daemon.json avec jq.
  3. Vérifiez bytes et inodes : df -h, df -i.
  4. Vérifiez le driver de stockage et les attentes du FS (docker info si ça démarre ; sinon consultez les logs).
  5. Seulement ensuite redémarrez : sudo systemctl restart docker.

Checklist D : Docker Desktop (macOS/Windows)

  1. Confirmez que le context est Desktop : docker context ls.
  2. Si le chemin du socket sous votre home manque, le backend Desktop est down.
  3. Redémarrez Desktop ; si WSL2, confirmez que l’intégration est activée pour la bonne distro.
  4. Évitez d’exécuter un second dockerd dans WSL sauf si vous gérez volontairement cette complexité.

FAQ

1) Pourquoi Docker dit « Is the docker daemon running? » alors qu’il tourne ?

Parce que le CLI ne peut pas atteindre l’endpoint configuré. Le daemon peut tourner sur un socket différent, un context différent, ou une machine différente.
Vérifiez d’abord les contexts et DOCKER_HOST.

2) Dois‑je simplement tout lancer avec sudo ?

Pour un débogage rapide, sudo docker ps peut confirmer un problème de permissions. À long terme, c’est salissant et cache les vrais problèmes.
Gérez l’appartenance au groupe docker explicitement ou utilisez Docker rootless quand c’est adapté.

3) Est‑ce sûr de m’ajouter au groupe docker ?

« Sûr » dépend de votre modèle de menace. Pratiquement, être membre du groupe docker rapproche des privilèges root sur cette machine.
Traitez cela comme un accès administratif et restreignez‑le en conséquence.

4) Pourquoi /var/run/docker.sock n’existe pas ?

Soit Docker n’est pas démarré, soit l’unité socket est désactivée, soit vous êtes dans un environnement (comme un conteneur ou un runner CI minimal) où le socket n’est pas monté.
Notez aussi que beaucoup de distributions utilisent /run/docker.sock avec /var/run comme symlink.

5) J’ai corrigé l’appartenance au groupe mais ça dit encore permission denied. Et maintenant ?

Confirmez que votre shell courant a bien les groupes mis à jour (id). Si non, reconnectez‑vous ou utilisez newgrp docker.
Puis vérifiez que le groupe du socket est effectivement docker et que le mode est srw-rw----.

6) Docker Desktop tourne, mais le CLI ne peut toujours pas se connecter. Quelle est la cause la plus courante ?

Le mauvais context. Les gens alternent entre « default » et « desktop-linux » (ou similaire) et oublient.
Lancez docker context ls et basculez sur le context Desktop.

7) Un disque plein peut‑il causer « Impossible de se connecter au daemon Docker » ?

Oui. Un disque plein (ou des inodes pleins) peut empêcher dockerd de démarrer, ou le bloquer lors de l’initialisation du stockage.
Vérifiez journalctl -u docker, df -h et df -i.

8) Quelle est la façon la plus rapide de savoir si je touche le mauvais daemon (local vs distant) ?

Utilisez docker context inspect pour voir l’endpoint, puis exécutez docker info et regardez les champs « Operating System » / « Name ».
Desktop et les moteurs distants s’identifient souvent clairement.

9) Comment éviter ce type d’incident en production ?

Maintenez une marge disque et une rotation des logs configurée, surveillez docker.service et la santé de containerd, évitez les emplacements de stockage exotiques pour data-root,
et rendez l’utilisation des contexts explicite dans les scripts opérationnels (pas d’exports d’env cachés).

10) Est‑ce qu’un mismatch client/serveur Docker peut causer ça ?

Rarement pour un pur « impossible de se connecter », mais cela peut apparaître comme des erreurs d’API après la connexion.
Si vous avez une connexion mais que les commandes échouent étrangement, comparez les versions d’API dans la sortie de docker version.

Conclusion : étapes pratiques suivantes

« Impossible de se connecter au daemon Docker » n’est pas un mystère ; c’est un problème de routage, de permissions, ou de santé du daemon.
L’astuce est de refuser de le traiter comme un bug unique.

  1. Identifiez l’endpoint : contexts et DOCKER_HOST avant toute chose.
  2. Vérifiez la santé du service et les logs : si dockerd ne peut pas démarrer, les logs vous diront pourquoi.
  3. Corrigez les permissions correctement : appartenance au groupe ou rootless, pas de sockets world‑writable.
  4. Respectez le stockage : marge disque, surveillance des inodes et rotation des logs évitent des incidents de « connectivité » qui sont en fait des incidents de filesystem.

Faites ces quatre choses et cette erreur redeviendra ce qu’elle aurait dû être depuis le début : une gêne mineure, pas un test de personnalité.

← Précédent
Docker : empêcher les conteneurs de redémarrer lors des mises à jour — verrouillez les images de façon responsable
Suivant →
Comment 3dfx a perdu : la chute la plus triste d’un roi

Laisser un commentaire