fix(compose): add working healthcheck for the graphile GraphQL server
Context
The server (PostGraphile/graphile) service in docker-compose.yml currently has no healthcheck at all — Docker/Compose/Portainer orchestration has no automated way to detect whether the GraphQL API is actually serving.
Why a naive fix doesn't work
Adding curl -f http://localhost:5678/graphql (a natural first attempt) fails for two independent reasons in this image:
Dockerfile.graphileis built onnode:20-alpinewith nocurl/wgetinstalled — onlynode.- Even with curl available,
localhostresolves to::1(IPv6) first in the container's/etc/hosts, but the server only binds IPv4 (0.0.0.0:5678) — the healthcheck would still fail with "connection refused".
Fix
Uses node -e (always present in this image) to GET http://127.0.0.1:5678/graphql (explicit IPv4). That route is the lightweight landing page defined in src/server.ts (app.get('/graphql', ...)), which always returns 200 — cheaper to poll on an interval than the POST-only /v1/graphql API route itself.
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://127.0.0.1:5678/graphql',res=>process.exit(res.statusCode===200?0:1)).on('error',()=>process.exit(1))"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60sHow this was found
A community-maintained Portainer stack for a production g1v2 deployment had independently added a curl -f http://localhost:5678/graphql healthcheck, which failed continuously (3+ days, unhealthy status) for the two reasons above — even though the GraphQL API itself was serving live production traffic correctly the whole time (confirmed via container logs showing hundreds of successful client requests, and by querying the API directly).
Since the upstream compose file ships no healthcheck for this service at all, anyone adding one manually is likely to hit the same two pitfalls. Proposing this fix upstream so future deployments (and this one, once it can pull the change) get a healthcheck that actually works out of the box.
Testing
Reproduced and validated against the live production container before and after:
- Before:
curl -f http://localhost:5678/graphql→curl: not found;wget http://localhost:5678/...→ connection refused (IPv6).docker inspecthealth log:ExitCode: 1on every check. - After (this fix, applied manually to the running container's equivalent stack and redeployed):
node -e ...against127.0.0.1:5678/graphql→STATUS 200, exit 0. Container health went fromunhealthy(3 day failing streak) tohealthy, confirmed stable over multiple check cycles (FailingStreak: 0).
Diagnosed and proposed with the assistance of an AI coding agent (Claude, Anthropic). Reviewed and validated by the deployment owner against a live container before submission.