How to wait until `docker start` is finished?

2019-08-01 15:36发布

When I run docker start, it seems the container might not be fully started at the time the docker start command returns. Is it so?

Is there a way to wait for the container to be fully started before the command returns? Thanks.

标签: docker
2条回答
祖国的老花朵
2楼-- · 2019-08-01 16:07

A common technique to make sure a container is fully started (i.e. services running, ports open, etc) is to wait until a specific string is logged. See this example Waiting until Docker containers are initialized dealing with PostgreSql and Rails.

Edited:

There could be another solution using the HEALTHCHECK of Docker containers.The idea is to configure the container with a health check command that is used to determine whether or not the main service if fully started and running normally.

The specified command runs inside the container and sets the health status to starting, healthy or unhealthy depending of its exit code (0 - container healthy, 1 - container is not healthy). The status of the container can then be retrieved on the host by inspecting the running instance (docker inspect).

Health check options can be configured inside Dockerfile or when the container is run. Here is a simple example for PostgreSQL

 docker run --name postgres --detach \
  --health-cmd='pg_isready -U postgres' \
  --health-interval='5s' \
  --health-timeout='5s' \
  --health-start-period='20s' \
  postgres:latest && \
  until docker inspect --format "{{json .State.Health.Status }}" postgres| \
  grep -m 1 "healthy"; do sleep 1 ; done

In this case the health command is pg_isready. A web service will typically use curl, other containers have their specific commands The docker community provides this kind of configuration for several official images here

Now, when we restart the container (docker start), it is already configured and we need only the second part:

docker start postgres && \
until docker inspect --format "{{json .State.Health.Status }}" postgres|\ 
grep -m 1 "healthy"; do sleep 1 ; done

The command will return when the container is marked as healthy

Hope that helps.

查看更多
地球回转人心会变
3楼-- · 2019-08-01 16:22

Disclaimer, I'm not an expert in Docker, and will be glad to know by myself whether a better solution exists.

The docker system doesn't really know that container "may not be fully started".

So, unfortunately, there is nothing to do with this in docker. Usually, the commands used by the creator of the docker image (in the Dockerfile) are supposed to be organized in a way that the container will be usable once the docker start command ends on the image, and its the best way. However, it's not always the case.

Here is an example:

A Localstack, which is a set of services for local development with AWS has a docker image, but once its started, for example, S3 port is not ready to get connections yet. From what I understand a non-ready-although-exposed port will be a typical situation that you refer to.

So, out of my experience, in the application that talks to docker process the attempt to connect to the server port should be enclosed with retries and once it's available.

查看更多
登录 后发表回答