pg_isready: Wait for Postgres in CI
pg_isready exits 0 when a PostgreSQL server is accepting connections, so it gates migrations behind a ready database.
A service-container database is not ready the instant the container starts. pg_isready polls the server and returns a clean exit code, letting you loop until Postgres accepts connections before you run any migration or test.
What it does
pg_isready connects to a PostgreSQL server and reports its status without running any SQL. It exits 0 when the server is accepting connections, 1 when it is starting up or rejecting, 2 when there is no response, and 3 on a bad invocation. It does not need valid credentials to detect readiness.
Common usage
# single check
pg_isready -h db -p 5432 -U app
# wait loop in CI (bash)
until pg_isready -h db -p 5432 -U app; do
echo "waiting for postgres..."; sleep 1
doneOptions
| Flag | What it does |
|---|---|
| -h <host> | Host to check |
| -p <port> | Port to check (default 5432) |
| -U <user> | User name to report in the connection |
| -d <db> | Database name to check |
| -t <secs> | Connection timeout (default 3, 0 disables) |
| -q | Quiet: suppress the status message |
In CI
Run a pg_isready wait loop before migrations so you never hit "Connection refused" from a database that is still booting. Many CI systems have a service-container health-check option that runs pg_isready for you; a manual until loop is the portable fallback. Cap the loop with a timeout so a truly dead database fails fast instead of hanging.
Common errors in CI
"no response" with exit code 2 means the host or port is unreachable, often the wrong service hostname. Exit code 1 ("rejecting connections") is normal during startup; keep looping. If pg_isready reports ready but psql then fails auth, that is expected: readiness does not validate credentials, only that the server responds.