在容器中运行多个进程
容器的主要运行进程是ENTRYPOINT
和/或CMD
在
结束Dockerfile
.最佳做法是通过以下方式分隔关注区域
每个容器使用一项服务。该服务可能会分叉为多个
进程(例如,Apache Web 服务器启动多个工作进程)。
拥有多个进程是可以的,但要从 Docker 中获得最大好处,
避免一个容器负责整体的多个方面
应用。您可以使用用户定义的网络连接多个容器,并且
共享卷。
容器的主进程负责管理它
开始。在某些情况下,主进程设计不善,无法处理
当容器退出时,“收割”(停止)子进程。如果
您的流程属于此类别,您可以使用--init
选项时
运行容器。这--init
flag 将一个小的 init-process 插入到
container 作为主进程,并在
容器退出。以这种方式处理此类进程优于使用
成熟的 init 进程,例如sysvinit
或systemd
处理流程
生命周期。
如果您需要在一个容器中运行多个服务,您可以实现 这有几种不同的方式。
使用包装脚本
将所有命令放在一个包装脚本中,包括 testing 和
调试信息。以CMD
.下面是一个
天真的例子。首先,包装脚本:
#!/bin/bash
# Start the first process
./my_first_process &
# Start the second process
./my_second_process &
# Wait for any process to exit
wait -n
# Exit with status of process that exited first
exit $?
接下来,Dockerfile:
# syntax=docker/dockerfile:1
FROM ubuntu:latest
COPY my_first_process my_first_process
COPY my_second_process my_second_process
COPY my_wrapper_script.sh my_wrapper_script.sh
CMD ./my_wrapper_script.sh
使用 Bash 作业控件
如果您有一个主进程需要先启动并保持运行,但您 临时需要运行一些其他进程(也许是为了与主 进程),则可以使用 Bash 的作业控制。首先,包装脚本:
#!/bin/bash
# turn on bash's job control
set -m
# Start the primary process and put it in the background
./my_main_process &
# Start the helper process
./my_helper_process
# the my_helper_process might need to know how to wait on the
# primary process to start before it does its work and returns
# now we bring the primary process back into the foreground
# and leave it there
fg %1
# syntax=docker/dockerfile:1
FROM ubuntu:latest
COPY my_main_process my_main_process
COPY my_helper_process my_helper_process
COPY my_wrapper_script.sh my_wrapper_script.sh
CMD ./my_wrapper_script.sh
使用进程管理器
使用流程管理器,例如supervisord
.这比其他的更复杂
选项,因为它需要您将supervisord
及其配置转换为
您的镜像(或基于包含supervisord
) 以及
它管理的不同应用程序。然后你开始supervisord
哪
为您管理您的流程。
以下 Dockerfile 示例显示了此方法。该示例假定 这些文件位于 Build Context 的根目录中:
supervisord.conf
my_first_process
my_second_process
# syntax=docker/dockerfile:1
FROM ubuntu:latest
RUN apt-get update && apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY my_first_process my_first_process
COPY my_second_process my_second_process
CMD ["/usr/bin/supervisord"]
如果要确保两个进程都输出其stdout
和stderr
自
容器日志中,您可以将以下内容添加到supervisord.conf
文件:
[supervisord]
nodaemon=true
logfile=/dev/null
logfile_maxbytes=0
[program:app]
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true