Docker Compose Healthchecks Checker
Check Docker Compose YAML for missing or weak healthchecks, readiness blockers, start-order race risks, restart-policy gaps, and probe suggestions before handoff.{{ result.summary.heading }}
- {{ error }}
| {{ header }} | Copy |
|---|---|
| {{ cell }} | |
| No rows for the current Compose input. |
Introduction:
Docker Compose healthchecks are small commands that tell Docker whether a running container is actually ready to do useful work. That distinction matters because a container can be running while the database is still starting, the web server has not opened its readiness endpoint, or a worker process has not reached its queue loop. Startup order alone is not enough for stacks where one service must wait for another service to become usable.
Healthchecks become especially important when Compose files use dependency conditions such as service_healthy. A dependency can only satisfy that condition when the target service has a valid healthcheck and reaches a healthy state. If a database, cache, broker, or API has no healthcheck, dependent services may start too early or wait on a condition that cannot succeed in the way the Compose file implies.
Restart policy is a separate concern. A healthcheck reports container health; it does not by itself decide whether a failed service should be started again after exit. Production Compose stacks often need both readiness checks and restart behavior, while local development stacks may intentionally keep helper services lighter. A useful review separates those choices instead of treating every missing probe as the same kind of problem.
A healthcheck audit is still a static review of the Compose file. It can catch missing declarations, weak timing, start-order risks, and likely probe patterns, but it cannot prove that a command succeeds inside the real image, that credentials are correct, or that the service is healthy under load. Use the result as a preflight checklist before testing the stack with actual containers.
Technical Details:
A Compose healthcheck is declared per service and centers on a test command. The command may use list syntax with CMD, CMD-SHELL, or NONE, or it may be written as a shell string. Timing fields such as interval, timeout, retries, start_period, and start_interval control when the check runs and how many failures are tolerated before the container becomes unhealthy.
Dependency conditions change the meaning of a healthcheck. The short form of depends_on is equivalent to a start-only dependency. The long form can request service_healthy, which waits for the dependency healthcheck to pass, or service_completed_successfully, which fits one-shot jobs such as migrations. A start-only dependency on a stateful service can still race with database or cache initialization.
Rule Core
The checker reads the top-level services map, classifies each service from names, images, build settings, commands, and environment keys, then decides whether that service should have a probe under the selected profile and scope.
| Review rule | Boundary used | Resulting action |
|---|---|---|
| Probe required | Stateful, app/API, worker, scheduler, and proxy roles count when the profile and review scope include them. | Missing, disabled, or invalid healthchecks become gaps for those services. |
| Optional service | Job/helper services and other roles outside the selected scope do not count as missing-healthcheck gaps. | The service remains visible, but its missing probe is labeled optional. |
| Weak timing | Standard and strict timing review expect explicit interval, timeout, and retries; strict review also expects startup grace. |
The healthcheck is present, but the row receives timing notes and a weak status. |
| Fragile timing | timeout greater than or equal to interval, retries below 2, or timeout below 1 second. |
The timing warning remains even when lenient review skips missing-field notes. |
| Readiness blocker | A service depends on another service with condition: service_healthy, but that dependency has no valid healthcheck. |
The readiness ledger labels the edge as a blocker and asks for a valid probe or a changed condition. |
| Restart review | Production profile, restart-policy audit on, required service, and no direct restart or deploy restart condition. |
The service can be otherwise covered but still receives restart-review wording. |
Healthcheck status is a compact label built from the presence of a command and the timing review. Disabled healthchecks are treated separately because Compose can suppress an image-provided healthcheck with disable: true or test: NONE.
| Status | Trigger | Interpretation |
|---|---|---|
| Covered | A non-empty healthcheck command is present and no timing warnings are produced. | The service has a usable readiness signal under the selected timing review. |
| Weak | A command is present, but required timing fields or timing boundaries need review. | The probe exists, but its cadence may be brittle for startup or failure detection. |
| Missing | No healthcheck is declared for a service that needs one under the current review. | The suggested-probe row becomes the fastest place to draft a starting command. |
| Disabled | The healthcheck uses disable: true or NONE. |
The Compose file intentionally suppresses health reporting and should explain why. |
| Invalid | A healthcheck exists but has no test command. | Add a real command plus timing fields before using the service in readiness gates. |
| Optional | The selected scope does not require a probe for that service. | Keep application retries in mind if the service later becomes a dependency target. |
Duration parsing accepts plain seconds and common Compose-style units including nanoseconds, microseconds, milliseconds, seconds, minutes, and hours. The checker does not run the healthcheck command. It reviews declarations, compares timing values when they can be parsed, follows dependency edges, and produces deterministic tables, chart data, and JSON from the supplied YAML and settings.
Everyday Use & Decision Guide:
Use Stack name as the label you would want in a handoff note, pull request, or release review. It does not change the audit logic, but it keeps copied JSON and exported rows tied to the Compose stack being checked.
Pick Audit profile before judging the gaps. Production handoff is the strictest default because app, worker, scheduler, proxy, and stateful services usually need explicit readiness and recovery behavior. CI dependency gate focuses more on dependency targets and core services. Local development review keeps helper services lighter so a developer-only stack is not overloaded with production wording.
- Review scope controls which services count as required. Use All runtime services for a release pass, Core app, worker, proxy, and stateful services when helper containers should stay visible but not count, and Readiness dependency targets when you only care about services referenced by
depends_on. - Timing review changes how much missing timing detail is flagged. Use Strict startup timing checks for slow databases and brokers that need startup grace, and Only invalid timing when you want fewer notes during a quick local scan.
- Restart policy audit should usually stay on for production Compose stacks. Turn it off only when another supervisor or platform owns restart behavior.
- Compose YAML accepts pasted text, dropped files, and browsed
.yml,.yaml, or.txtfiles up to 2 MB.
The summary line is the first stop: it reports how many required service healthchecks are strong, how many readiness blockers were found, and how many start-order reviews remain. Then use Healthcheck Coverage for service-by-service gaps, Readiness Gate Ledger for depends_on edges, and Probe Pattern Brief for starter probe commands and timing baselines.
A result with 0 gaps is not a guarantee that the stack is production-ready. It means the selected profile found no missing or invalid required healthchecks. Before using the Compose file for a release handoff, compare the suggested probe command with the actual image contents, run the stack, and confirm that the health state changes the way the dependent services expect.
Step-by-Step Guide:
Work from scope to YAML to result review so the gap count reflects the same rules you would use in the handoff.
- Enter a meaningful value in Stack name; later, confirm the same label appears in the JSON context if you copy or download the structured result.
- Choose Audit profile, Review scope, and Timing review. Watch the summary badges change between production, CI, and local-development wording when profile strictness changes.
- Leave Restart policy audit on for production review unless an external orchestrator owns restarts. If it is on, missing restart behavior can appear as Restart review even when a healthcheck is covered.
- Paste the Compose content into Compose YAML, browse for a file, drop a file onto the textarea, or click Load sample to see the default orders stack.
- If the alert says Review Compose input, fix the shown message first. Empty input asks for a Compose file, malformed YAML reports an invalid source, and a file without a top-level
servicesmap reports that no services were found. - Read Healthcheck Coverage for each service role, healthcheck status, timing text, restart policy, dependency posture, and action. The Action column is the best place to start fixing missing or weak rows.
- Open Readiness Gate Ledger when the summary mentions readiness blockers or start-order reviews. A Blocker row means a
service_healthydependency points at a service without a valid healthcheck. - Use Probe Pattern Brief to copy the idea, not the command blindly. PostgreSQL, Redis, MongoDB, RabbitMQ, worker, and HTTP-style services receive different probe suggestions because their readiness signals differ.
- Check Coverage Mix Chart for a quick role-level view, then use JSON only after the table rows match the Compose file you intend to review.
Finish with the summary badge, the first missing or weak row in Healthcheck Coverage, and any Blocker or Race risk rows in Readiness Gate Ledger.
Interpreting Results:
The headline number counts required services whose healthcheck is missing, disabled, or invalid under the selected profile and scope. Weak rows are not counted as missing gaps, but they still deserve attention because timing notes can make a real service look flaky during cold starts or short outages.
Readiness blocker is more urgent than a general missing probe. It means another service is already relying on condition: service_healthy, so the dependency target needs a valid healthcheck before that readiness gate can be trusted. Race risk and Start-only point to dependencies that may start in order but still become usable later than the dependent service expects.
- Coverage percentage is based on required services only. Optional services can appear in the tables without lowering the percentage.
- Restart review means the checker did not find restart behavior for a required production service. It does not prove the service will fail; it marks recovery ownership as unclear.
- Probe Pattern Brief provides a starting command and baseline timing, not a verified command for your image. Make sure the binary exists inside the container and the endpoint or process check matches the service.
- Parser warnings in the JSON context should slow the review down, especially if the page had to fall back to an indentation scan with limited dependency detail.
Do not treat a clean chart as a substitute for running the stack. Use it to spot role-level coverage, then verify one or two important services with docker compose ps, health state, logs, and the dependent service behavior that motivated the healthcheck.
Worked Examples:
Orders stack with database and cache dependencies
The sample stack has api, worker, db, and redis. Under Production handoff, All runtime services, and Standard timing checks, api and db have covered healthchecks, while worker and redis are missing required probes. The summary shows 2 gaps, and Healthcheck Coverage gives each missing service an action.
The same sample also shows why dependency wording matters. worker waits for redis with condition: service_healthy, but redis has no healthcheck, so Readiness Gate Ledger reports a Blocker. api depends on redis with start-only behavior, so the ledger marks that edge as a start-order review rather than a ready-gated dependency.
CI gate focused on dependency targets
A pull request changes only service startup ordering, so Review scope is set to Readiness dependency targets. In that mode, services referenced by depends_on decide the required set. If db has a strong pg_isready healthcheck and redis has no probe, Healthcheck Coverage keeps the database covered and points the cache row toward a Redis PING probe. Services outside the dependency target set remain visible without becoming missing-healthcheck gaps.
Weak timing on a valid command
A PostgreSQL service may have a useful command such as pg_isready, but no explicit interval, timeout, or retries. Under Standard timing checks, the row becomes Weak rather than Covered. Switching to Strict startup timing checks can add a startup-grace note when start_period is missing, which is helpful for slower database initialization.
Malformed YAML before a review
If a pasted Compose file has broken indentation or an unclosed string, the alert shows Review Compose input with an invalid-YAML message. The result tables are not the right place to start in that state. Fix the YAML first, then confirm Healthcheck Coverage lists the expected service names before acting on any readiness or probe suggestions.
FAQ:
Does Compose wait for a service to be ready by default?
No. Short-form depends_on waits for dependency startup order, not application readiness. Use condition: service_healthy with a valid healthcheck when a dependent service must wait for real readiness.
Why is one missing healthcheck labeled optional?
The selected Audit profile and Review scope decide which service roles count as required. Job/helper services and services outside the current scope can stay visible without becoming gap counts.
Why did a service with a healthcheck show as weak?
The command exists, but timing review found missing or fragile settings such as no explicit interval, timeout, or retries, a timeout greater than or equal to the interval, retries below 2, or a timeout below 1 second.
What should I do when no services are found?
Check that the pasted YAML has a top-level services map and that service names are nested under it. The checker cannot audit healthchecks when it cannot identify Compose services.
Is the Compose content sent to a server for parsing?
No server-side parser is used by this checker. Pasted text and selected files are read in the browser, but sensitive Compose files should still be handled according to your workstation and repository policies.
Glossary:
- Healthcheck
- A service-level command that Docker uses to decide whether a running container is healthy.
service_healthy- A Compose dependency condition that waits for the dependency healthcheck to pass before starting the dependent service.
service_started- The start-only dependency condition used by short-form
depends_onand long-form dependencies without a healthier gate. start_period- A startup grace setting that gives slower services time before healthcheck failures count normally.
- Readiness blocker
- A dependency edge where
service_healthyis requested but the dependency lacks a valid healthcheck. - Restart policy
- Compose or deploy configuration that states how failed or stopped service containers should be restarted.
References:
- Define services in Docker Compose, Docker Docs.
- Control startup and shutdown order in Compose, Docker Docs.
- Start containers automatically, Docker Docs.