我正在尝试使用 systemd 用户服务在 ubuntu 22.04 下启动一些 docker 容器。由于 docker 容器需要运行 docker 守护程序,因此我将 包含Requires=docker.service
在单元文件中。但是,当我尝试启动 docker 容器时,systemd/systemctl 无法找到 docker 服务,即使它正在运行。
以下是启动服务的命令的结果:
$ systemctl --user start test-example-org
Failed to start test-example-org.service: Unit docker.service not found.
我可以使用以下命令查看 docker 服务正在运行:
$ systemctl list-units --type=service | egrep 'UNIT|docker|test'
UNIT LOAD ACTIVE SUB DESCRIPTION
docker.service loaded active running Docker Application Container Engine
我可以使用类似的命令查看我的用户测试服务:
$ systemctl --user list-units --type=service | egrep 'UNIT|docker|test'
UNIT LOAD ACTIVE SUB DESCRIPTION
● test-example-org.service loaded failed failed The Test example.org web server
我还可以获取 docker 守护进程的状态,如下所示:
$ systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2023-10-03 18:13:52 UTC; 2 weeks 0 days ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
我的用户单元文件包含:
$ cat ~/.config/systemd/user/test-example-org.service
[Unit]
Description=The Test example.org web server
After=multi-user.target
Requires=docker.service
Documentation=https://github.com/example/example
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=%h/test-repo
Environment=TEST_WEBSITE_STARTED_BY_SYSTEMD=true
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
Restart=on-abort
[Install]
WantedBy=multi-user.target
我使用apt
(不是snap
) 安装了 docker,以防万一。如果我Requires=docker.service
从单元服务文件中删除该行,该systemctl --start
命令会尝试运行该docker compose up
命令。
为什么systemctl --user
找不到正在运行的docker服务?
答案1
正如@steeldriver 指出的那样,用户服务似乎无法要求系统服务运行。
我认为我已经找到了一种更好的方式来表达用户服务与 docker(系统)服务的依赖关系。
Requires=docker.service
或者Requisite=docker.service
在本[Unit]
节中,我的服务最好依赖于 docker 套接字的存在。这意味着添加以下行
ConditionPathExists=/var/run/docker.sock
到该[Service]
部分。该行要求在启动用户服务之前创建 docker 套接字。当用户服务访问套接字时,如果 docker 守护进程尚未运行,则会启动它。现在我的单元文件包含:
$ cat ~/.config/systemd/user/test-example-org.service
[Unit]
Description=The Test example.org web server
After=multi-user.target
Documentation=https://github.com/example/example
[Service]
Type=oneshot
RemainAfterExit=yes
ConditionPathExists=/var/run/docker.sock
WorkingDirectory=%h/test-repo
Environment=TEST_WEBSITE_STARTED_BY_SYSTEMD=true
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
Restart=on-abort
[Install]
WantedBy=multi-user.target
现在我只需要弄清楚为什么连接到 docker 套接字时存在权限问题......