Docker Tip #85: Define HEALTHCHECK in your Docker Compose File
There's pretty big benefits for having your health check defined in your Docker Compose file instead of your Dockerfile. Here's why.
The main issue with putting it in your Dockerfile
is that you end up using
the same health check for all environments, which for a typical web app might
be curl
‘ing some URL.
This isn’t fun in development when you’re using the Docker Compose terminal output to help debug an issue while you get bombarded by health check outputs on a set interval.
Another potential downside is if you’re using Kubernetes you’ll probably want
to use its own health check mechanisms which is defined in its YAML config.
You wouldn’t want your Dockerfile’s HEALTHCHECK
to run in this case.
You can fix both issues in 1 shot by moving the health check to your Docker Compose file. You can do that by adding this to your Docker Compose service:
services:
mywebapp:
# ...
env_file:
- ".env"
healthcheck:
test: "${DOCKER_HEALTHCHECK_TEST:-curl localhost:8000/healthy}"
interval: "60s"
timeout: "3s"
start_period: "5s"
retries: 3
Feel free to configure it however you see fit. 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 is a minimal command that won’t throw an
error and it produces no output. It’s very close to a no-op. It’s a way to
disable the health check in development.
With the above approach now you can use your single Dockerfile / Docker image with Docker Compose, Swarm and Kubernetes. Yay for portability!
I’ve been doing this for quite some time now and you can see a fully working implementation of this pattern in the open source version of my Build a SAAS App with Flask course on GitHub.