Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,15 @@ services:
resources:
limits:
memory: "${POSTGRES_MEM_LIMIT:-2g}"
# start_period (#3898): pg_isready's failed-probe count applies from the very first check unless a
# start_period grace is set. A genuinely cold initdb (first pull, slow disk, low-memory VPS, creating
# the pgvector extension) can plausibly take longer than the 5x10s=50s this healthcheck otherwise
# allows before Docker marks the service unhealthy and fails every downstream service_healthy gate.
healthcheck:
test: ["CMD-SHELL", "pg_isready -U gittensory"]
interval: 10s
timeout: 5s
start_period: 20s
retries: 5

# ── PgBouncer (--profile pgbouncer) ───────────────────────────────────────
Expand Down Expand Up @@ -264,6 +270,7 @@ services:
test: ["CMD", "pg_isready", "-h", "127.0.0.1", "-p", "5432"]
interval: 10s
timeout: 5s
start_period: 15s
retries: 5

# Postgres internals exporter. Starts with the Postgres profiles so Prometheus can scrape it when
Expand Down
13 changes: 13 additions & 0 deletions test/unit/selfhost-compose-db-health.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,17 @@ describe("docker-compose.yml — postgres/pgbouncer startup ordering (#2500, #25

expect(dependsOn.postgres).toEqual({ condition: "service_healthy" });
});

it("gives postgres and pgbouncer a start_period so a cold pg_isready probe isn't marked unhealthy (#3898)", () => {
const compose = readYaml("docker-compose.yml");
const services = (compose.services as Record<string, Record<string, unknown>>) ?? {};

// Every failed probe counts toward `retries` from the very first check unless start_period is set --
// a genuinely cold pgvector initdb (first pull, slow disk) can plausibly exceed 5 retries at 10s each
// with no grace period, marking postgres unhealthy and failing every service_healthy depends_on gate.
for (const name of ["postgres", "pgbouncer"]) {
const healthcheck = (services[name] ?? {}).healthcheck as { start_period?: string } | undefined;
expect(healthcheck?.start_period, name).toBeTruthy();
}
});
});
Loading