Помилка зазвичай з’являється у найневідповідніший момент: ви якраз робите деплой, CI щойно впав у червоне, або намагаєтеся виконати швидку однорядкову команду перед нарадою.
Ви вводите docker ps і Docker відповідає еквівалентом жесту безсилих плечей:
Не вдається підключитися до демона Docker.
Це не одна конкретна проблема. Це симптом. Іноді демон просто вимкнений. Іноді він запущений, але ви звертаєтесь не до того сокета.
Іноді вам заборонено з ним спілкуватися. А іноді ви навіть не на тій машині, про яку думаєте. Виправимо саме те, що потрібно, швидко,
без культу «sudo на все».
Що насправді означає помилка (і чому вона бреше)
Docker CLI — це клієнт. Демон Docker (dockerd) — це сервер. Помилка «Не вдається підключитися» — це клієнт, який каже:
«Я намагався дістатися сервера за якимось endpoint і зазнав невдачі».
Цей endpoint зазвичай — Unix-сокет на Linux: /var/run/docker.sock. На Docker Desktop це сокет, проксований через
додаток Desktop і віртуальну машину. У віддалених налаштуваннях це може бути TCP з TLS або транспорт через SSH. Якщо клієнт не може відкрити сокет, не може
аутентифікуватися або підключається не туди — ви отримаєте однакове узагальнене повідомлення.
Є чотири великі категорії:
- Демон не запущений (сервіс зупинено, цикл падінь, невдала оновлення).
- Демон запущений, але недоступний (неправильний шлях сокета, неправильний контекст, неправильний
DOCKER_HOST, проблеми з DNS/SSH/TLS). - Відмова в доступі (користувач не в групі
docker, невідповідність rootless, права на сокет). - Демон не може запуститися (диск заповнений, пошкоджений стан, проблеми з драйвером зберігання, cgroup/iptables, несумісна конфігурація).
Цікаві факти та коротка історія (бо минуле продовжує ламати ваше сьогодення)
- Початковий дефолт Docker був локальний Unix-сокет. «Віддалений API по TCP» з’явився пізніше і відтоді є серйозною проблемою безпеки.
- systemd змінив правила гри для управління сервісами на Linux; «Docker впав» перетворився на «systemd каже, що він запущений, але він не відповідає» (інша проблема).
- Docker Desktop використовує VM на macOS і Windows; ви ніколи не спілкуєтесь з «рідним» dockerd на хості.
- Режим rootless існує, щоб уникнути демонa від імені root, але він змінює сокети, шляхи й очікування — хороша ідея, часта плутанина.
- Група docker фактично = root на більшості систем. Вона може монтувати файлову систему хоста і дозволяти вихід із контейнера. Ставтеся до неї як до sudo.
- OverlayFS став основним драйвером зберігання на Linux, замінивши старіші, як AUFS; оновлення можуть виявити приховані проблеми файлової системи.
- Прийняття cgroups v2 (тепер поширене) змінило припущення про контроль ресурсів; старі конфіги демона можуть ламаються незвично.
- Переходи iptables/nftables принесли роки несподіванок у мережуванні контейнерів; демон може «запуститися», але не змогти налаштувати NAT-правила.
- Docker contexts ввели для керування кількома endpoint’ами; вони також полегшили випадкове звертання до неправильного демона.
Корисна ментальна модель: Docker CLI не «запускає Docker». Він лише просить Docker щось зробити. Якщо телефонна лінія обрізана, ви можете голосно кричати
(sudo), але ви все одно кричите в неробочий приймач.
Одна цитата, варта запису на стікері, бо вона рятує від годин віри в забобони під час дебагу:
Парафраз ідеї Sidney Dekker: надійність живе в тому, як системи реагують на сюрпризи, а не в відсутності сюрпризів.
Швидкий план діагностики: перші/другі/треті перевірки
Коли ви на виклику, ви не «досліджуєте». Ви звужуєте коло. Ось найкоротший шлях до істини.
Перше: який endpoint намагається використовувати CLI?
- Перевірте
docker contextі змінні оточення (DOCKER_HOST,DOCKER_CONTEXT). - Рішення: якщо він вказує на віддалений, Desktop або rootless, усувайте проблему на тому шляху — не бійтеся запускати
systemctlна хості.
Друге: чи живий демон і чи слухає він?
- На Linux:
systemctl status dockerтаjournalctl -u docker. - Рішення: якщо сервіс вимкнений або в циклі падінь, виправте помилки запуску перед тим, як чіпати права доступу.
Третє: якщо він живий — чи проблема в правах або шляху сокета?
- Перевірте власника/режим
/var/run/docker.sock, підтвердіть групи користувача. - Рішення: якщо відмова в доступі, виправте членство в групі (або використайте rootless належним чином). Уникайте «chmod 666» як чуму.
Четверте (тільки якщо потрібно): чи демон не стартує через ресурси або конфігурацію?
- Диск/іноди. Драйвер зберігання. Cgroups/iptables. Проксі змінні. TLS сертифікати.
- Рішення: обирайте вузьке виправлення, яке відповідає помилці в логах, а не те, що ви пам’ятаєте з минулого року.
Жарт №1: Розслідування Docker схоже на приготування еспресо — більшість хвалять машину, а насправді проблема в помолі (ваш endpoint).
Практичні завдання: команди, виводи, рішення (12+)
Кожне завдання нижче має три частини: команду, яку можна виконати, що зазвичай означає її вивід, і яке рішення потрібно прийняти.
Це секція «припиніть гадати».
Завдання 1: Дізнайтеся точно, куди CLI намагається підключитися
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
Значення: Зірочка позначає активний контекст. Endpoint показує транспорт і шлях сокета/хоста.
Рішення: Якщо активний контекст не той, що треба, перемкніть контексти перш ніж робити інші дії.
Завдання 2: Показати змінні оточення, що перевизначають endpoint
cr0x@server:~$ env | egrep '^(DOCKER_HOST|DOCKER_CONTEXT|DOCKER_TLS_VERIFY|DOCKER_CERT_PATH)='
DOCKER_HOST=tcp://127.0.0.1:2375
Значення: Ваш шел змушує Docker використовувати TCP на 2375 (часто з старого скрипта або профілю).
Рішення: Скиньте його (unset DOCKER_HOST) або виправте на потрібний endpoint. Не починайте дебаг /var/run/docker.sock, доки цього не зробите.
Завдання 3: Швидка перевірка стану — чи досягає CLI демона взагалі?
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?
Значення: Клієнт встановлений; сервер недоступний.
Рішення: Переходьте до перевірок сервісу/сокета. Не перевстановлюйте клієнт; він уже є.
Завдання 4: На Linux перевірте, що systemd думає про Docker
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
Значення: Демон запущений, отже «Не вдається підключитися» швидше за все — невідповідність endpoint або права.
Рішення: Перейдіть до перевірок прав сокета та контексту/змінних оточення, а не до перезапусків.
Завдання 5: Якщо Docker вимкнений — запустіть його і подивіться, чи тримається
cr0x@server:~$ sudo systemctl start docker
cr0x@server:~$ systemctl is-active docker
active
Значення: Сервіс успішно стартнув (поки що).
Рішення: Негайно перевірте логи, якщо він флапає. «Active» зараз не означає, що через 30 секунд він буде активним.
Завдання 6: Прочитайте останні 100 рядків логів; припиніть гадати
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'.
Значення: Це не проблема прав доступу. Не проблема сокета. Демон не може ініціалізувати сховище через вичерпання простору.
Рішення: Виправте місце на диску/іноди перш ніж перезапускати. Перезапуск не допоможе.
Завдання 7: Підтвердіть, що сокет існує і хто його власник
cr0x@server:~$ ls -l /var/run/docker.sock
srw-rw---- 1 root docker 0 Jan 2 09:14 /var/run/docker.sock
Значення: Сокет існує, власник root:docker, доступний для членів групи docker.
Рішення: Якщо ви не в групі docker, або додайте себе (усвідомлено), або використовуйте sudo/rootless належним чином.
Завдання 8: Перевірте, чи ваш користувач у групі docker
cr0x@server:~$ id
uid=1001(cr0x) gid=1001(cr0x) groups=1001(cr0x),27(sudo)
Значення: Ви не в групі docker.
Рішення: Додайте користувача до групи (або вирішіть, що не хочете такого привілею й використовуйте sudo).
Завдання 9: Додайте користувача в docker групу безпечно, потім повторно увійдіть
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)
Значення: Поточна оболонка тепер має групу docker.
Рішення: Спробуйте ще раз docker ps. Якщо ваша організація вважає групу docker привілейованою (так і має бути), документуйте і обмежуйте членство.
Завдання 10: Виявити невідповідність 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
Значення: Ви говорите з rootful демоном (системним).
Рішення: Якщо ви мали на увазі rootless — ви в неправильному контексті або на неправильному сокеті. Якщо ви очікували rootful — продовжуйте діагностику прав і здоров’я сервісу.
Завдання 11: Якщо диск повний — виміряйте це як слід (простір і іноди)
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% /
Значення: У вас закінчилися як байти, так і іноди. Контейнери й шари люблять іноди.
Рішення: Звільніть місце (prune образи/контейнери) або збільшіть сховище. Не чекайте, що демон запуститься, поки обидва показники не стануть адекватними.
Завдання 12: Знайдіть, що саме в /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
Значення: overlay-шари — головний споживач. Це нормально; питання в тому, чи воно вийшло з-під контролю.
Рішення: Розгляньте docker system df і pruning, але лише після впевненості, що ви не видалите потрібні образи в продакшні.
Завдання 13: Працюйте з prune безпечно (і розумійте, що видаляєте)
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
Значення: Ви звільнили місце, переважно з невикористовуваних образів/кешу.
Рішення: Якщо це продакшн, отримайте явне погодження або використайте цільовий pruning (docker image prune), щоб уникнути видалення кешованих шарів, потрібних для швидкого деплою.
Завдання 14: Підтвердіть, що демон слухає там, де ви думаєте
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))
Значення: dockerd слухає на /run/docker.sock, не обов’язково на /var/run/docker.sock (який часто є символьним посиланням).
Рішення: Якщо ваш клієнт вказує на /var/run/docker.sock і цей шлях пошкоджений, виправте симвлінк або скоригуйте endpoint.
Завдання 15: Знайти зламаний симвлінк /var/run (так, таке трапляється)
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
Значення: Канонічний каталог runtime — /run; /var/run — символьне посилання. Якщо /run/docker.sock існує, а інший шлях — ні, щось неконсистентно.
Рішення: Віддавайте перевагу unix:///run/docker.sock, якщо система так працює. Виправляйте зламані шляхи замість хаотичного chmod’у файлів.
Linux (systemd): коли сервіс вимкнений або хворий
На Linux-серверах ця помилка часто проста: dockerd не працює. Але «не працює» має шари, як будь-який серйозний інцидент зі сховищем.
Сервіс може бути зупинений, в циклі падінь, блокований на залежностях, або ж живий, але не може відповісти на API-запити, бо завис у стартовій роботі.
Почніть з погляду systemd, потім підтвердіть реальність
Якщо systemctl status каже «active (running)», перевірте, що сокет існує і що ви справді можете опитати демон.
Якщо каже «failed», не чіпайте права. Спочатку логи.
Типові блокери запуску, які ви побачите в логах
- Диск заповнений / вичерпано іноди: ініціалізація graphdriver завершується з помилкою; Docker не може змонтувати overlay-шари.
- Невалідний daemon.json: опечатка зупиняє демон одразу.
- Проблеми з iptables: Docker може стартувати, але не створює мережі; іноді він не стартує залежно від дистрибутива та налаштувань.
- Невідповідність cgroup: старі конфіги на нових ядрах можуть зламати припущення середовища запуску контейнерів.
- containerd вимкнений: dockerd залежить від containerd; якщо він нездоровий, Docker може не стартувати або працювати дивно.
Перевірте daemon.json замість сварок з ним
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
Значення: JSON розбирається коректно.
Рішення: Якщо jq падає — виправте JSON перед перезапуском Docker. systemd буде невтомно перезапускати зламану конфігурацію.
Перезапускайте з наміром, а не в паніці
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)
Значення: Docker перезапустився і наразі живий.
Рішення: Негайно перевірте docker ps. Якщо працює — все добре. Якщо ні — проблема не в «сервіс вимкнений».
Якщо docker.service «active», але CLI все одно не може підключитися
Тут професіонали витрачають час, якщо не загальмують. Якщо демон запущений, «Не вдається підключитися» майже завжди одне з:
(а) невідповідність endpoint, (б) права, або (в) ви в контейнері/неймспейсі, де шлях сокета не існує.
Перевірте аргументи процеса, щоб побачити, де він слухає:
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
Значення: -H fd:// означає, що в гру вступає активація сокета systemd; має значення юніт docker.socket.
Рішення: Перевірте docker.socket, якщо файл сокета не з’являється.
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)
Значення: Socket-юніт слухає на /run/docker.sock.
Рішення: Переконайтесь, що endpoint клієнта збігається (unix:///run/docker.sock) або що симвлінк /var/run цілий.
Права та групи: docker.sock і звичка sudo
Найпоширеніший варіант «Не вдається підключитися» насправді:
відмова в доступі під час спроби підключитися до сокета демона Docker.
Docker часто виводить обидва повідомлення, але люди читають лише перший рядок і йдуть перезапускати сервіси, ніби це пожежна тривога.
Зрозумійте, що ви надаєте
Додавання користувача до групи docker зручно. Це також надає майже root-контроль, бо Docker може змонтувати файлову систему хоста
або запускати привілейовані контейнери. У корпоративному середовищі це слід трактувати як доступ адміністратора.
Діагностика проблем з правами чисто
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
Значення: Демон, ймовірно, запущений; ваш користувач не може відкрити сокет.
Рішення: Виправте членство в групі або використайте sudo docker на цьому хості (з політикою дозволу). Не робіть сокет світлозаписувальним.
Не робіть «chmod 666 /var/run/docker.sock»
Це «вирішує» помилку, зробивши контролюючий сокет Docker доступним для всіх. Це не виправлення. Це як залишити ключі від сервера під килимком
і здивуватися, що вас обікрали. Також: systemd відтворить сокет при перезапуску з правильними правами, тож ваше «виправлення» нестабільне.
Коли sudo прийнятний
На персональних дев-боксах — гаразд. На спільних системах, CI-runner’ах і всьому, що містить дані клієнтів — краще обирати явні моделі доступу:
контрольоване членство в групі, rootless Docker або виділений агент збірки з мінімальними привілеями.
Перевірте, якими мають бути права на сокеті
cr0x@server:~$ stat -c '%A %U:%G %n' /run/docker.sock
srw-rw---- root:docker /run/docker.sock
Значення: Лише root і група docker можуть читати/записувати сокет.
Рішення: Якщо група не docker або режим нестандартний — перевірте systemd overrides або зміни пакування дистрибутива.
Неправильний endpoint: Docker contexts, DOCKER_HOST, SSH, TLS
Якщо Docker запущений і права в порядку, наступний ймовірний винуватець — ви підключаєтесь не туди.
Contexts зробили роботу з кількома середовищами зручною. Вони також спростили випадкове звертання до мертвого демона, бо шел запам’ятав вибір.
Знайте правила пріоритету
DOCKER_HOSTперевизначає майже все.DOCKER_CONTEXTобирає контекст (і перевизначає «поточний» контекст).- «Поточний контекст» — це те, що встановлює
docker context use. - Docker Desktop часто створює контекст на кшталт
desktop-linux.
Перемкніть контекст явно і перевірте
cr0x@server:~$ docker context use default
default
cr0x@server:~$ docker context inspect --format '{{.Name}} -> {{.Endpoints.docker.Host}}' default
default -> unix:///var/run/docker.sock
Значення: Ви повернулися до локального сокета.
Рішення: Повторіть Docker-команду. Якщо тепер працює — ви щойно виправили людську помилку пам’яті, а не баг демона.
Віддалено через SSH: спочатку діагностуйте 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
Значення: Docker активний на віддаленому хості, і SSH працює. Залишається проблема з правами віддаленого сокета або невідповідністю SSH-конфігу.
Рішення: Спробуйте виконати віддалену Docker-команду через SSH напряму як контрольний тест, або перевірте, чи віддалений користувач має доступ до сокета 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
Значення: Віддалений користувач не має прав.
Рішення: Виправте доступ віддаленого користувача (група docker або політика sudo). Не копайтеся в контекстах локально.
TCP endpoint’и: якщо вже треба — робіть це відповідально
Якщо ви бачите tcp:// у DOCKER_HOST, будьте підозрілі. Порт 2375 зазвичай — простий HTTP (без TLS). Порт 2376 часто — з TLS.
Простий TCP Docker API — це «віддалена шел-сесія з правами root», якщо відкритий. Добре для атакуючих. Погано для сну.
cr0x@server:~$ echo "$DOCKER_HOST"
tcp://127.0.0.1:2375
cr0x@server:~$ curl -sS 127.0.0.1:2375/_ping
OK
Значення: Хтось слухає на 2375 і відповідає як Docker.
Рішення: Якщо це несподівано — видаліть таку конфігурацію. Якщо очікувано — прив’яжіть до loopback і бажано захистіть TLS.
Docker Desktop: режими відмов на macOS і Windows
Desktop-середовища породжують особливий тип плутанини: Docker CLI на хості, а демон — у VM.
Коли Desktop ламається, ви можете ганятися за фантомними Linux-сервісами, яких просто не існує.
macOS: демон — не launchd-сервіс, який можна «systemctl»
На macOS Docker Desktop управляє власним бекендом. Якщо ви отримуєте «Не вдається підключитися», зазвичай одне з:
- Додаток Desktop не запущений або завис при запуску
- контекст перемкнено з
desktop-linux - пошкоджений стан Desktop (рідко, але буває)
- VPN/проксі/мережеві фільтри заважають зв’язку з 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
Значення: Ви на default, але Desktop очікує desktop-linux.
Рішення: Перемкніть на desktop-linux і спробуйте знову. Якщо шлях сокета в домашньому каталозі відсутній — бекенд Desktop не запущений.
Windows: WSL2 і плутанина контекстів
На Windows з WSL2 може бути принаймні три реальності:
Docker CLI в PowerShell, що говорить з Docker Desktop,
Docker CLI всередині WSL-дистрибутива, що говорить через інтеграцію Desktop,
або dockerd, який ви встановили всередині WSL (чого, ймовірно, робити не слід).
Якщо ви всередині WSL і встановили Docker Engine там, можливо, у вас немає systemd (залежно від дистрибутива/налаштувань) і сервіс ніколи не стартує.
Якщо ви покладаєтесь на інтеграцію Desktop, ваш WSL-дистрибутив не повинен запускати власний 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
Значення: Ви розмовляєте з бекендом Docker Desktop.
Рішення: Якщо не вдається підключитись — виправте Desktop (перезапустіть, скиньте, вирішіть питання інтеграції WSL). Не дебагуйте Linux systemd усередині WSL, якщо ви не запускаєте власний engine.
Жарт №2: Якщо Docker Desktop каже «Starting…» 20 хвилин — він не стартує, він розмірковує про ваші життєві рішення.
Rootless Docker, CI-runner’и та «в мене працює на ноуті»
Rootless Docker змінює розташування сокета і модель власності. Це саме задум. Воно також ламає припущення в скриптах,
CI-завданнях і в README, яке ніхто не оновлював з останньої реорганізації.
Розпізнавайте rootless-сокети
Rootless Docker зазвичай слухає на сокеті, що належить користувачу, наприклад /run/user/1001/docker.sock.
Ваш CLI може все ще вказувати на /var/run/docker.sock, що зазнає невдачі (або підключається до іншого демона).
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
Значення: Існує rootless-сокет для вашого користувача.
Рішення: Вкажіть клієнту цей сокет (через контекст або DOCKER_HOST=unix:///run/user/1001/docker.sock) і припиніть «ремонтувати» /var/run.
CI-runner’и: епhemeral, обмежені та іноді навмисно без демона
У CI «Не вдається підключитися до демона Docker» може бути очікуваною поведінкою: ви на раннері, який не надає Docker-in-Docker, або сервіс-контейнер
не було запущено. Правильне рішення — вирівняти архітектуру пайплайну, а не додавати привілейований режим скрізь.
cr0x@server:~$ ls -l /var/run/docker.sock
ls: cannot access '/var/run/docker.sock': No such file or directory
Значення: Локального сокета немає. У CI це часто означає, що завдання не повинно використовувати Docker напряму.
Рішення: Або змонтуйте сокет (якщо політика безпеки дозволяє), або використайте віддалений збирач, або rootless-пайплайн. Не «встановлюйте docker» сліпо.
Docker-in-Docker (DinD): розумійте компроміси
DinD зазвичай запускає окремий демон у контейнері. Якщо ви забули його запустити, або йому бракує привілеїв/сховища, ви отримаєте ту саму помилку.
Це валідний підхід для деяких CI-навантажень. Це також компроміс продуктивності та безпеки.
cr0x@server:~$ docker run --rm docker:26.1-dind dockerd --version
Docker version 26.1.3, build 9e34c2a
Значення: dind-образ містить dockerd, але це не означає, що ваше CI-середовище дозволить йому працювати.
Рішення: Якщо вам потрібен DinD — переконайтеся, що раннер підтримує привілейовані контейнери і дає достатній диск I/O. Інакше використовуйте віддалений демон або підхід на базі BuildKit.
Сховище та диск: коли демон не дихає
Помилки зі сховищем — підступні родичі помилки «Не вдається підключитися». CLI не може підключитися, бо демон ніколи не дійшов до стану, коли може приймати з’єднання.
Або він приймає з’єднання, але настільки повільний, що клієнт вичерпує таймаут.
«Диск повний» — це не просто «диск повний»
Docker дбає про:
- Байти (df -h)
- Іноди (df -i)
- Функції файлової системи (очікування OverlayFS)
- Записна ампліфікація (overlay-шари плюс масивні логи = біда)
Визначте драйвер зберігання і чи він підходить
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
Значення: overlay2 на ext4 з підтримкою d_type — хороший шлях.
Рішення: Якщо бачите Supports d_type: false або несподіваний драйвер, очікуйте дивної поведінки шарів і проблем при запуску; виправте файлову систему/конфігурацію перед тим, як звинувачувати Docker.
Коли проблеми з продуктивністю виглядають як проблеми з підключенням
Іноді демон «запущений», але так загруз у I/O, що клієнт вичерпує час і повідомляє про помилку підключення.
Ви побачите довгі затримки, зависання docker ps і логи з таймаутами при зв’язку з 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
Значення: Диск завантажений; латентність запису висока. Операції з метаданими Docker будуть стояти.
Рішення: Розглядайте це як інцидент ресурсів: зменшіть навантаження на запис (логи!), звільніть місце, перемістіть data-root на швидший диск або масштабуйтесь.
Зростання логів: тихий вбивця /var
Логування за замовчуванням у Docker у форматі json-file може з’їдати диски, коли додатки спамлять логами. Демон не переймається, що це «тільки логи»;
його турбує, що не можна записати метадані та шари.
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
Значення: Окремі логи контейнерів — багатогігабайтні. Це може заповнити диск і не дати dockerd стартувати.
Рішення: Налаштуйте ротацію логів через daemon.json (max-size, max-file) і/або перемістіть логи в централізовану систему. Потім обережно обріжте найбільші файли.
Три міні-історії з корпоративного світу
1) Інцидент через неправильне припущення: «default context означає локальний»
Середня компанія мала акуратну систему: розробники використовували Docker Desktop локально, продакшн працював на Linux VM, а опси керували кількома середовищами через Docker contexts.
Команда мала контекст «prod», налаштований по SSH для операцій. Це було зручно. Надто зручно.
Одного ранку інженер отримав «Не вдається підключитися до демона Docker» на своєму ноуті. Він припустив, що Docker Desktop помер. Тож зробив те, що роблять усі:
перезапустив Docker Desktop, перезавантажив Mac, і помилка лишилася. Розчарування зростало. Повідомлення в Slack сипались. Ніхто не подивився на docker context ls.
Насправді: в профілі шелу було експортовано DOCKER_CONTEXT=prod після минулого тижневого «гарячого виправлення». Отже CLI на ноуті не намагався підключитися локально.
Він намагався дістатися production по SSH. Але production змінив ключі хоста і локальний SSH-конфіг відхилив з’єднання.
Помилка CLI була технічно вірною, але емоційно марною.
Виправлення зайняло дві хвилини, як тільки хтось поставив нудне питання: «Куди ти намагаєшся підключитися?»
Видалили експорт зі профілю, перемкнули контекст назад на Desktop і задокументували політику: не експортувати постійно Docker context-змінні в профілі шелу.
Використовуйте явні команди і короткоживучі сесії для роботи з продом. Зручність — це податок, який ви платите пізніше.
2) Оптимізація, що обернулася проти: «Поставимо Docker на велике спільне файлове сховище»
Інша організація спробувала оптимізувати використання диска. Їхні билд-сервери закінчилися місцем, а зберігання дороге.
Хтось запропонував перемістити data-root Docker на спільний мережевий файловий сервер, змонтований на кожному білдері.
Одна копія шарів, спільна між машинами. У PowerPoint виглядало як перемога.
Вони впровадили це, оновили /etc/docker/daemon.json, перезапустили Docker, і декілька днів усе «працювало».
Потім перший серйозний інцидент: періодичні «Не вдається підключитися до демона Docker» на випадкових білдерах. Не всі одразу; тут один, там один.
systemd показував docker.service «active», але CLI зависав або падав. Логи мали таймаути containerd і помилки overlay.
Провал виплив з кількох реалій, які не видно в таблиці витрат:
overlay2 і метадані контейнерів дуже «балакучі». Латентність важлива. Бігування й блокування важливі. Мережеві збої важливі.
При навантаженні спільна ФС давала довгі очікування запису; dockerd ставав неотзивним і іноді падав під час стартових сканувань.
Остаточне рішення було не героїчне, а архітектурне: тримати записувані шари Docker на локальному SSD, використовувати реєстр для обміну образами,
і дозволити кешуванню відбуватися на правильних рівнях (build cache, registry mirrors), а не робити файлову систему «єдиним великим диском».
«Оптимізація» намагалася поширити те, що не слід поширювати.
3) Нудна, але правильна практика, яка врятувала день: ротація логів і запас простору
Платформа, що співпрацює з фінансами, мала суворі вимоги по uptime і практичну команду SRE. Вони не були найцікавішими людьми на вечірках.
Вони зробили непопулярну річ: застосували політику запасу дискового простору і налаштували ротацію Docker-логів скрізь, навіть у деві.
Одної п’ятниці прийшла нова версія сервісу з багом, що спамив логи в циклі повторного спробування. В інших організаціях це місце, де диски заповняться,
Docker впаде і вікенд зникне. Тут логи контейнера автоматично ротувалися. Використання диска зросло, а потім вирівнялося. Сигнали спрацювали на «незвичну активність логування»,
а не на «система померла».
Інженери відкотилися, виправили баг і пішли додому. Жодного краху демона. Жодних каскадних «Не вдається підключитися» помилок. Жодного ночного розбору файлової системи.
Коренева причина залишалась важливою, але платформа мала достатньо запобіжників, щоб відмову не поширити.
Урок передбачуваний: «нудні» за замовчуванням не нудні, коли вони рятують від дебагу сховища о 3 ранку.
Налаштуйте обмеження на логи. Тримайте запас. Припускайте, що люди будуть шипити гучний софт.
Типові помилки: симптом → коренева причина → виправлення
1) «Не вдається підключитися…» після перемикання між середовищами
- Симптом: Вчора працювало, сьогодні падає;
systemctl status dockerвиглядає добре. - Корінь: Неправильний Docker context або встановлені в шел змінні
DOCKER_HOST/DOCKER_CONTEXT. - Виправлення:
docker context ls, скиньте env-оверрайди,docker context use defaultабо правильний Desktop-контекст.
2) «permission denied … /var/run/docker.sock»
- Симптом: Помилка згадує відмову в доступі; Docker-сервіс активний.
- Корінь: Користувач не в групі docker, або сокет має несподівані права через override юніта.
- Виправлення: Додайте користувача в групу docker (за політикою), повторно увійдіть/newgrp, перевірте власність сокета
root:dockerі режим660.
3) «No such file or directory» для docker.sock
- Симптом: Шлях сокета відсутній.
- Корінь: Демон не запущено, docker.socket вимкнений, або ви в контейнері/неймспейсі без примонтованого сокета.
- Виправлення: Запустіть/увімкніть службу і socket; в контейнерах змонтуйте
/var/run/docker.sockнавмисно або використайте віддалений демон.
4) Docker service не стартує після зміни конфігу
- Симптом:
systemctl start dockerне вдається; логи показують помилки парсингу. - Корінь: Невалідний JSON або непідтриманий ключ у
/etc/docker/daemon.json. - Виправлення: Перевірте за допомогою
jq, відкотіть останню зміну, перезапустіть. Зберігайте зміни мінімальними та перевіреними.
5) Docker «active», але CLI зависає або таймаутиться
- Симптом:
docker psзависає; зрештою «Не вдається підключитися» або таймаути; велике навантаження. - Корінь: Насичення дискового I/O, containerd завис, або великі операції шарів/метаданих під час старту.
- Виправлення: Перевірте iowait, звільніть простір, зменшіть спам логами, розгляньте перенесення
data-rootна швидший диск, перезапустіть containerd при потребі.
6) Docker Desktop: CLI не може підключитися, але Linux-діагностика нічого не показує
- Симптом: На macOS/Windows ви пробуєте
systemctlі це не має сенсу. - Корінь: Бекенд Desktop не працює, пошкоджений стан, або неправильний контекст.
- Виправлення: Перемкніть на Desktop-контекст, перезапустіть Desktop, перевірте налаштування інтеграції WSL (Windows), скидання стану — лише за потреби.
7) Rootless-плутанина: сокет існує, але CLI вказує в інше місце
- Симптом: У вас є
/run/user/UID/docker.sock, але CLI намагається/var/run/docker.sock. - Корінь: Контекст/змінні оточення все ще вказують на rootful endpoint.
- Виправлення: Встановіть правильний контекст або експортуйте
DOCKER_HOSTна rootless-сокет для сесії.
8) Корпоративні проксі: Docker-команди падають виглядячи як проблеми демона
- Симптом: «Не вдається підключитися» під час pull/build, особливо з віддаленими контекстами.
- Корінь: Змінні проксі застосовані непослідовно; NO_PROXY відсутній для локального сокета/хостів; корпоративний MITM перехоплює TLS.
- Виправлення: Підтвердіть проксі-змінні і NO_PROXY; тримайте проксі-конфіг демона явним, а не успадкованим випадково від шелу.
Контрольні списки / покроковий план
Чекліст A: Ви на Linux і потрібно просто щоб Docker працював зараз
- Підтвердіть endpoint:
docker context ls;env | egrep '^DOCKER_'. - Перевірте сервіс:
systemctl is-active docker. - Якщо неактивний:
sudo systemctl start docker, потімsudo journalctl -u docker -n 100якщо не стартує. - Якщо активний, але падає: перевірте існування сокета і права:
ls -l /run/docker.sockтаid. - Якщо відмова в доступі: вирішіть політику (група docker vs sudo). Додавайте в групу лише якщо це прийнятно.
- Якщо пов’язано з диском: запустіть
df -hіdf -i; обережно відновіть простір.
Чекліст B: Підозрюєте неправильний контекст/віддалений endpoint
docker context ls: визначте активний контекст і endpoint.env | egrep '^(DOCKER_HOST|DOCKER_CONTEXT)=': видаліть оверрайди.docker context use default(або потрібний вам).- Повторно перевірте через
docker version, щоб побачити клієнт/сервер. - Якщо через SSH: протестуйте SSH окремо; потім виконайте
ssh host docker psдля ізоляції прав віддаленого середовища.
Чекліст C: Docker service не стартує (не бийте по ньому молотком)
sudo journalctl -u docker -n 200: зафіксуйте реальну помилку.- Перевірте
/etc/docker/daemon.jsonза допомогоюjq. - Перевірте байти і іноди:
df -h,df -i. - Перевірте драйвер зберігання і очікування FS (
docker infoякщо він стартує; інакше — дивіться логи). - Лише потім перезапускайте:
sudo systemctl restart docker.
Чекліст D: Docker Desktop (macOS/Windows)
- Переконайтесь, що контекст — Desktop:
docker context ls. - Якщо шлях сокета в домашньому каталозі відсутній — бекенд Desktop не працює.
- Перезапустіть Desktop; якщо WSL2 — підтвердіть, що інтеграція увімкнена для потрібного дистрибутива.
- Уникайте запуску другого dockerd всередині WSL, якщо ви свідомо не погодилися з цією складністю.
Часті питання
1) Чому Docker каже «Is the docker daemon running?» якщо він запущений?
Тому що CLI не може досягти endpoint’у, який налаштований для використання. Демон може бути запущений на іншому сокеті, в іншому контексті або на іншій машині.
Спочатку перевірте контексти і DOCKER_HOST.
2) Чи просто запускати все через sudo?
Для швидкого дебагу sudo docker ps може підтвердити проблему з правами. Але як довгострокова звичка — це погано і приховує справжні проблеми.
Керуйте членством у групі docker або використовуйте rootless Docker, де це доречно.
3) Чи безпечно додати себе в групу docker?
«Безпечно» залежить від вашої моделі загроз. Практично, членство в групі docker наближене до root на цій машині.
Сприймайте це як адміністративний доступ і обмежуйте відповідно.
4) Чому /var/run/docker.sock не існує?
Або Docker не запущено, або socket-юніт вимкнений, або ви в середовищі (наприклад контейнер чи мінімальний CI-runner), де сокет не примонтований.
Також зауважте, що багато дистрибутивів використовують /run/docker.sock з /var/run як симлінком.
5) Я виправив членство в групі, але все одно «permission denied». Що далі?
Підтвердіть, що поточна оболонка оновила групи (id). Якщо ні — повторно увійдіть або використайте newgrp docker.
Потім перевірте, що група сокета дійсно docker і режим srw-rw----.
6) Docker Desktop запущений, але CLI все одно не підключається. Яка найпоширеніша причина?
Неправильний контекст. Люди переключаються між «default» і «desktop-linux» (або подібними) і забувають.
Запустіть docker context ls і перемкніть на Desktop-контекст.
7) Чи може повний диск спричинити «Не вдається підключитися до демона Docker»?
Так. Повний диск (або іноди) може завадити dockerd стартувати або заклинити його під час ініціалізації сховища.
Перевірте journalctl -u docker, df -h і df -i.
8) Який найшвидший спосіб зрозуміти, що я звертаюсь не до того демона (локальний vs віддалений)?
Використайте docker context inspect, щоб побачити endpoint, потім виконайте docker info і подивіться на поля «Operating System» / «Name».
Desktop і віддалені рушії часто ідентифікуються явно.
9) Як уникнути цього класу відмов у продакшні?
Тримайте запас дискового простору і ротацію логів, моніторте docker.service і здоров’я containerd, уникайте екзотичних розміщень data-root,
і робіть використання контекстів явним у операційних скриптах (без прихованих env-експортів).
10) Чи може це бути несумісність версій клієнта/сервера Docker?
Рідко для чистої помилки «cannot connect», але воно може проявитися як помилки API після підключення.
Якщо з’єднання є, але команди дивно працюють — порівняйте версії API у виводі docker version.
Висновок: практичні подальші кроки
«Не вдається підключитися до демона Docker» — це не загадка; це проблема маршрутизації, прав доступу або здоров’я демона.
Хитрість — відмовитись трактувати це як одну помилку.
- Визначте endpoint: спочатку контексти і
DOCKER_HOST. - Перевірте здоров’я сервісу і логи: якщо dockerd не стартує — логи скажуть чому.
- Виправляйте права правильно: членство в групі або rootless, а не світлозаписувальні сокети.
- Повага до зберігання: запас диску, моніторинг інодів і ротація логів запобігають інцидентам, які виглядають як проблеми підключення, але по суті — файлові.
Зробіть ці чотири речі і ця помилка повернеться до свого справжнього статусу: дрібної неприємності, а не тесту на характер.