在容器中运行多个进程

容器的主要运行进程是位于 结束 .最佳做法是通过以下方式分隔关注区域 每个容器使用一项服务。该服务可能会分叉为多个 进程(例如,Apache Web 服务器启动多个工作进程)。 拥有多个进程是可以的,但要从 Docker 中获得最大好处, 避免一个容器负责整体的多个方面 应用。您可以使用用户定义的网络连接多个容器,并且 共享卷。ENTRYPOINTCMDDockerfile

容器的主进程负责管理它 开始。在某些情况下,主进程设计不善,无法处理 当容器退出时,“收割”(停止)子进程。如果 您的流程属于此类别,您可以在以下情况下使用该选项 运行容器。该标志将一个小的 init-process 插入到 container 作为主进程,并在 容器退出。以这种方式处理此类进程优于使用 成熟的 init 进程,例如 OR 处理进程 生命周期。--init--initsysvinitsystemd

如果您需要在一个容器中运行多个服务,您可以实现 这有几种不同的方式。

使用包装脚本

将所有命令放在一个包装脚本中,包括 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

使用进程管理器

使用类似 的进程管理器。这比其他的更复杂 选项,因为它需要您将 您的镜像(或基于包含的镜像)以及 它管理的不同应用程序。然后你开始 ,它 为您管理您的流程。supervisordsupervisordsupervisordsupervisord

以下 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"]

如果要确保两个进程都将其 和 输出到 容器日志中,您可以将以下内容添加到文件中:stdoutstderrsupervisord.conf

[supervisord]
nodaemon=true
logfile=/dev/null
logfile_maxbytes=0

[program:app]
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true