Configuration and examples
One of the available Design & Config about Dockerfile introduces the most important commands for container definition. Few of these commands deserve a longer explanation. In this blog post, I will focus on Docker healthcheck. It allows us to monitor easily the status of the container.
There are two main states of the container:
There is also an additional state that lasts until the first check. It shows as starting, which means we don’t know yet the status of the container.
In order to configure Docker healthcheck in your Dockerfile add the following command:
HEALTHCHECK [OPTIONS] CMD command
where command
is your check, which must exit with either code 0 for success or 1 for failure. Based on that code and options healthy/unhealthy status is assigned.
Additionally, we can modify options of the healthcheck using the following parameters:
Let’s make the use of the knowledge gathered above. In the example, I will run a single elasticsearch node to show you how it works and how can we implement Docker healthcheck in practice.
We can start by running container from an official elasticsearch image:
$ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.9.0
To verify if it is running we can examine output of docker ps command:
As you can see there is no useful information about elasticsearch status. We know only that it has been running for some time, but it might not work as intended.
We can now build a new image that is based on elasticsearch but extends it with simple healthcheck. Create a file named elastic_health.Dockerfile with the following content:
FROM elasticsearch:7.9.0
HEALTHCHECK --interval=5s --timeout=3s CMD curl -f -X GET "localhost:9200/_cluster/health?wait_for_status=green&timeout=1s" || exit 1
The implemented check will perform a curl on a specific endpoint, which returns the health of the elasticsearch cluster. Do not confuse it with the container status. Elasticsearch has its own healthcheck, that we want to expose to the container status. The default response is json with some useful information, but in this case, only green status is in our focus. By providing additional options in the URL we ensure that this command ends with success if the status is green and fails otherwise. To make sure we are compliant with Docker healthcheck expected exit status in case of any error we exit with code 1.
Let’s see what is the difference between vanilla elasticsearch and the one with Docker healthcheck.
First of all, we need to build a new image based on the aforementioned Dockerfile:
$ docker build -f elastic_health.Dockerfile . -t elastic_health
and run the new container alongside the old one (we need to change ports to do so):
$ docker run --rm -d --name elastic_health -p 9201:9200 -p 9301:9300 -e "discovery.type=single-node" elastic_health
Having this done we can check status:
As mentioned before, the initial status is starting. After a couple of seconds, Docker enters a healthy state.
We can do one more experiment to verify that the unhealthy state also works correctly. Using the next command I will force elasticsearch to attempt to create a cluster with some arbitrary address (1.1.1.1). Of course, this will fail since no elasticsearch instance is at that address, so the status will be different from green:
$ docker run -d --name elastic_health -p 9201:9200 -p 9301:9300 -e "node.name=elastic_health" -e "discovery.seed_hosts=1.1.1.1" -e "cluster.initial_master_nodes=elastic_health,1.1.1.1" elastic_health
Leave a Reply