【问题标题】:Automatically Start Services in Docker Container在 Docker 容器中自动启动服务
【发布时间】:2023-09-26 18:49:01
【问题描述】:

我正在用 docker 做一些初步测试。此刻我有我的图像,我可以运行一些容器:

docker ps

我做docker attach container_id 并启动 apache2 服务。

然后我从主控制台将容器提交到图像。

退出容器后,如果我尝试启动容器或尝试从提交的镜像运行一个新容器,服务总是停止。

如何在服务启动的情况下创建或重启一个容器,例如 apache?

【问题讨论】:

    标签: linux ubuntu docker linux-containers


    【解决方案1】:

    编辑: 自从最初发布这个答案以来,我已经学到了很多关于 Docker 的知识。 “在 Docker 容器中自动启动服务”对于 Docker 来说不是一个好的使用模式。相反,请使用 fleetKubernetes 甚至 Monit/SystemD/Upstart/Init.d/Cron 之类的东西来自动启动在 Docker 容器中执行的服务。

    原始答案: 如果您使用命令/bin/bash 启动容器,那么您可以按照此处概述的方式完成此操作:https://*.com/a/19872810/2971199

    所以,如果您使用docker run -i -t IMAGE /bin/bash 启动容器,并且如果您想在容器启动时自动启动 apache2,请在容器中编辑 /etc/bash.bashrc 并添加 /usr/local/apache2/bin/apachectl -f /usr/local/apache2/conf/httpd.conf(或任何您的 apache2 启动命令)到文件末尾的换行符。

    保存对图像的更改并使用docker run -i -t IMAGE /bin/bash 重新启动它,当您附加时您会发现 apache2 正在运行。

    【讨论】:

    • /etc/bash.bashrc 将在每次 bash 启动时执行,如果您以后想与容器交互(例如执行 docker exec -ti ID bash),这可能会导致问题......我认为这不是正确的地方为 apache2 等服务放置启动脚本
    • 同意彼得。自从我发布这个答案以来,我已经了解了 Docker,虽然它有效,但它根本不是我们在现实生活中实际使用 Docker 的方式。
    • 为什么不docker run -i -t IMAGE /usr/local/apache2/bin/apachectl -f /usr/local/apache2/conf/httpd.conf bash 是干什么用的?
    • vbence,您似乎没有阅读您上面的 cmets 和我对我的回答的编辑?是的,您提到的是一种更合适的方法,但是这个答案来自于我在了解更多有关容器化和流程初始化的信息之前,正如我的 EDIT 所展示的那样。这也是在 Docker 使用“docker exec ...”添加进程注入之前 - 所以当时我们几乎没有办法在没有运行 bash 的情况下与容器进行交互或故障排除。
    • 说“现在我们如何在现实生活中使用 Docker”似乎很愚蠢。使用 docker 来包装依赖关系是完全可以的,因为它会为构建或其他非生产的东西而旋转和丢弃。如果您以这种方式使用 docker,请不要难过。
    【解决方案2】:

    您可以使用的一个选项是使用诸如 Supervisord 之类的进程管理器来运行多个进程。有人用 sshd 和 mongodb 完成了这个:https://github.com/justone/docker-mongodb

    【讨论】:

      【解决方案3】:

      我猜你不能。您可以做的是使用 Dockerfile 创建一个映像并在其中定义一个 CMD,它将在容器启动时执行。请参阅构建器文档了解基础知识 (https://docs.docker.com/reference/builder/),并参阅 Run a service automatically in a docker container 了解有关保持服务运行的信息。

      您不需要使用 Dockerfile 自动执行此操作。您也可以像这样做一样通过手动提交来创建映像,然后在命令行运行它。然后,您提供它应该运行的命令(这正是 Dockerfile CMD 实际执行的操作)。您也可以通过这种方式覆盖 Dockerfiles CMD:仅执行最新的 CMD,如果您使用一个启动容器,这是命令行命令。文档中的基本docker run -i -t base /bin/bash 命令就是一个示例。如果您的命令变得太长,您当然可以创建一个方便的脚本。

      【讨论】:

        【解决方案4】:

        按照设计,以分离模式启动的容器会在用于运行容器的根进程退出时退出。 您需要在 FOREGROUND 模式下启动 Apache 服务。

        docker run -p 8080:80 -d ubuntu/apache apachectl -D FOREGROUND
        

        参考:https://docs.docker.com/engine/reference/run/#detached-vs-foreground

        【讨论】:

          【解决方案5】:

          尝试像这样将启动脚本添加到 dockerfile 中的入口点;

          ENTRYPOINT service apache2 restart && bash
          

          【讨论】: