docker-library/docs

Request: adding Docker health check to `postgres/README.md`

jamesbraza opened this issue · 6 comments

It would be good to add a healthcheck to the postgres/README.md.

There are some possible starting points posed here: https://stackoverflow.com/questions/65115627/safe-ways-to-specify-postgres-parameters-for-healthchecks-in-docker-compose


Aside: running the below:

---
version: "3.8"
services:
    postgres:
        image: postgres:latest
        environment:
            POSTGRES_USER: user
            POSTGRES_PASSWORD: pass
            POSTGRES_DB: db
docker compose up postgres --detach 
docker compose run postgres pg_isready --username user --dbname db

I can never get pg_isready to output something besides /var/run/postgresql:5432 - no response

The following works for me:

services:
    postgres:
        image: postgres:latest
        environment:
            POSTGRES_USER: user
            POSTGRES_PASSWORD: pass
            POSTGRES_DB: db
        healthcheck:
            test: pg_isready
            interval: 60s
            retries: 3
            start_period: 10s
            timeout: 10s
CONTAINER ID   IMAGE             COMMAND                  CREATED              STATUS                        PORTS      NAMES
c1242e57029b   postgres:latest   "docker-entrypoint.s…"   About a minute ago   Up About a minute (healthy)   5432/tcp   postgres-health-postgres-1

@LaurentGoderre can you tell me what this outputs for you?

docker compose run postgres pg_isready
# or
docker compose run postgres pg_isready --username user --dbname db

And also thanks for sharing your config, appreciate your help!

Running that command doesn't give you real result because you are overwriting the command so the postgres doesn't start.

A better way would be

docker run --name my-db  -e POSTGRES_PASSWORD=password -d postgres
sleep 2
docker exec my-db pg_isready
820871225dadb64bf79b128613e48a84224f2f53504164be989ce9cd770754fc
/var/run/postgresql:5432 - accepting connections

Ah I see, thank you!! One follow up question, is the healthcheck seems to be conservatively slow. With the healthcheck:

---
version: "3.8"
services:
    postgres:
        image: postgres:16.1-bookworm
        ports:
            - "5432:5432"
        healthcheck:
            test: pg_isready
            start_period: 0s
        environment:
            POSTGRES_HOST_AUTH_METHOD: trust
 > time docker compose up --detach --wait postgres
...
docker compose up --detach --wait postgres  0.20s user 0.16s system 1% cpu 31.287 total

We see it takes about 31 seconds. Now removing the healthcheck, it is way faster:

> docker compose up --detach postgres && sleep 1 && docker compose exec postgres pg_isready
...
/var/run/postgresql:5432 - accepting connections

We see it worked within about 1 second.

Why is the healthcheck using pg_isready taking over 30 seconds?

Update, I have realized from https://docs.docker.com/engine/reference/builder/#healthcheck the default interval is 30-seconds.

So moving to:

        healthcheck:
            test: pg_isready
            interval: 1s

This solved the issue:

>  time docker compose up --detach --wait postgres
...
docker compose up --detach --wait postgres  0.10s user 0.06s system 7% cpu 2.053 total

#2393 (comment) 🙈

(see also https://github.com/docker-library/faq#healthcheck, many of which applies to trying to make "generic" documentation for health checks too, and https://github.com/docker-library/healthcheck/blob/40afbf64d69cf933af0da4df6383958a29113601/postgres/docker-healthcheck which is likely more than we'd want in the documentation but the main point there being explicitly using TCP to ensure we don't connect to the temporary server)