在Docker容器中启用systemctl

在Docker容器中启用systemctl,docker,ubuntu,systemctl,Docker,Ubuntu,Systemctl,我正在尝试创建我自己的docker容器,以及为我的工作创建的自定义服务,这是我的服务文件 [1/1]/etc/systemd/system/qsinavAI.service [Unit] Description=uWSGI instance to serve Qsinav AI After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/root/AI/ Environment="PATH

我正在尝试创建我自己的docker容器,以及为我的工作创建的自定义服务,这是我的服务文件 [1/1]/etc/systemd/system/qsinavAI.service

[Unit]
Description=uWSGI instance to serve Qsinav AI
After=network.target
[Service]
User=www-data
Group=www-data

WorkingDirectory=/root/AI/
Environment="PATH=/root/AI/bin"
ExecStart=/root/AI/bin/uwsgi --ini ai.ini
[Install]
WantedBy=multi-user.target
当我试图运行这个服务时,我得到了这个错误

系统尚未以systemd作为初始系统(PID 1)启动。不能 操作。无法连接到总线:主机已关闭

我搜索了很多以找到解决方案,但我找不到,如何在docker中启用systemctl。 这是我用来运行容器的命令

docker run -dt  -p 5000:5000 --name AIPython2 --privileged   -v /sys/fs/cgroup:/sys/fs/cgroup:ro --cap-add SYS_ADMIN last_python_image

Docker容器应该有一个在前台运行的“entrypoint”命令来保持容器的运行。容器背后的基本思想是,只要启动它的根进程继续运行,它就会一直运行。由于您将发出
systemctl start qsinavAI.service
,因此该命令将成功执行,但一旦该命令退出,容器将停止

根据设计,当用于运行容器的根进程退出时,容器以分离模式启动

请参阅中有关此和启动nginx服务的一些参考

因此,与其尝试将应用程序作为服务运行,不如在
Dockerfile
的末尾添加一条entrypoint语句。然后,当您使用
docker run
启动此容器时,可以指定
-d
以“分离”模式运行它

例如,从
ExecStart
获取命令并假设它在前台运行:

ENTRYPOINT ["/root/AI/bin/uwsgi", "--ini", "ai.ini"]

如果应用程序仅在容器中运行,则应创建一个docker-entrypoint.sh脚本,该脚本末尾带有“exec”,以便应用程序在容器中作为重新映射的PID 1运行。这样,云系统可以查看应用程序是否处于活动状态,并发送SIGTERM来停止应用程序

#! /bin/bash
cd /root/AI
PATH=/root/AI/bin
exec /root/AI/bin/uwsgi --ini ai.ini

如果您的应用程序能够在容器外部的systemd环境中运行,那么您可以选择重用systemd描述符。它需要PID 1上的init守护进程和服务管理器来检查“enabled”服务。脚本就是一个例子。

您需要构建一个具有发行版支持系统的映像。取舍是图像无疑会过于“臃肿”谢谢你的回复,这很有意义,所以你的意思是我必须在Dockerfile中添加ENTRYPOINT[“/root/AI/bin/uwsgi”、“--ini”、“AI.ini”?我在docker文件中添加了命令,但容器仍然没有任何日志退出,只需要确保运行应用程序的命令保持运行,而不是以零或非零退出代码退出。谢谢Guido U.Drahein!真的很有用,做了很多工作!