A healthcheck that tests the app, not the port

A health check that opens a TCP connection reports healthy for a process that is listening and cannot serve a request.

# almost useless: nginx accepts the connection whether or
# not php-fpm is alive
healthcheck:
  test: ["CMD", "nc", "-z", "localhost", "80"]

# useful: an endpoint that touches what the app needs
healthcheck:
  test: ["CMD", "curl", "-fsS", "http://localhost/health"]

# and the endpoint itself checks the database connection,
# the cache, and nothing that is slow or external.

The rule that has held up is that a health check should test the dependencies the process cannot start without and nothing else. Including a third-party API makes the container unhealthy when somebody else has an outage, which turns their incident into a restart loop in yours. Including a slow query makes the check itself a load source. A readiness endpoint returning a JSON object with per-dependency status is worth building once and reusing.