【问题标题】:docker run a shell script in the background without exiting the containerdocker在后台运行一个shell脚本而不退出容器
【发布时间】:2015-07-22 17:37:04
【问题描述】:

我正在尝试在我的 docker 容器中运行一个 shell 脚本。问题是 shell 脚本产生了另一个进程,它应该继续运行,除非另一个关闭脚本用于终止由启动脚本产生的进程。

当我运行以下命令时,

docker run image:tag /bin/sh /root/my_script.sh

然后,

docker ps -a

我看到命令已经退出。但这不是我想要的。我的问题是如何让命令在后台运行而不退出?

【问题讨论】:

    标签: linux docker


    【解决方案1】:

    您还没有解释为什么要在脚本退出后看到容器运行,或者您是否期望脚本退出。

    一旦容器的CMD 退出,docker 容器就会退出。如果您希望您的容器继续运行,您将需要一个可以继续运行的进程。一种选择是在脚本末尾放置一个 while 循环:

    while :; do
      sleep 300
    done
    

    您的脚本将永远不会退出,因此您的容器将继续运行。如果您的容器托管网络服务(Web 服务器、数据库服务器等),那么这通常是容器生命周期内运行的进程。

    如果您的脚本意外退出,您可能需要查看容器日志 (docker logs <container>),并可能在脚本中添加一些调试。

    如果您只是问“我如何在后台运行容器?”,那么 Emil 的回答(将 -d 标志传递给 docker run)将帮助您。

    【讨论】:

      【解决方案2】:

      docker 运行的进程取代了 UNIX 进程树中的initinit 是最顶层的父进程,一旦它退出,docker 容器就会停止。任何子进程(现在是orphan process)也将停止。

      $ docker pull busybox >/dev/null
      $ time docker run --rm busybox sleep 3
      
      real    0m3.852s
      user    0m0.179s
      sys 0m0.012s
      

      所以你不能让父 pid 退出,但你有两个选择。您可以保留父进程并允许它管理其子进程(例如,通过告诉它wait 直到所有子进程都退出)

      $ time docker run --rm busybox sh -c 'sleep 3 & wait'
      
      real    0m3.916s
      user    0m0.178s
      sys 0m0.013s
      

      ...或者您可以使用exec 将父进程替换为子进程。这意味着新命令正在父进程的空间中执行……

      $ time docker run --rm busybox sh -c 'exec sleep 3'
      
      real    0m3.886s
      user    0m0.173s
      sys 0m0.010s
      

      后一种方法可能很复杂,具体取决于子进程的性质,但运行较少的不必要进程更符合 Docker 的习惯。 (这并不是说您应该只拥有 一个 进程。)

      【讨论】:

        【解决方案3】:

        使用以下命令在后台使用脚本运行容器

        docker run -i -t -d  image:tag /bin/sh /root/my_script.sh
        

        通过docker ps命令查看容器id

        然后验证您的脚本是否在容器上执行

        docker exec <id> /bin/sh -l -c "ps aux"
        

        【讨论】:

          【解决方案4】:

          使用 docker-entrypoint.sh bash 脚本包装程序,该脚本会阻止容器进程并能够捕获 ctrl-c。这个 bash 示例应该会有所帮助: https://rimuhosting.com/knowledgebase/linux/misc/trapping-ctrl-c-in-bash

          当 Docker 发送退出信号时,脚本应该干净地关闭进程。

          您还可以在脚本中添加一个循环来重复检查正在运行的进程。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-10-20
            • 2019-09-26
            • 2020-11-19
            • 2012-01-06
            • 2013-09-07
            • 1970-01-01
            • 2015-10-13
            相关资源
            最近更新 更多