执行代码后停止Docker容器

6
为了更深入地了解Docker,我创建了一个Dockerfile来执行Python脚本。虽然它可以正常运行,但是在脚本执行完后容器会崩溃。那么我该如何修改我的Dockerfile,以便在脚本执行完成后销毁容器,而不是让容器一直崩溃和重新启动?
Dockerfile内容:
FROM python:3

ADD aa.py /

CMD [ "python", "./aa.py" ]

Python:

print('Hello!')

错误消息:

2017-06-14 11:37:09 [CELL/0] OUT Starting health monitoring of container
2017-06-14 11:37:09 [APP/PROC/WEB/0] OUT Hello!
2017-06-14 11:37:09 [APP/PROC/WEB/0] OUT Exit status 0
2017-06-14 11:37:09 [CELL/0] OUT Exit status 143
2017-06-14 11:37:09 [CELL/0] OUT Destroying container
2017-06-14 11:37:09 [API/0] OUT Process has crashed with type: "web"
2017-06-14 11:37:09 [API/0] OUT App instance exited with guid 6fdede46-6751-4725-ad78-b76262dbe701 payload: {"instance"=>"", "index"=>0, "reason"=>"CRASHED", "exit_description"=>"2 error(s) occurred:\n\n* 2 error(s) occurred:\n\n* Codependent step exited\n* cancelled\n* cancelled", "crash_count"=>4, "crash_timestamp"=>1497433029411246770, "version"=>"98e2a035-e38f-4169-95fb-2701c8486e9c"}
2017-06-14 11:37:09 [CELL/0] OUT Successfully destroyed container
2017-06-14 11:38:31 [CELL/0] OUT Creating container

你是如何启动容器的?你可以使用docker run --rm mypython命令,该命令将在执行脚本后删除你的容器。 - lvthillo
我在CloudFoundry上使用Docker。通过用户界面,我输入了一个Docker Hub仓库并启动了它。 - jz22
我从未使用过CloudFoundry,所以无法帮助您解决这个问题。我猜测它会尝试重新启动,因为在Docker中,该容器将运行、显示消息并停止。--rm选项将在运行后删除容器。我无法帮助您在CloudFoundry中重现此问题。 - lvthillo
1个回答

3
注意:默认python:3CMDpython3退出码143表示SIGTERM,如此处所述。这是Docker发送的内容。
因此,您需要为您的Python3应用程序优雅地处理SIGTERM信号
不要忘记,一旦您的Python应用程序完成并退出主函数,容器将自动停止和退出。

该用户评论中添加:

与此同时,我发现在Docker环境下处理SIGTERM完全没有问题。

然而,在CloudFoundry上使用相同的代码无法防止容器崩溃。
在CloudFoundry中,您需要一个始终运行而不是像脚本一样执行任务然后停止的应用程序。
即使没有错误地停止也会被检测为在CloudFoundry中崩溃。

我通过使用flask框架将我的脚本转换为REST服务器。现在它始终在运行,但只有在通过其URL调用时才执行其任务。


谢谢。信号是什么时候发送的?脚本执行后吗? - jz22
我尝试了这些解决方案,但在处理SIGTERM后它又崩溃了。 - jz22
@user3080315 没错,这就是为什么我关注你的另一个问题,它解决了这个问题:https://stackoverflow.com/questions/44567981/how-to-properly-handle-sigint-signal-in-python - VonC
与此同时,我已经发现在Docker环境中处理SIGTERM非常完美。然而,在CloudFoundry上使用相同的代码并不能防止容器崩溃。在CloudFoundry中,您需要一个始终运行而不仅仅是执行任务然后停止的应用程序,就像脚本一样。即使没有错误地停止也会被检测为在CloudFoundry中崩溃。我通过使用flask框架将我的脚本转换成了REST服务器。现在它始终在运行,但只有在通过其URL调用时才执行其任务。 - jz22
@user3080315 很好的发现!我已经将您的评论包含在答案中,以增加可见性。 - VonC
显示剩余6条评论

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