成功关注这些RHEL systemd container instructions之后,我现在想要容器,每次启动时都运行一个bash脚本。但是,我希望它只运行一次。这对我来说似乎不是一种“服务”。我不想启动容器,然后手动运行bash脚本(例如,docker exec -it ...)。我应该创建一个systemd单元文件来启动脚本,然后在我的bash脚本中禁用该服务吗?这看起来有点像黑客,不是吗?
更新:要回答评论者,bash脚本需要systemd。因此,首先必须启动systemd,然后运行脚本,安装软件,然后发出systemctl start命令。是的,我知道你在想什么:使用RUN安装软件然后让systemd启动它,但不幸的是,我不能为这个项目做到这一点。我没写过的脚本希望systemd能够运行。此外,该脚本确实在容器内,在命名卷中运行。
答案 0 :(得分:2)
您可以为bash脚本创建服务类型oneshot
的systemd单元文件。 oneshot
类型表示短期过程,通常作为一次性任务运行。 systemd在继续使用其他单位之前等待进程退出。
例如,
[Unit]
Description=my only-once script
[Service]
Type=oneshot
ExecStart=/bin/bash /path/to/only_once_script.sh
RemainAfterExit=true
StandardOutput=journal
[Install]
WantedBy=multi-user.target
请注意,如果您希望systemd在启动操作成功完成后将服务视为活动,则必须将RemainAfterExit
设置为true
。
在systemd docs中查看示例2 和示例3 。
答案 1 :(得分:1)
如果您只需要“systemd”,因为安装程序运行“systemctl start”命令,那么您可以使用systemctl-docker-replacement包装器来避免模糊。
我经常使用它来覆盖/ usr / bin / systemctl,在这种情况下,“systemctl start”正确执行,而不运行任何systemd守护程序。经过大量安装程序测试,以模仿他们期望从“systemctl start”开始的行为。
答案 2 :(得分:0)
您可以在同一服务中执行此操作。考虑我机器上的以下流程
$ docker run -d ubuntu:16.04 sleep 200
2e76d13cee285143dc91af0e6ddbd51bd31e92d7baa3ec34638726cdd0abb572
$ docker exec -d 2e76d13cee285143dc91af0e6ddbd51bd31e92d7baa3ec34638726cdd0abb572 sleep 300
$ docker exec 2e76d13cee285143dc91af0e6ddbd51bd31e92d7baa3ec34638726cdd0abb572 ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.2 0.0 4384 756 ? Ss 12:25 0:00 sleep 200
root 5 0.1 0.0 4384 792 ? Ss 12:25 0:00 sleep 300
root 9 0.0 0.2 34428 2740 ? Rs 12:25 0:00 ps aux
如你所见,我在后台执行了一个命令(-d / - exec命令的分离)
所以在你的服务文件中。只需在主设备中定义启动Docker容器的ExecStartPost=
,然后使用带有exec
标记的-d