Docker Healthchecks

  • HEALTHCHECKwas 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)
  • It expects exit 0(OK) or exit 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

results matching ""

    No results matching ""