Menu

US Region

Grandmetric LLC
Lewes DE 19958
16192 Coastal Hwy USA
EIN: 98-1615498
+1 302 691 94 10
info@grandmetric.com

EMEA Region

GRANDMETRIC Sp. z o.o.
ul. Metalowa 5, 60-118 Poznań, Poland
NIP 7792433527
+48 61 271 04 43
info@grandmetric.com

UK

Grandmetric LTD
Office 584b
182-184 High Street North
London
E6 2JA
+44 20 3321 5276
info@grandmetric.com

  • en
  • pl
  • Docker healthcheck

    Configuration and examples

    Docker healthcheck

    Date: 16.09.2020

    Category: DevOps


    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:

    • healthy – this means that whatever we defined as a check passed
    • unhealthy – the defined check failed

    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.

    Configuring Docker healthcheck

    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:

    • –interval=DURATION (default: 30s) – how often check is performed
    • –timeout=DURATION (default: 30s) – how long does daemon waits for exit code = 0
    • –start-period=DURATION (default: 0s) – additional delay before first check
    • –retries=N (default: 3) – how many checks must fail one after another before assigning unhealthy status.

    Example

    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

    Author

    Mateusz Buczkowski

    Mateusz Buczkowski is a senior software engineer and a leader of the R&D team. In Grandmetric, Mateusz is responsible for the shape of the software projects as well as takes his part in backend development. On top of that, he researches and develops IoT and wireless solutions. As an R&D engineer, he took part in two FP7 EU projects, namely 5GNOW and SOLDER, where he worked on solutions that could be used in the 5th Generation wireless networks.

    Leave a Reply

    Your email address will not be published. Required fields are marked *


    Grandmetric