Docker Healthchecks
HEALTHCHECK
was added in 1.12 (mid 2016)- Supported in Dockerfile, Compose YAML, docker run and Swarm Services
- Docker engine will exec's the command in the container
- (e.g.
curl localhosht
)
- (e.g.
- It expects
exit 0
(OK) orexit 1
(Error) - Three container states: starting, healthy, unhealthy
- Much better than "is binary still running?"
- Not a external monitoring replacement
- Healthcheck status shows up in
docker container ls
- Check last 5 healthchecks with
docker container inspect
- Docker run does nothing with healthchecks
- Services will replace tasks if they fail healthcheck
- Service updates wait for them before continuing
Healthcheck Docker Run Example
docker run \
--health-cmd="curl -f localhost:9200/_cluster/health || false" \
--health-interval=5s \
--health-retries=3 \
--health-timeout=2s \
--health-start-period=15s \
elasticsearch:2
Options for healthcheck command
--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--start-period=DURATION (default: 0s) (17.09+)
--retries=N (default: 3)
Basic command using default options
HEALTHCHECK curl -f http://localhost/ || false
Custom options with the command
HEALTHCHECK --timeout=2s --interval=3s --retries=3 \
CMD curl -f http://localhost/ || exit 1
Healthcheck in a Dockerfile
Healthcheck in Nginx Dockerfile
Static website running in Nginx, just test default URL
FROM nginx:1.13
HEALTHCHECK --timeout=2s --interval=3s --retries=3 \
CMD curl -f http://localhost/ || exit 1
Healthcheck in PHP Nginx Dockerfile
PHP-FPM running behind Nginx, test the Nginx and FPM status URL
FROM your-nginx-php-fpm-combo-image
# don't do this if php-fpm is another container
# must enable php-fpm ping/status in pool.ini
# must forward /ping and /status urls from nginx to php-fpm
HEALTHCHECK --timeout=3s --interval=5s \
CMD curl -f http://localhost/ping || exit 1
Healthcheck in Postgres Dockerfile
Use a PostgreSQL utility to test for ready state
FROM postgres
# specify real user with -U to prevent errors in log
HEALTHCHECK --timeout=3s --interval=5s \
CMD pg_isready -U postgres || exit 1
Healthcheck in Compose/Stack Files
version: "2.1"
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 1m #version 3.4 minimum
Examples
[node1] ~> docker container run --name p1 -d postgres
e7d23ddaef770db17e88542edfa83b0114cf2b2f53a4a48e0ebbc84259038872
[node1] ~> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e7d23ddaef77 postgres "docker-entrypoint.s…" 41 seconds ago Up 39 seconds 5432/tcp p1
[node1] ~> docker container run --name p2 -d --health-cmd="pg_isready -U postgres || exit 1" postgres
2cb1fab9a12011cb3118ec11800e22cc616f7a3926715cba05fa66cecb6a2fa5
[node1] ~> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2cb1fab9a120 postgres "docker-entrypoint.s…" 15 seconds ago Up 13 seconds (health: starting) 5432/tcp p2
e7d23ddaef77 postgres "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 5432/tcp p1
[node1] ~> docker container ls
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2cb1fab9a120 postgres "docker-entrypoint.s…" 2 minutes ago Up 2 minutes (healthy) 5432/tcp p2
e7d23ddaef77 postgres "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 5432/tcp p1
[node1] ~> docker container inspect p2
~~~ output ommited ~~~
"Health": {
"Status": "healthy",
"FailingStreak": 0,
"Log": [
{
"Start": "2019-01-24T17:41:03.378768196Z",
"End": "2019-01-24T17:41:03.442862293Z",
"ExitCode": 0,
"Output": "/var/run/postgresql:5432 - accepting connections\n"
},
{
"Start": "2019-01-24T17:41:33.458365064Z",
"End": "2019-01-24T17:41:33.51977943Z",
"ExitCode": 0,
"Output": "/var/run/postgresql:5432 - accepting connections\n"
},
{
"Start": "2019-01-24T17:42:03.532545567Z",
"End": "2019-01-24T17:42:03.594929445Z",
"ExitCode": 0,
"Output": "/var/run/postgresql:5432 - accepting connections\n"
},
{
"Start": "2019-01-24T17:42:33.610781557Z",
"End": "2019-01-24T17:42:33.673644141Z",
"ExitCode": 0,
"Output": "/var/run/postgresql:5432 - accepting connections\n"
},
{
"Start": "2019-01-24T17:43:03.684101549Z",
"End": "2019-01-24T17:43:03.746147982Z",
"ExitCode": 0,
"Output": "/var/run/postgresql:5432 - accepting connections\n"
}
]
}
~~~ output ommited ~~~
[node1] ~> docker service create --name p1 postgres
yh7phs8qczi8o7gn852y9u2r7
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
[node1] ~> docker service create --name p2 --health-cmd="pg_isready -U postgres || exit 1" postgres
ujqvzuk8c6ouurlzgjcla04cs
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged