docker在后台运行shell脚本而不退出容器

时间:2015-07-22 17:37:04

标签: linux docker

我正在尝试在我的docker容器中运行shell脚本。问题是shell脚本生成另一个进程,它应该继续运行,除非使用另一个关闭脚本来终止由启动脚本生成的进程。

当我运行以下命令时,

docker run image:tag /bin/sh /root/my_script.sh

然后,

docker ps -a

我看到该命令已退出。但这不是我想要的。我的问题是如何让命令在后台运行而不退出?

4 个答案:

答案 0 :(得分:6)

您还没有解释为什么要在脚本退出后看到您的容器正在运行,或者您是否期望您的脚本退出。

一旦容器的CMD退出,docker容器就会退出。如果您希望容器继续运行,则需要一个可以继续运行的进程。一个选项就是在脚本末尾放置一个while循环:

while :; do
  sleep 300
done

您的脚本永远不会退出,因此您的容器将继续运行。如果您的容器承载网络服务(Web服务器,数据库服务器等),那么这通常是容器生命周期的运行过程。

如果您的脚本意外退出,您可能需要查看容器日志(docker logs <container>)并可能在脚本中添加一些调试。

如果您只是问“我如何在后台运行容器?”,那么Emil的回答(将-d标志传递给docker run)将帮助您解决问题。

答案 1 :(得分:4)

docker运行的进程取代了UNIX进程树中的initinit是最顶层的父进程,一旦退出docker容器就停止。任何子进程(现在都是orphan process)也将被停止。

$ docker pull busybox >/dev/null
$ time docker run --rm busybox sleep 3

real    0m3.852s
user    0m0.179s
sys 0m0.012s

所以你不能允许父pid退出,但你有两个选择。您可以保留父进程并允许它管理其子进程(例如,通过将其告知wait直到所有子进程都退出)

$ time docker run --rm busybox sh -c 'sleep 3 & wait'

real    0m3.916s
user    0m0.178s
sys 0m0.013s

...或者您可以使用exec将子进程替换为子进程。这意味着新命令正在父进程的空间中执行......

$ time docker run --rm busybox sh -c 'exec sleep 3'

real    0m3.886s
user    0m0.173s
sys 0m0.010s

后一种方法可能很复杂,具体取决于子进程的性质,但运行较少的不必要的进程更具有惯用的Docker。 (这并不是说你应该只有一个进程。)

答案 2 :(得分:3)

使用您的脚本在后台使用以下命令运行容器

docker run -i -t -d  image:tag /bin/sh /root/my_script.sh

通过docker ps命令

检查容器ID

然后验证您的脚本是否正在容器上执行

docker exec <id> /bin/sh -l -c "ps aux"

答案 3 :(得分:1)

使用docker-entrypoint.sh bash脚本包装程序,该脚本阻止容器进程并能够捕获ctrl-c。这个bash示例应该有所帮助: https://rimuhosting.com/knowledgebase/linux/misc/trapping-ctrl-c-in-bash

当Docker发送退出信号时,脚本应该干净地关闭进程。

您还可以在脚本中添加一个循环,重复检查正在运行的进程。