我想对我们的 docker/docker-compose/podman 设置进行系统化,但似乎 systemd 无法正确处理在不留下进程的情况下结束的服务单元。这是有问题的,因为所讨论的工具通过调用 API 来工作,调度进程启动但不生成或分叉它们本身,因此当对 docker-compose 的调用返回时,systemd 没有可见进程,因此Type/RemainAfterExit 的任何变化仍然会导致服务被标记为停止/死亡/停止等,因为没有检测到幸存的 PID。
我不确定这是否相关,但我在用户空间中运行--user
.为用户启用延迟。
这是我让 systemd 工作的众多尝试之一,但与任何其他设置组合一样,它会在 5 秒后停止:
[Unit]
Description=%u service with docker compose
BindsTo=podman.service
After=podman.service
[Service]
Environment=DOCKER_HOST=unix:///run/user/%U/podman/podman.sock
Environment=XDG_RUNTIME_DIR=/run/user/%U
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/srv/podman/%u
ExecStart=/usr/local/bin/docker-compose up -d --remove-orphans
ExecStop=/usr/local/bin/docker-compose down -v
[Install]
WantedBy=default.target
我从上面的文件开始systemctl --user start myservice.service
。它产生如下输出:
May 04 14:10:27 myhost systemd[841]: Starting myservice service with docker compose...
May 04 14:10:27 myhost docker-compose[106023]: Container nginx Creating
May 04 14:10:27 myhost docker-compose[106023]: Container nginx Created
May 04 14:10:27 myhost docker-compose[106023]: Container nginx Starting
May 04 14:10:27 myhost docker-compose[106023]: Container nginx Started
May 04 14:10:27 myhost systemd[841]: Finished myservice service with docker compose.
May 04 14:10:32 myhost systemd[841]: Stopping myservice service with docker compose...
May 04 14:12:03 myhost systemd[841]: myservice.service: Stopping timed out. Terminating.
May 04 14:12:03 myhost systemd[841]: myservice.service: Failed with result 'timeout'.
May 04 14:12:03 myhost systemd[841]: myservice.service: Unit process 106072 (docker-compose) remains running after unit stopped.
May 04 14:12:03 myhost systemd[841]: Stopped myservice service with docker compose.
May 04 14:12:03 myhost docker-compose[106072]: Container nginx Stopping
May 04 14:12:03 myhost docker-compose[106072]: Container nginx Stopped
May 04 14:12:03 myhost docker-compose[106072]: Container nginx Removing
May 04 14:12:03 myhost docker-compose[106072]: Container nginx Removed
答案1
当执行时docker-compose
,systemd
您不想守护进程(-d
从您的 中删除该选项ExecStart
),以便systemd
可以正确跟踪它。
您可能也不需要声明Type=
或RemainAfterExit=
选项,因为默认值应该适合docker-compose
服务。
如果您想为单个容器提供服务,我建议您查看podman generate systemd
其中一个容器的输出,并将 Docker 服务文件调整为类似的。
另一个注意事项:podman.service
不应该持续运行,因为它是从 调用的podman.socket
。设置After=
为参考podman.socket
可能更接近您期望的行为。我不确定该BindsTo=
选项是您正在寻找的。虽然podman.socket
运行命令需要它docker-compose
,但运行容器不需要它,并且我不确定您是否希望在 Podman API 重新启动时重新启动所有容器。
综上所述,您发布的服务文件将如下所示:
[Unit]
Description=%u service with docker compose
After=podman.socket
[Service]
Environment=DOCKER_HOST=unix:///run/user/%U/podman/podman.sock
Environment=XDG_RUNTIME_DIR=/run/user/%U
WorkingDirectory=/srv/podman/%u
ExecStart=/usr/local/bin/docker-compose up --remove-orphans
ExecStop=/usr/local/bin/docker-compose down -v
[Install]
WantedBy=default.target
这些都是我跑步podman
和docker-compose
穿越的经历systemd
。希望其中一些可以帮助您为容器制作工作服务。