【问题标题】:How to check if the docker engine and a docker container are running?如何检查 docker 引擎和 docker 容器是否正在运行?
【发布时间】:2017-09-29 00:15:24
【问题描述】:

在脚本中,我需要检查:

a) docker 引擎是否正在运行?
b) 给定一个容器名称,该 docker 容器是否正在运行?

[这个问题的最初措辞含糊不清,有些人将其解释为“检查 docker 引擎”,而另一些人将其解释为“检查 docker 容器”]

【问题讨论】:

  • 任何 docker 命令(docker -v 除外),例如 docker ps
  • docker attach containerName
  • 或试试docker ps
  • sudo systemctl status docker
  • docker ps ----- 这个命令只会显示正在运行的容器

标签: bash docker


【解决方案1】:

检查 .State.Status、.State.Running 等会告诉您它是否正在运行,但最好确保容器的 health。下面是一个您可以运行的脚本,它将确保两个容器在第二个容器中执行命令之前运行良好。如果已达到等待时间/尝试次数阈值,它会打印出 docker 日志。

示例取自npm sql-mdb

#!/bin/bash
# Wait for two docker healthchecks to be in a "healthy" state before executing a "docker exec -it $2 bash $3"
##############################################################################################################################
# $1 Docker container name that will wait for a "healthy" healthcheck (required)
# $2 Docker container name that will wait for a "healthy" healthcheck and will be used to run the execution command (required)
# $3 The actual execution command that will be ran (required). When "npm_deploy", all tokens will be included in execution of
#     "npm run jsdoc-deploy" and "npm publish"
attempt=0
health1=checking
health2=checking
while [ $attempt -le 79 ]; do
  attempt=$(( $attempt + 1 ))
  echo "Waiting for docker healthcheck on services $1 ($health1) and $2 ($health2): attempt: $attempt..."
  if [[ health1 != "healthy" ]]; then
    health1=$(docker inspect -f {{.State.Health.Status}} $1)
  fi
  if [[ $health2 != "healthy" ]]; then
    health2=$(docker inspect -f {{.State.Health.Status}} $2)
  fi
  if [[ $health1 == "healthy" && $health2 == "healthy"  ]]; then
    echo "Docker healthcheck on services $1 ($health1) and $2 ($health2) - executing: $3"
    docker exec -it $2 bash -c "$3"
    [[ $? != 0 ]] && { echo "Failed to execute \"$3\" in docker container \"$2\"" >&2; exit 1; }
    break
  fi
  sleep 2
done
if [[ $health1 != "healthy" || $health2 != "healthy"  ]]; then
  echo "Failed to wait for docker healthcheck on services $1 ($health1) and $2 ($health2) after $attempt attempts"
  docker logs --details $1
  docker logs --details $2
  exit 1
fi

