简体   繁体   English

是否可以在 Dockerfile 中使用 RUN 命令启动进程?

[英]Is it possible to start a process using RUN command in Dockerfile?

Currently I have a dockerfile that runs two executables using an ampersand:目前我有一个 dockerfile 使用&符号运行两个可执行文件:

FROM <Linux base image>
CMD ["bin/sh", "-c", "/service1 & /service2"]

As I am looking to migrate this dockerfile to distroless, I will no longer be able to run this ampersand command, since my new minimal image will no longer have a shell to recognize it.当我希望将此 dockerfile 迁移到无发行版时,我将不再能够运行此 & 符号命令,因为我的新最小映像将不再具有 shell 来识别它。 Thus I am looking for alternate ways to ensure I can run both services from the same image.因此,我正在寻找替代方法来确保我可以从同一个映像运行这两个服务。

As an alternative, I am experimenting with doing something like this:作为替代方案,我正在尝试做这样的事情:

FROM <minimal base image>
RUN /service1
CMD ["/service2"]

Is there any issue with executing /service1 using the RUN command?使用 RUN 命令执行 /service1 有什么问题吗? Is this even possible, given /service1 will be a process running on the container?这是否可能,因为 /service1 将是在容器上运行的进程?

Note: I am aware it is not usually recommended to run two services from the same container, but this is to help me better understand RUN and CMD commands.注意:我知道通常不建议从同一个容器运行两个服务,但这是为了帮助我更好地理解 RUN 和 CMD 命令。 I have read through Dockerfile reference but it is still unclear to me.我已通读Dockerfile 参考资料,但我仍不清楚。 I have also tested this out locally and the container fails to run, although I do not see logs to confirm this is the reason.我也在本地对此进行了测试,但容器无法运行,尽管我没有看到日志来确认这是原因。

The RUN instruction is executed at container build time and the result of the command is saved to the image that is built as a new layer. RUN指令在容器构建时执行,命令结果保存到作为新层构建的镜像中。 See the reference here RUN请参阅此处的参考RUN

The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. RUN 指令将在当前图像之上的新层中执行任何命令并提交结果。 The resulting committed image will be used for the next step in the Dockerfile.生成的提交图像将用于 Dockerfile 中的下一步。

I would recommend writing a single initialization script that starts your services for you.我建议编写一个初始化脚本来为您启动服务。 Since you cannot rely on any distro specific tooling you would need to execute the script with something that you installed earlier in your docker file.由于您不能依赖任何特定于发行版的工具,因此您需要使用之前在 docker 文件中安装的东西来执行脚本。

You cannot start background services with a RUN command.您不能使用RUN命令启动后台服务。 They are not persisted in the image, and are stopped as soon as the RUN command completes.它们不会保留在映像中,并且会在RUN命令完成后立即停止。

What you can do, though, is override the CMD when you run the container.但是,您可以在运行容器时覆盖CMD Rather than trying to run two processes in a single container, it's a better practice to run two separate containers with one process each.与其尝试在一个容器中运行两个进程,不如运行两个独立的容器,每个容器都有一个进程。

docker run -d your-image /service1
docker run -d your-image /service2
version: '3.8'
services:
  service1:
    build: .
    command: /service1
  service2:
    build: .
    command: /service2

Since this setup doesn't require a shell or any other sort of automation in a container, it will also work just fine with a FROM scratch or another kind of "distroless" image.由于此设置不需要 shell 或容器中的任何其他类型的自动化,因此它也可以与FROM scratch或其他类型的“无发行版”映像一起正常工作。

Fundamentally a container runs one process (which could launch subprocesses) and when that process completes the container exits.从根本上说,容器运行一个进程(可以启动子进程),当该进程完成时,容器退出。 If you want to run two processes in the same container then either one needs to launch the other, or you need some common parent process that can manage the two.如果您想在同一个容器中运行两个进程,那么其中一个需要启动另一个,或者您需要一些可以管理这两个进程的通用父进程。 That requires you to introduce at least a shell in most cases, which gets away from the spirit of these extremely minimal images.在大多数情况下,这要求您至少引入 shell,这与这些极简图像的精神背道而驰。

FYI:供参考:

  • Commands passed to RUN are executed only when you build the image by running docker build -t...仅当您通过运行docker build -t...构建映像时,才会执行传递给RUN的命令

  • Commands passed to CMD are executed only when you run a container from that image you built (not executed while building the image).传递给CMD的命令仅在您从您构建的镜像运行容器时执行(在构建镜像时不执行)。

See also也可以看看

PS: For your specific scenario (for experimental purposes probably) without splitting each executable to a dedicated container, you may also try to PS:对于您的特定场景(可能出于实验目的),无需将每个可执行文件拆分到专用容器,您也可以尝试

1- Research supervisord service which can run & manage multiple services/processes and implement it in your container. 1-研究可以运行和管理多个服务/进程并在您的容器中实现它的supervisord服务。

2- Call and run the second executable from the first one (if it is possible) as an alternative not recommended solution. 2-从第一个可执行文件(如果可能)调用并运行第二个可执行文件作为不推荐的替代解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM