Dockerfile CMD指令将在运行后立即退出容器

时间:2017-02-14 06:02:29

标签: bash shell docker sh dockerfile

我想在容器启动时设置一些配置,为此我使用的是shell脚本。但是我的容器会在脚本结束后立即退出,我尝试使用-d标志/分离模式,但它永远不会以分离模式运行。

下面是我的Dockerfile

FROM ubuntu:14.04

ADD shell.sh /usr/local/bin/shell.sh

RUN chmod 777 /usr/local/bin/shell.sh

CMD /usr/local/bin/shell.sh

以下是我的shell脚本

#!/bin/bash
echo Hello-docker
  1. 不带任何标志运行

    docker run hello-docker
    

    这将在我的控制台上打印“Hello-docker”并退出

  2. 使用-itd标志运行

    docker run -itd hello-docker
    

    并且在我的控制台输出下面,这次也将很快退出。的:( enter image description here

    • 我看到的差异在COMMAND部分,当我运行其他图像命令部分将显示“/ bin / bash”并将继续处于分离模式。

    • 当我在带有shell脚本的容器中运行我的图像时,COMMAND部分将显示“/ bin / sh -c / usr / loca”,然后退出。

    • 我想运行容器,直到我不能手动停止。

  3.   

    编辑:

    在Dockerfile中添加ENTRYPOINT指令后,这将不会执行我的shell脚本:(

    FROM ubuntu:14.04
    
    ADD shell.sh /usr/local/bin/shell.sh
    
    RUN chmod 777 /usr/local/bin/shell.sh
    
    CMD /usr/local/bin/shell.sh
    
    ENTRYPOINT /bin/bash
    
      

    根据码头文档here

    在使用其他参数运行容器时将覆盖CMD,因此如果我使用如下所示的某些参数运行docker image,则不会执行CMD指令。 :(

    sudo docker run -it --entrypoint=/bin/bash <imagename>
    

6 个答案:

答案 0 :(得分:14)

只要Dockerfile中的CMD占用,就会运行一个docker容器。

在您的情况下,CMD由包含单个回显的shell脚本组成。因此容器将在完成回声后退出。

您可以覆盖CMD,例如:

sudo docker run -it --entrypoint=/bin/bash <imagename>

这将在容器中启动交互式shell,而不是执行CMD。退出该shell后,您的容器将立即退出。

如果您希望容器保持活动状态,则必须确保CMD继续运行。例如,通过将行while true; do sleep 1; done添加到shell.sh文件中,您的容器将打印您的hello消息,然后在您停止它之前不再执行任何操作(在另一个终端中使用docker stop)。

您可以使用docker exec -it <containername> bash在正在运行的容器中打开shell。如果您随后执行命令ps ax,它将显示您的shell.sh仍在容器内运行。

答案 1 :(得分:12)

最后通过一些实验,我得到了最好的结果,如下所示

我的Dockerfile没有任何问题,因为它正确无误。

FROM ubuntu:14.04

ADD shell.sh /usr/local/bin/shell.sh

RUN chmod 777 /usr/local/bin/shell.sh

CMD /usr/local/bin/shell.sh

我做的是获得预期的结果,我只是在我的shell脚本文件中添加一个命令(/ bin / bash),如下所示,并且一切都以我最好的方式工作。

#!/bin/bash

echo “Hello-docker” > /usr/hello.txt

/bin/bash

答案 2 :(得分:11)

您也可以修改第一个Dockerfile,替换

CMD /usr/local/bin/shell.sh

通过

CMD /usr/local/bin/shell.sh ; sleep infinity

这样,您的脚本不会终止,并且您的容器仍在运行。

答案 3 :(得分:1)

CMD bash -C '/path/to/start.sh';'bash'

答案 4 :(得分:1)

试试

CMD /bin/bash -c 'MY_COMMAND_OR_SHELL_SCRIPT; /bin/bash'

尝试在此处解释@lanni654321 的答案。 sh shell 在 Dockerfile 中是标准的。您必须调用 bash shell 以使用 bash 启动 .bashrc,许多命令也需要 RUN /bin/bash -c '...',与上面的 CMD 中的方式相同,因为 {{1}壳通常是不够的。如果您在 sh 的末尾添加“bash”,容器将不会退出,因为提交的图像仍然处于打开状态。

请参阅 https://cloud.google.com/scheduler/docs/quickstart 以了解由 CMD 引起并由 sh 解决的错误。

我认为您通常不需要这个。您可以只使用 bash,在我的情况下,这可以在您进入 RUN /bin/bash -c '...' 中的各种细节以启动容器之前,执行可以在基本映像中完成的任何操作。

但是如果您只需要运行一个容器而不退出,那么这一切都不是必需的。只是

docker-compose

然后

docker run -dit --name MY_CONTAINER MY_IMAGE:latest

你应该在容器的bash中,它不应该退出。

或者如果退出发生在 docker exec -it MY_CONTAINER /bin/bash 期间,使用

docker-compose

答案 5 :(得分:0)

在您的开始shell处添加一行代码: tail -f /dev/null/bin/bash 确保您已完成外壳程序并挂起系统中的进程,以使Docker容器不会关闭。别忘了授予“ chmod + x”访问start.sh的权限。 有演示:

#!/bin/bash
cp /root/supervisor/${RUN_SERVICE}.ini /etc/supervisor/conf.d/
sleep 1
service supervisor start
/bin/bash