如何检测是否码头运行程序化成功?

我正在编写一个非常简单的 bash 脚本,以快速检查容器是否仍在正确构建和启动,以及容器中的应用程序是否响应请求。

有时候 docker run会失败,例如,因为我试图绑定容器的端口已经分配好了。但是当这种情况发生时,docker run的退出代码仍然是0,所以我不能使用退出代码。如何通过编程检查容器是否正确启动?

我正在考虑的解决方案是:

  • 解析输出中的错误
  • docker ps查看容器是否正在运行

但是这两种方法似乎都有点过分和丑陋。我是否错过了检查 docker run是否成功的更好方法?

67793 次浏览

As suggested by Abel Muiño in comments, this may have been fixed in more recent Docker versions (I'm currently running 0.9.1).

But, if you're temporarily stuck like me with an older version, I did find a decent workaround to check if the container started by using docker inspect.

docker inspect returns a JSON object with a lot of info about the container, and in particular whether the container is currently running or not. The -f flag lets you easily extract the bits needed:

docker inspect -f \{\{.State.Running}} $CONTAINER_ID

or

docker inspect -f "\{\{.State.Running}}" $CONTAINER_ID

will return true or false.

Note that you probably want to sleep 1 (or more) between starting the container and checking if it is up. If there's something wrong with your setup it's possible that it would appear as 'running' for a very short time before actually exiting.

To avoid parsing anything, you could use docker top, which returns 1 if the container is not running:

id=$(docker run mycontainer)
if ! docker top $id &>/dev/null
then
echo "Container crashed unexpectedly..."
return 1
fi

We could use docker exec $id true 2>/dev/null || echo not running.

This command does not write to stdout, as "docker top" does. It writes to stderr when the container is not running, the same message as "docker top".

I had to use:

$ docker inspect -f \{\{.State.Health.Status}} xxx

(the container was in state running but the service inside the container wasn't fully started.

Part of inspect output:

"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 1618,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-03-08T10:39:24.061732398Z",
"FinishedAt": "0001-01-01T00:00:00Z",
"Health": {
"Status": "starting",
"FailingStreak": 0,
"Log": []

Applying the suggestions aforementioned to a script.

1 - Create a script keepMyDockerUp.sh :

vi keepMyDockerUp.sh




#!/bin/bash
Container_ID=INSERT_YOUR_CONTAINER_ID HERE
result=$( docker inspect -f \{\{.State.Running}} $Container_ID)
echo "result is" $result
if [ $result = "true" ]
then
echo "docker is already running"
else
systemctl restart docker
docker start $Container_ID
fi

2 - Then simply add it to cron, so your script verifies whether your Docker container is up from time to time:

crontab -e

Go to the last line and add your script file. For example:

* * * * * /root/keepMyDockerUp.sh

3 - Save crontab and never worry about your Docker container being down again.

Hope it helps...

;-)