使用docker run命令时,Docker容器会退出(0),但使用docker start命令可以正常运行。

4
我正在尝试将GUI应用程序制作成Docker镜像,并已经取得了一些成功。如果我将Dockerfile构建成一个镜像,然后执行docker run --name testcontainer testimage命令,它会开始处理,但会突然停止。然后我检查docker ps来确认没有容器在运行。然后我检查docker ps -a,并可以看到它以状态码exit(0)退出。然后,如果我运行命令docker start testcontainer,它似乎会再次启动ENTRYPOINT命令,这次它能够继续进行,GUI就会弹出。
我的最佳猜测是,当我运行docker run命令时,该进程会开始运行,但可能被派生为后台进程,导致容器退出,因为前台进程已经结束。虽然这可能完全不准确,因为你会认为docker start命令会产生相同的结果。我考虑尝试强制该进程保持在前台,但不知道如何实现。有什么建议吗?
更新:我编辑了我的Dockerfile,使用supervisord管理GUI应用程序的启动。现在,我的docker run命令将启动supervisor,supervisor再启动我的GUI应用程序,它可以工作。关于这个问题需要注意的一些事情是,supervisor显示:
INFO spawned: myguiapp with pid 7
INFO success: myguiapp entered RUNNING state
INFO: exited: myguiapp (exit status 0; expected)
此时,Supervisor和容器仍在运行,这似乎表明主进程启动了一个子进程。由于supervisor仍在运行,我的容器保持运行状态,并且GUI应用程序确实出现了并且我也能够使用它。当我关闭GUI时,supervisor报告:
CRIT reaped unknown pid 93
Supervisor仍在运行,导致容器不会关闭。因此,我必须CTRL-C来杀死supervisor。我不想使用supervisor,但如果必须使用,我希望supervisor在该子进程结束时优雅地关闭自身。如果我能够找到方法让我的容器或supervisor跟踪主进程的子进程,那么我认为这个问题将得到解决。

你的Dockerfile和启动命令是什么样子的?如果你的启动命令退出,那么你的容器也会退出。因此,在前台启动进程似乎是一个好主意。 - christian
抱歉,我不明白你的意思。在运行命令退出后,我的Docker启动命令可以正常工作。我的ENTRYPOINT命令只是用于GUI应用程序可容器化的CLI路径。 - codenaugh
1个回答

2

第一个问题可能是因为您的应用程序需要一个tty,而您没有分配伪tty。尝试以这种方式运行容器:

docker run -t --name testcontainer testimage

当您第二次执行docker start时,它会分配虚拟tty,并使进程保持运行状态。我亲自尝试过。然而,在Docker文档中找不到此信息。

此外,如果您的用户界面是交互式的,则需要:

docker run -t -i --name testcontainer testimage

1
我还会为 GUI 应用程序添加 `-i' 选项,使其变成交互模式。 - user2915097
GUI是交互式的,但似乎不需要-i。话虽如此,我已经尝试了-it以及每个标志,但结果没有任何变化。 - codenaugh
@CommanderCody,你能发一下你的 Dockerfile 吗?还有你使用的 GUI 应用是什么类型的?用的是哪种编程语言?用了哪个库? - Rico
我不能提供安装文件,因为您无法访问它们(这是一个工作项目)。只需知道它是一个基于Java的大型应用程序。 - codenaugh

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