Bashar
Bashar

Reputation: 393

Wait for docker container healthcheck to succeed before detaching

Is there a way in docker-py to wait for the healthcheck to succeed before detaching the container? I'm trying to do the following but the issue is that .run() returns before the healthcheck is successful. If I try to curl the elasticsearch endpoint after run(), the call fails.

cls.es = client.containers.run("elasticsearch:7.5.0", auto_remove=True,
                                detach=True, publish_all_ports=True,
                                healthcheck='curl localhost:9200/_cat/health',
                                ports={'9200/tcp': 9200},
                                environment={'discovery.type': 'single-node'})

Upvotes: 4

Views: 2181

Answers (1)

LondonRob
LondonRob

Reputation: 78803

This appears to be completely undocumented, but from poking around in the source code, I've come up with a method for waiting for a healthcheck to pass before proceeding.

Since this isn't really anything to do with which image you're healthchecking, I've used an image I know well, which has its own healthcheck tool. This method will work for other images and healthcheck methods too.

from time import sleep
from docker import APIClient
from docker.models.containers import Container
import docker

def get_health(container: Container):
    api_client = APIClient()
    inspect_results = api_client.inspect_container(container.name)
    return inspect_results['State']['Health']['Status']


client = docker.from_env()
container = client.containers.run(
    'postgres:12',
    environment={'POSTGRES_HOST_AUTH_METHOD': 'trust'},
    detach=True,
    remove=True,
    healthcheck={'test': ['CMD', 'pg_isready', '-U', 'postgres'], 'interval': 100000000},
)
while get_health(container) != 'healthy':
    print(get_health(container))
    sleep(0.1)
print('Container is healthy')

Disclaimers:

  • There's no timeout here, so if the healthcheck fails, this process will wait forever
  • Since this is completely undocumented, I assume there's some reason why it isn't the right way to do this. I'd be interested to hear whether any of the contributors to py-docker know what happened to this feature.

Update from a contributor

I've found this comment in the Github issues tracker which says:

The idea is to avoid the proliferation of properties that in turn need to be maintained and may appear in different locations in the attribute dictionary depending on the API version. As a result, we limit the number of quick access attributes to a few essentials. And to that point, I would personally disagree with the notion that a health attribute is essential; most containers do not use healthchecks at all.

Upvotes: 11

Related Questions