我已经看过一堆教程似乎做了我想做的事情,但出于某种原因,我的Docker容器退出了.基本上,我在Docker容器中设置了一个Web服务器和几个守护进程.我通过一个名为bash的脚本完成了最后的部分run-all.sh,我在Dockerfile中运行CMD.run-all.sh看起来像这样:
service supervisor start
service nginx start
Run Code Online (Sandbox Code Playgroud)
我在Dockerfile中启动它,如下所示:
CMD ["sh", "/root/credentialize_and_run.sh"]
Run Code Online (Sandbox Code Playgroud)
我可以看到,当我手动运行时(即使用-i -t/bin/bash访问图像),服务都能正常启动,并且当我运行图像时,一切看起来都正常运行,但它会退出一次它完成了我的流程.我希望这些进程无限期地运行,据我所知,容器必须继续运行才能实现.然而,当我跑步时docker ps -a,我看到:
? docker_test docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7706edc4189 some_name/some_repo:blah "sh /root/run-all.sh 8 minutes ago Exited (0) 8 minutes ago grave_jones
Run Code Online (Sandbox Code Playgroud)
是什么赋予了?为什么要退出?我知道我可以在我的bash脚本末尾添加一个while循环来保持它,但是什么是阻止它退出的正确方法?
Sof*_*ets 117
如果您使用的是Dockerfile,请尝试:
ENTRYPOINT ["tail", "-f", "/dev/null"]
(显然这只是出于开发目的,你不应该让容器保持活着,除非它正在运行一个进程,例如.nginx ...)
arn*_*e.z 77
我遇到了同样的问题,我发现如果你使用-t和-d标志运行你的容器,它会继续运行.
docker run -td <image>
Run Code Online (Sandbox Code Playgroud)
这是标志的作用(根据docker run --help):
-d, --detach=false Run container in background and print container ID
-t, --tty=false Allocate a pseudo-TTY
Run Code Online (Sandbox Code Playgroud)
最重要的是-t国旗.-d只是让你在后台运行容器.
Tho*_*zco 44
这不是你应该如何设计你的Docker容器.
在设计Docker容器时,你应该构建它,使得只有一个进程在运行(即你应该有一个容器用于Nginx,一个用于supervisord或它正在运行的应用程序); 另外,该进程应该在前台运行.
当进程本身退出时,容器将"退出"(在您的情况下,该进程是您的bash脚本).
但是,如果您确实需要(或想要)在Docker容器中运行多个服务,请考虑从"Docker Base Image"开始,它将runit用作伪init进程(runit将在Nginx和Supervisor运行时保持在线状态),这将保持不变当你的其他进程做他们的事情时,在前台.
他们拥有大量的文档,因此您应该能够轻松地实现您想要做的事情.
pha*_*zei 41
它退出的原因是因为shell脚本首先作为PID 1运行,当它完成时,PID 1消失,而docker仅在PID 1运行时运行.
您可以使用主管来执行所有操作,如果使用"-n"标志运行,则告知不要守护进程,因此它将作为第一个进程保留:
CMD ["/usr/bin/supervisord", "-n"]
Run Code Online (Sandbox Code Playgroud)
还有你的supervisord.conf:
[supervisord]
nodaemon=true
[program:startup]
priority=1
command=/root/credentialize_and_run.sh
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
autorestart=false
startsecs=0
[program:nginx]
priority=10
command=nginx -g "daemon off;"
stdout_logfile=/var/log/supervisor/nginx.log
stderr_logfile=/var/log/supervisor/nginx.log
autorestart=true
Run Code Online (Sandbox Code Playgroud)
然后,您可以拥有任意数量的其他进程,如果需要,主管将处理它们的重新启动.
这样你就可以在需要nginx和php5-fpm的情况下使用supervisord,将它们分开是没有多大意义的.
Ser*_*nov 37
你可以运行plain cat而没有任何参数,如bro @ Sa'ad所提到的那样只是让容器工作[实际上什么都不做,只是等待用户输入](Jenkins的Docker插件做同样的事情)
its*_*ire 19
动机:
在docker 容器内运行多个进程并没有错。如果有人喜欢将 docker 用作轻量级 VM - 那就这样吧。其他人喜欢将他们的应用程序拆分为微服务。我想:一个容器中的 LAMP 堆栈?太棒了。
答案:
坚持一个良好的基础图像像PHUSION基本图像。可能还有其他人。请给出意见。
这只是对主管的又一次恳求。因为 phusion 基础映像除了提供 cron 和语言环境设置等其他内容之外,还提供主管。在运行这样一个轻量级的虚拟机时你喜欢设置的东西。值得一提的是,它还提供了到容器的 ssh 连接。
如果您发出以下基本的 docker run 语句,phusion 映像本身将启动并继续运行:
moin@stretchDEV:~$ docker run -d phusion/baseimage
521e8a12f6ff844fb142d0e2587ed33cdc82b70aa64cce07ed6c0226d857b367
moin@stretchDEV:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
521e8a12f6ff phusion/baseimage "/sbin/my_init" 12 seconds ago Up 11 seconds
Run Code Online (Sandbox Code Playgroud)
或者死简单:
如果基本映像不适合您...为了快速 CMD 使其保持运行,我会假设 bash 是这样的:
CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"
Run Code Online (Sandbox Code Playgroud)
或者这个对于busybox:
CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"
Run Code Online (Sandbox Code Playgroud)
这是很好的,因为它会立即退出上docker stop。
很简单,sleep或者cat在容器被docker 强行杀死之前需要几秒钟。
作为对 Charles Desbiens 关于在一个容器中运行多个进程的回应:
这是一个意见。并且文档指向这个方向。引用:“拥有多个进程是可以的,但要从 Docker 中获得最大收益,请避免一个容器负责整个应用程序的多个方面。” 可以肯定的是,将复杂的服务划分到多个容器中显然要强大得多。但在某些情况下,走一个集装箱路线可能是有益的。特别是对于电器。该GitLab泊坞窗图像是我最喜欢的多工艺容器的例子。它使这个复杂系统的部署变得容易。没有办法进行错误配置。GitLab 保留对其设备的所有控制权。双赢。
小智 15
从 docker engine v1.25 开始,有一个名为 的选项init。
Docker-compose从 开始包含此命令version 3.7。
所以我当前的 CMD 在运行容器时应该运行到无穷大:
CMD ["sleep", "infinity"]
Run Code Online (Sandbox Code Playgroud)
然后使用以下命令运行它:
docker build
docker run --rm --init app
Run Code Online (Sandbox Code Playgroud)
iTe*_*ech 12
确保你添加daemon off;nginx.conf或CMD ["nginx", "-g", "daemon off;"]按照官方的nginx图像运行它
然后使用以下命令将supervisor作为服务运行,将nginx作为前台进程运行,以防止容器退出
service supervisor start && nginx
在某些情况下,您需要在容器中有多个进程,因此强制容器只有一个进程将无法工作,并且可能会在部署中产生更多问题.
因此,您需要了解权衡并做出相应的决定.
小智 5
在变量(例如$ NGNIX_PID)和入口点文件末尾捕获ngnix进程的PID
wait $NGNIX_PID
Run Code Online (Sandbox Code Playgroud)
这样,你的容器应该运行直到ngnix存活,当ngnix停止时,容器也会停止
| 归档时间: |
|
| 查看次数: |
161534 次 |
| 最近记录: |