Postgres is (un)healthy and the app won't start
Medium

Problem

The stack came up but the API never did. docker ps shows db running but (unhealthy), and api isn't running at all — compose was told to wait for db to be healthy before starting api, and that never happened.

Yet the database looks fine in its logs. Figure out whether postgres is actually broken or whether something else is keeping the stack down, then get api up.

Initial setup

  • dbpostgres:15, Up 20 minutes (unhealthy), on 5432.
  • apimyapp:latest, Created (never started; gated on db health).

Example interaction

$ docker ps -a
CONTAINER ID   IMAGE          STATUS                            NAMES
a0b1c2d3e4f5   postgres:15    Up 20 minutes (unhealthy)         db
f5e4d3c2b1a0   myapp:latest   Created                           api

$ docker inspect -f '{{json .State.Health}}' db
{"Status":"unhealthy","FailingStreak":4,"Log":[{"ExitCode":1,"Output":"",...}]}

Acceptance

You've solved it when:

  • You've established the failure is a misconfigured healthcheck, not a
broken database: postgres's own logs show `database system is ready to accept connections, while .State.Health` shows the probe failing (ExitCode: 1). The DB is up; the healthcheck command is wrong, so the health gate falsely held api back.
  • You've got api running (the dependency is genuinely available, so
the app can be started).

Constraints

  • Tools: docker CLI only.
  • The diagnosis must distinguish the healthcheck Log (failing probe) from
the postgres server log (ready) — they disagree, and that's the clue.

Follow-up

  1. Where does .State.Health.Log come from, and why can it say unhealthy
while docker logs shows the server is up?
  1. A correct postgres healthcheck is usually pgisready -U "$POSTGRESUSER"
— why is a bare false (or a check against the wrong port/db) a classic way to get a permanently-unhealthy-but-fine container?
  1. With compose dependson: condition: servicehealthy, what is the
blast radius of one wrong healthcheck line?
Live session
Code
SavedNo commands yet