为什么Docker exec在退出时会终止nohup进程?

13

我正在运行一个只包含Bash脚本的Ubuntu Docker容器。我想使用docker exec在该容器内启动我的应用程序,如下所示:

docker exec -it 0b3fc9dd35f2 ./main.sh

在主脚本中,我想使用nohup运行另一个长时间运行的应用程序:

#!/bin/bash
nohup ./java.sh &
#with this strange sleep the script is working
#sleep 1
echo `date` finish main >> /status.log

java.sh脚本如下所示(为了简单起见,这是一个虚拟脚本):

#!/bin/bash
sleep 10
echo `date` finish java >> /status.log

问题在于 java.sh 在 docker exec 返回后立即被杀死。问题是为什么?

我找到的唯一解决方法是,在第一个脚本中添加一些虚假的 sleep 1,在 nohup 启动后。然后第二个进程就能正常运行了。你有什么想法吗?为什么会这样?

[编辑]

第二种解决方法是在 java.sh 脚本中,在睡眠之前添加一些 echotrap 命令。然后它可以正常工作。不幸的是,我不能使用这个解决方法,因为我有一个 Java 进程,而不是这个脚本。


你不应该使用 docker exec 来启动一个容器,而是应该使用 docker run 命令,并且需要仔细查看 Dockerfile 中的 CMDENTRYPOINT 指令。 - user2915097
我已经有一个正在运行的容器,其中包含不同的进程。使用docker exec命令,我想要启动第二个进程。这是持续集成方案,因此我们希望在一个容器中拥有更多的进程。 - Marek Smigielski
3个回答

15

这不是一个答案,但我仍然没有足够的声望来评论。

我不知道为什么nohup不起作用。但是我采用了你的想法找到了一个可行的解决方法:

docker exec -ti running_container bash -c 'nohup ./main.sh &> output & sleep 1'

9

好的,让我们结合上面两个答案:D

首先,rcmgleite说得很对:使用

-d

选项将进程作为“分离”后台运行。

其次(最重要的是!),如果您运行了分离进程,则不需要nohup

deploy_app.sh

#!/bin/bash
cd /opt/git/app
git pull
python3 setup.py install
python3 -u webui.py >> nohup.out

在容器内执行此操作。
docker exec -itd container_name bash -c "/opt/scripts/deploy_app.sh"

检查它

$ docker attach container_name
$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  11768  1940 pts/0    Ss   Aug31   0:00 /bin/bash
root       887  0.4  0.0  11632  1396 pts/1    Ss+  02:47   0:00 /bin/bash /opt/scripts/deploy_app
root       932 31.6  0.4 235288 32332 pts/1    Sl+  02:47   0:00 python3 -u webui.py

1
你为什么需要“交互式 talktoyou”(即 -it)? - santiago arizti

6

我知道这是一个晚回复,但出于文档记录的目的,我会在此添加。

在bash上使用nohup并在docker容器上使用'exec'运行时,您应该使用:

$ docker exec -d 0b3fc9dd35f2 /bin/bash -c "./main.sh"

-d选项的含义是:

-d, --detach 分离模式:在后台运行命令

有关docker exec的更多信息,请参见: https://docs.docker.com/engine/reference/commandline/exec/

这样就可以解决问题了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接