首页 > 解决方案 > 如何创建 Dockerfile 以便容器可以在不立即退出的情况下运行

问题描述

像 MySQL 这样的官方 Docker 镜像可以这样运行:

docker run -d --name mysql_test mysql/mysql-server:8.0.13

它可以在后台无限期地运行。

我想尝试创建一个执行相同操作的图像,特别是 Flask 开发服务器(仅用于测试)。但我的容器立即退出。我的 Dockerfile 是这样的:

FROM debian:buster
ENV TERM xterm
RUN XXXX # some apt-get and Python installation stuffs
ENTRYPOINT [ "flask", "run", "--host", "0.0.0.0:5000" ]
EXPOSE 80
EXPOSE 5000
USER myuser
WORKDIR /home/myuser

但是,它一运行就立即退出。我还尝试将“bash”作为入口点,以确保它不是 Flask 配置问题并且它也退出了。

如何使它在容器中作为进程运行?

编辑

好的有人在下面发布(但后来被删除),测试的命令是使用tail -f /dev/null,它确实无限期地运行。我仍然不明白为什么bash不能作为一个不存在的进程工作(是吗?)。但我的烧瓶配置可能已关闭。

编辑 2

我看到在没有 -d 标志的情况下运行会打印出标准输出(或标准错误),以便我可以诊断问题。

标签: dockerdockerfile

解决方案


让我们把事情弄清楚。

通常,一旦成功执行其入口点,容器就会退出。

在您的情况下,如果不是 python 专家,这ENTRYPOINT [ "flask", "run", "--host", "0.0.0.0:5000" ]足以让容器保持活力。但我猜你有一些配置错误,并且由于该错误,容器在运行flask命令之前退出了。您可以通过运行docker ps -a并检查退出代码(可能为 1)来验证这一点。

现在让我们讨论一下您编辑中的问题。

您误解的关键部分来自-d旗帜。

您认为设置bash为入口点足以使容器保持活动状态是正确的,您需要附加到该外壳。

当以分离模式(-d)运行时,容器将执行bash命令,但一旦没有人附加到该外壳,它将退出。此外,使用此标志会阻止您实时查看容器日志(但您可以使用docker logs container_id它来调试),这在您处于设置的早期阶段时非常有用。因此,我建议仅在您确定一切都按预期工作时才使用此标志。

要附加到 bash shell 并使容器保持活动状态,您应该使用该-it标志,以便将 bash shell 附加到调用docker run命令的当前 shell。

-t : 分配一个伪 tty

-i :即使没有附加,也保持 STDIN 打开

另请参阅有关前台与后台模式的官方文档。


推荐阅读