【讨论】:

    【解决方案2】:

    我最终使用了

    docker info
    

    使用 bash 脚本检查 docker 引擎是否正在运行。

    编辑:如果 docker 没有运行,它可以用来使你的脚本失败,如下所示:

    #!/usr/bin/env bash
    if ! docker info > /dev/null 2>&1; then
      echo "This script uses docker, and it isn't running - please start docker and try again!"
      exit 1
    fi
    

    【讨论】:

    • 这个答案被低估了。它是跨平台的,可以快速通过/失败。
    • docker info > /dev/null 2>&1 如果你不需要输出
    【解决方案3】:

    我有一个更充实的例子,在 Gitea 容器的上下文中使用上面的一些工作,但它可以很容易地根据名称转换为另一个容器。此外,您还可以使用docker ps --filter 功能在较新的系统或未使用 docker-compose 的系统中设置 $GITEA_CONTAINER。

    # Set to name or ID of the container to be watched.
    GITEA_CONTAINER=$(./bin/docker-compose ps |grep git|cut -f1 -d' ')
    
    # Set timeout to the number of seconds you are willing to wait.
    timeout=500; counter=0
    # This first echo is important for keeping the output clean and not overwriting the previous line of output.
    echo "Waiting for $GITEA_CONTAINER to be ready (${counter}/${timeout})"
    #This says that until docker inspect reports the container is in a running state, keep looping.
    until [[ $(docker inspect --format '{{json .State.Running}}' $GITEA_CONTAINER) == true ]]; do
    
      # If we've reached the timeout period, report that and exit to prevent running an infinite loop.
      if [[ $timeout -lt $counter ]]; then
        echo "ERROR: Timed out waiting for $GITEA_CONTAINER to come up."
        exit 1
      fi
    
      # Every 5 seconds update the status
      if (( $counter % 5 == 0 )); then
        echo -e "\e[1A\e[KWaiting for $GITEA_CONTAINER to be ready (${counter}/${timeout})"
      fi
    
      # Wait a second and increment the counter
      sleep 1s
      ((counter++))
    
    done
    

    【讨论】:

      【解决方案4】:

      容器状态:真/假

      # docker inspect --format '{{json .State.Running}}' container-name
      true
      #
      

      【讨论】:

      • 请在您的答案中添加一些解释,以便其他人可以从中学习
      • 对于其他关注此内容的人,如果您正在寻找容器的健康检查,这很好。如果它正在工作,它将返回 true
      • 这似乎不再起作用了。 “状态”不是 JSOn 中返回的键之一。也没有看到任何关于跑步或健康的信息。但它已经启动,我收到了 JSON 响应。
      • 完美运行
      【解决方案5】:

      有关第一个问题的答案,请参阅此答案 - https://stackoverflow.com/a/65447848/4691279

      对于您的第二个问题 - 您可以使用 docker ps --filter "name=<<<YOUR_CONTAINER_NAME>>>" 之类的命令来检查特定容器是否正在运行。

      • 如果 Docker 和 Container 都在运行,那么您将得到如下输出:

        $ docker ps --filter "name=nostalgic_stallman"
        
        CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES       
        9b6247364a03        busybox             "top"               2 minutes ago       Up 2 minutes                            nostalgic_stallman
        
      • 如果 Docker 未运行,那么您将收到一条错误消息,指出 docker daemon 未运行。

      • 如果 Docker 正在运行但 Container 没有运行,那么您将不会在此命令的输出中获得容器名称。

      【讨论】:

        【解决方案6】:

        在终端中运行这个命令:

        docker ps
        

        如果 docker 没有运行,您将收到以下消息:

        来自守护进程的错误响应:拨打 unix docker.raw.sock:连接:连接被拒绝

        【讨论】:

          【解决方案7】:

          有时您不知道完整的容器名称,在这种情况下,这对我有用:

          if docker ps | grep -q keyword
          then 
              echo "Running!"
          else
              echo "Not running!"
              exit 1
          fi
          

          我们列出所有正在运行的容器进程(docker ps -a 会显示我们也没有运行的容器进程,但这不是我需要的),我们搜索一个特定的词(grep 部分),如果我们没有找到就会失败至少一个运行中的容器,其名称包含我们的关键字。

          【讨论】:

          【解决方案8】:

          对于 OS X 用户 (Mojave 10.14.3)

          这是我在 Bash 脚本中用来测试 Docker 是否正在运行的内容

          # Check if docker is running
          if ! docker info >/dev/null 2>&1; then
              echo "Docker does not seem to be running, run it first and retry"
              exit 1
          fi
          

          【讨论】:

          【解决方案9】:

          docker ps -a

          你可以看到所有的 docker 容器,不管它是活的还是死的。

          【讨论】:

            【解决方案10】:

            我如何签入 SSH.Run:

            systemctl
            

            如果响应:获取 D-Bus 连接失败:不允许操作

            它是一个 docker 或 WSL 容器。

            【讨论】:

              【解决方案11】:

              如果你正在寻找一个特定的容器,你可以运行:

              if [ "$( docker container inspect -f '{{.State.Running}}' $container_name )" == "true" ]; then ...
              

              为了避免容器处于崩溃循环并不断重启以显示它已启动,可以通过检查Status 字段来改进上述内容:

              if [ "$( docker container inspect -f '{{.State.Status}}' $container_name )" == "running" ]; then ...
              

              如果你想知道 dockerd 是否在本地机器上运行并且你已经安装了 systemd,你可以运行:

              systemctl show --property ActiveState docker
              

              您也可以使用docker infodocker version 连接到docker,如果守护程序不可用,它们会出错。

              【讨论】:

              • 如何将docker inspect … 放入bash 脚本的if 语句中?
              • if [ $(docker inspect -f '{{.State.Running}}' $container_name) = "true" ]; then echo yup; else echo nope; fi
              • 我使用docker inspect -f '{{.State.Restarting}}' $container_name,因为我使用重启策略启动我的容器,但这里“true”是你想要避免的。
              • 当容器没有运行时,bash 和 docker 都会抱怨上面的if 语句。这隐藏了错误情况下不需要的溢出:if [ "$(docker inspect -f '{{.State.Running}}' ${container_name} 2>/dev/null)" = "true" ]; then echo yup; else echo nope; fi
              • @MarcoLackovic 听起来你错过了上面的“你已经安装了 systemd”部分。
              【解决方案12】:

              列出所有容器:

              docker container ls -a

              ls = 列表
              -a = 全部

              检查“状态”列

              【讨论】:

              • 这就是我所需要的,因为它适用于所有平台!!
              • 简单易行......工作成功。
              【解决方案13】:

              在 Mac 上,您可能会看到该图像:

              如果您右键单击泊坞窗图标,您会看到:

              或者:

              docker ps

              docker run hello-world

              【讨论】:

                【解决方案14】:

                运行:

                docker version
                

                如果 docker 正在运行,您将看到:

                Client: Docker Engine - Community
                 Version:           ...
                 [omitted]
                
                Server: Docker Engine - Community
                 Engine:
                  Version:          ...
                 [omitted]
                

                如果 docker 没有运行,你会看到:

                Client: Docker Engine - Community
                 Version:           ...
                 [omitted]
                
                Error response from daemon: Bad response from Docker engine
                

                【讨论】:

                • 对于 Windows 用户,如果引擎未运行,您可能还会看到如下错误:连接时出错:Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1 .35/info: 打开 //./pipe/docker_engine
                【解决方案15】:

                如果基本目标是“如何在 Docker 启动时启动容器?”

                我们可以使用Docker的restart policy

                向现有容器添加重启策略:

                Docker: Add a restart policy to a container that was already created

                例子:

                docker update --restart=always <container>
                

                【讨论】:

                  【解决方案16】:

                  您可以使用以下方式检查 docker 状态:systemctl is-active docker

                  ➜  ~  systemctl is-active docker
                  active
                  

                  您可以将其用作:

                  ➜  ~  if [ "$(systemctl is-active docker)" = "active" ]; then echo "is alive :)" ; fi
                  is alive :)
                  
                  ➜  ~  sudo systemctl stop docker
                  
                  ➜  ~  if [ "$(systemctl is-active docker)" = "active" ]; then echo "is alive :)" ; fi
                   * empty response *
                  

                  【讨论】:

                  • 这不回答问题。 "检查容器名称"
                  • 是的,问题似乎不明确,要检查容器是否正在运行,您应该使用docker ps --filter name=pattern,然后您可以格式化输出以仅检查添加此标志的状态:--format {{.Status}}
                  • 这会告诉你 systemctl thinks docker 是否正在运行,但它不会真正检查 docker 是否真的在运行。所以上面的docker info 命令是更好的选择,恕我直言
                  【解决方案17】:

                  您还可以使用以下命令检查特定 docker 容器是否正在运行:

                  docker inspect postgres | grep "Running"
                  

                  此命令将检查例如我的 postgres 容器是否正在运行,并将返回输出为 "Running": true

                  希望这会有所帮助。

                  【讨论】:

                  • 这正是我想要的。它有效。 (投反对票的人说出原因很好,这样菜鸟就可以学习更好的礼仪。:))
                  • 我没有投反对票,但是“错误:没有这样的对象:postgres”
                  • @ged postgres 是容器的名称,而不是命令。
                  【解决方案18】:

                  您可以使用此命令检查systemctl status docker,它将显示 docker 的状态。如果你想开始你可以使用systemctl start docker而不是systemctl你也可以分别尝试serviceservice docker statusservice docker start

                  【讨论】:

                  • 此答案假定最终用户使用 systemd 作为他们的 init。
                  • systemctl status docker 正确显示 docker 服务正在运行。谢谢。
                  【解决方案19】:

                  任何 docker 命令(docker -v 除外),例如 docker ps 如果 Docker 正在运行,您将获得一些有效响应,否则您将收到一条消息,其中包括“您的 docker 守护程序是否已启动并正在运行?”

                  您也可以查看您的任务管理器。

                  【讨论】:

                  • 有趣的是,docker -v 不会检查 docker 是否正在运行,但 docker version 会!哈哈
                  猜你喜欢
                  • 2022-12-23
                  • 2017-10-14
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-06-24
                  • 1970-01-01
                  • 2021-08-15
                  • 2015-07-28
                  相关资源
                  最近更新 更多