В какой-то момент понадобилось мне запустить новый docker-compose.yml файл. Процесс загрузки образов и настройки окружения контейнеров прошел хорошо, даже контейнеры создались, но далее процесс не пошел.

Получаем ошибку

Что бы получить ошибку достаточно выполнить следующую команду:

1
docker run -it --rm --init fedora bash

Вместо того, что бы оказаться в bash контейнера с Fedora, получаем такую ошибку:

1
docker: Error response from daemon: exec: "docker-init": executable file not found in $PATH

Точно такая же ошибка падала при развертывании docker-compose.yml.

Поиски причины

Так как в Fedora у меня установлен moby-engine, проверил что есть в официальном пакете с докером:

1
2
3
4
5
6
7
8
9
❯ rpm -qlp https://download.docker.com/linux/fedora/43/x86_64/stable/Packages/docker-ce-29.1.4-1.fc43.x86_64.rpm
предупреждение: https://download.docker.com/linux/fedora/43/x86_64/stable/Packages/docker-ce-29.1.4-1.fc43.x86_64.rpm: Header OpenPGP V4 RSA/SHA512 signature, key ID c52feb6b621e9f35: NOKEY
/etc/docker
/usr/bin/docker-proxy
/usr/bin/dockerd
/usr/lib/systemd/system/docker.service
/usr/lib/systemd/system/docker.socket
/usr/libexec/docker/docker-init
/usr/share/man/man8/dockerd.8.gz

Да, действительно там есть файл /usr/libexec/docker/docker-init на который сейчас жалуется докер. А есть ли этот файл где-то в другом пакете в Fedora?

1
2
3
4
❯ dnf provides '*/docker-init'
Обновление и загрузка репозиториев:
Репозитории загружены.
No matches found. If searching for a file, try specifying the full path or using a wildcard prefix ("*/") at the beginning.

К сожалению найти такой файл (в моих подключенных репах) не получилось. Но среди зависимостей moby-engine есть tini-static:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
❯ dnf repoquery --requires moby-engine
Обновление и загрузка репозиториев:
Репозитории загружены.
/bin/sh
container-selinux
containerd
docker-cli = 28.4.0-1.fc43
docker-cli = 29.1.3-1.fc43
iptables
libc.so.6(GLIBC_2.34)(64bit)
libnftables.so.1()(64bit)
libnftables.so.1(LIBNFTABLES_1)(64bit)
libseccomp
libsystemd.so.0()(64bit)
libsystemd.so.0(LIBSYSTEMD_209)(64bit)
moby-filesystem = 28.4.0-1.fc43
moby-filesystem = 29.1.3-1.fc43
nftables
pigz
rtld(GNU_HASH)
systemd
tar
tini-static
xz

Именно tini и должен использоваться вместо docker-init, но почему-то не хочет использоваться. Проверим, что же указано в moby-engine:

1
2
3
4
❯ dnf repoquery -l moby-engine | grep docker.service
Обновление и загрузка репозиториев:
Репозитории загружены.
/usr/lib/systemd/system/docker.service

Так, есть в нем такой файл, для запуска сервиса с докером. И в этом файл прописано:

1
2
3
4
5
6
7
8
❯ cat moby-engine-29.1.3-1.fc43.x86_64/usr/lib/systemd/system/docker.service | grep ExecStart -A6
ExecStart=/usr/bin/dockerd \
    -H fd:// \
    --containerd=/run/containerd/containerd.sock \
    --selinux-enabled \
    --userland-proxy-path /usr/bin/docker-proxy \
    --init-path /usr/bin/tini-static
ExecReload=/bin/kill -s HUP $MAINPID

Теперь проверяем что же systemd сейчас делает при запуске докера:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
❯ systemctl cat docker.service | head -n 20
# /etc/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=docker.socket network-online.target firewalld.service
Requires=docker.socket
Wants=network-online.target

[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/docker
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd \
          --host=fd:// \
          --exec-opt native.cgroupdriver=systemd \
          $OPTIONS
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead

Оказывается что файл, который сейчас используеться в systemd лежит в совсем другом месте: /etc/systemd/system/docker.service и нечего не знает про --init-path /usr/bin/tini-static. Если попробовать найти чей это файл, то выясняется:

1
2
3
4
5
6
7
❯ dnf provides /etc/systemd/system/docker.service
Обновление и загрузка репозиториев:
Репозитории загружены.
No matches found. If searching for a file, try specifying the full path or using a wildcard prefix ("*/") at the beginning.

❯ ls -al /etc/systemd/system/docker.service
-rw-r--r--. 1 root root 1313 мар 27  2023 /etc/systemd/system/docker.service

Решение

Файл /etc/systemd/system/docker.service лежит с марта 2023 года и по логике загрузки systemd - заменяет собой тот, что есть в /usr/lib/systemd/system. Так что удаляем кастомный файл и перечитываем все сервис файлы:

1
2
3
4
❯ sudo rm /etc/systemd/system/docker.service
[sudo] пароль для user:

❯ systemctl daemon-reload

После чего еще раз пробуем запустить:

1
2
❯ docker run -it --rm --init fedora bash
[root@410a1e428d08 /]#

Наблюдаем что все теперь работает.