Why are Docker Compose Healthcheck important

Facebook
Twitter
LinkedIn

Never miss a post!

Sign up for our newsletter and get FREE Development Trends delivered directly to your inbox.

You can unsubscribe any time. Terms & Conditions.
Categories

Docker is used to manage and create software package using two concepts: images and containers. To ship software solutions, we create portable Docker images. The Docker containers are created from the writable executable layer of those images and then deployed via cloud service providers. We need to make sure that our containers are running properly before we can deploy our application services. It is therefore important to check that your Docker service runs as expected. An inoperable Docker service could lead to major problems. To avoid such issue, you can us docker healthcheck. This article will explain docker healthcheck, and how it can be used with Docker compose.

 

What is a Docker Healthcheck?

A healthcheck is just what it sounds like: a way to assess the health of a resource. This is a way of determining if a container running is in a healthy state or not. We ask Docker for a series of commands to run to check if our service/application is running. Docker executes those commands, checks the status code returned and determines whether the container is healthy.

If you use Docker Compose to manage multiple containers, you can add a HEALTHCHECK directive to the Dockerfile or a healthcheck configuration parameter (to the docker-compose.yml) to health-check a container. In this article, I will talk about docker compose healthcheck.

 

Heathcheck with Docker Compose

Docker Compose allows you to manage multiple containers of Docker applications. A compose file allows us to define the services we want and then configure them according our needs. Your Docker Compose file can be used to define your health check instead of your Dockerfile. The original introduction of healthcheck was in the 2.1 Compose format. It is now part the compose specification that is used by the latest versions of Docker Compose. This allows for a check to be set up to determine if containers are “healthy” for a service.

It is not a good idea to put health checks in your Dockerfile. You end up using the same health checks for all environments. For example, curling a URL might be a common web app. It is not fun when you use Docker Compose to debug an issue and get bombarded with health check outputs every other minute. Kubernetes will likely require you to use its own health checks, which are defined in the YAML configuration. This would prevent your Dockerfile’s HEALTHCHECK from running in this situation.

Both issues can be fixed in one go by adding the health check to your Docker Compose file. Below is a sample example of how to use healthcheck to your Docker Compose file:


services:
  mywebapp:
    # ...
    env_file:
      - ".env"
    healthcheck:
      test: "${DOCKER_HEALTHCHECK_TEST:-curl localhost:8000/healthy}"
      interval: "60s"
      timeout: "3s"
      start_period: "5s"
      retries: 3

 

You can configure it however you like. I like using an environment variable and by default it will curl my app at localhost:8000/healthy which is what I want in production. But in development, I would set DOCKER_HEALTHCHECK_TEST=/bin/true in an .env file. The /bin/true command, which is a minimal command, doesn’t throw any errors and produces no output. It is very close to a no-op. It is a way to disable health checks in development.

 

But, how do I wait for container X before starting Y? This is a common issue and requires additional tools and scripts, such as wait-for-it and dockerize. These additional tools and scripts are often unnecessary when using the healthcheck parameter.

 

Let’s take another example, consider we have a web application that uses nginx for its web server. We need to define two services: app, and nginx. To define the healthcheck process, we can add a compose configuration parameter in our nginx service:

version: "3.7"
services:
  app:
    build:
      context: .
    depends_on:
      - nginx
    
  nginx:
    image: nginx:latest
    ports:
      - '80:80'
    healthcheck:
      test: curl --fail http://localhost || exit 1
      interval: 20s
      timeout: 20s
      start_period: 20s
      retries: 5

Now we can run docker-compose up -d and check our containers list using docker ps -a. This will show the health of the container.

CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS                            PORTS                NAMES

5y6dfgfggd75   nginx:latest   “/docker-entrypoint.…”   4 seconds ago   Up 3 seconds (health: starting)   0.0.0.0:80->80/tcp   healthcheck_nginx_1

 

After a few seconds, you will see a message against the container such as: Up About a Minute (healthy message).

Docker Compose Healthcheck Properties

Five properties are included in the Docker Compose Healthcheck:

 

  • test: This property is used to specify the command that will execute and it serves as the health check for the container. If everything is correctly set up, this command MUST be available and functioning.
  • interval: This property indicates the time interval between the initial health check and the next health check.
  • timeout: This property indicates the amount of time Docker waits for you to issue a health check command that will return an exit code, before declaring it failed.
  • retries: This property indicates the number of consecutive failures in a health check required to declare the container unhealthy.
  • start_period: This property indicates how long your container takes to bootstrap. A container that has an exit code of greater than zero will not be deemed unhealthy during this time. However, a container with a status code of zero will be deemed healthy.

 

Custom Health Check

What if we require a more comprehensive and complex health check? Is curl http://localhost sufficient for all image containers? No!

You may have noticed that for services such as ElasticSearch or Nginx, a simple HTTP request can be sufficient to determine if the service container is up and running (healthy) or if there are any issues. But, if we need to check a few other aspects of an app’s health, then we can create a custom health-check program and run it. For example:

HEALTHCHECK –interval=10s CMD go run healthcheck.go

We can also create a status-check endpoint within our backend system, and call it to confirm that our application is running smoothly.

HEALTHCHECK –interval=10s \

CMD curl –fail -I http://localhost:8080/status || exit 1

Final Thoughts

Docker health check is used in order to assess the health of a container that is running. A health check command, which is used to test a container’s functionality, is created when a Docker container is launched. Docker can’t tell if services are running in your container unless a health check is defined. So, go ahead and add healthcheck to your docker compose files. This will allow you to monitor the health of your containers.

Facebook
Twitter
LinkedIn

Our website uses cookies that help it to function, allow us to analyze how you interact with it, and help us to improve its performance. By using our website you agree by our Terms and Conditions and Privacy Policy.