Dev Encyclopedia
ArticlesToolsContactAbout

Get notified when new content drops

No spam. Just new articles, tools, and updates straight to your inbox.

Dev Encyclopedia

A reference for builders

Content

  • Articles
  • Tools
  • About
  • Contact

Connect

  • support@devencyclopedia.com
  • RSS Feed

Legal

  • Privacy Policy
  • Terms of Service
  • Disclaimer

© 2026 Dev Encyclopedia

Back to top ↑
  1. Home
  2. /
  3. Tools
  4. /
  5. ComposeHealthCheck
Free · Live100% Client-Side

Your App Started Before the Database Was Ready. Here's Why.

Paste your docker-compose.yml and see exactly which services are missing the healthcheck config that would have caught this. Takes five seconds, runs entirely in your browser.

Zeeshan Tofiq

Zeeshan Tofiq

Full Stack Developer

How ComposeHealthCheck works

1

Paste your compose file

Copy the contents of your docker-compose.yml (or compose.yaml) and paste it into the input area. Any file with a top-level services key is accepted.

2

YAML is parsed locally

The file is parsed entirely in your browser with a bundled YAML parser. Each service is extracted with its image, depends_on entries, and healthcheck block.

3

The dependency graph is built

Every depends_on relationship becomes an edge in a graph: which service waits on which, and under what condition (service_started, service_healthy, or service_completed_successfully).

4

depends_on and healthcheck rules are checked

Each service is checked against known gotchas: a depends_on with no condition pointing at a service that has a healthcheck, a healthcheck test using curl or wget, missing timeout or retries, and start_period present (flagged as informational, since it's a grace period, not a delay).

5

The whole graph is checked for cycles

A depth-first search walks the entire depends_on graph looking for a service that, through some chain, ends up depending on itself. If found, the exact cycle is shown (A → B → C → A) instead of a generic error.

6

Results with a visual startup graph

Each service gets a severity rating (Critical, Warning, Info, or Clean) with specific findings and a plain-English fix, alongside a diagram showing the full startup order at a glance.

What the results mean

Critical

The service is part of a circular dependency. Compose cannot compute a valid startup order for services that wait on each other, directly or through a chain, and will error at startup.

When it triggers: When a depth-first walk of the entire depends_on graph finds a service that eventually depends back on itself.
Example: worker depends_on queue, and queue depends_on worker. Neither can be first.
Warning

A depends_on or healthcheck configuration issue that will likely cause a real startup-order or false-unhealthy bug, but doesn't stop Compose from starting.

When it triggers: When depends_on has no condition specified and the target has a healthcheck, when a healthcheck test calls curl or wget, or when timeout or retries are left unset.
Example: api depends_on: [db] in short form, while db defines a healthcheck. api probably meant condition: service_healthy.
Info

Not a bug, a reminder about a commonly misunderstood field. Worth reading once, then safe to ignore if you already account for it.

When it triggers: When a healthcheck defines start_period, which is frequently misread as a startup delay rather than a grace period for failures.
Example: start_period: 15s means failures in the first 15 seconds don't count against retries. It doesn't delay when checks begin.
Clean

No issues detected for this service. Its depends_on conditions match what its targets actually support, and its healthcheck (if any) is fully specified.

When it triggers: When every depends_on entry either has no matching healthcheck to wait for, or explicitly uses the right condition, and any healthcheck defines its own timeout and retries.
Example: db defines a healthcheck with interval, timeout, and retries all set, and nothing depends on it without specifying condition: service_healthy.

depends_on and healthcheck syntax reference

ComposeHealthCheck understands both the short and long forms of depends_on, and every field in a healthcheck block.

depends_on — short form (list)

services:
  api:
    depends_on:
      - db
      - redis

depends_on — long form (with condition)

services:
  api:
    depends_on:
      db:
        condition: service_healthy
      migrator:
        condition: service_completed_successfully

healthcheck — full field reference

services:
  db:
    image: postgres:16-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s      # time between checks
      timeout: 5s       # how long one check may take
      retries: 5        # consecutive failures before "unhealthy"
      start_period: 10s # grace period; failures here don't count
      disable: false

test accepts a CMD array (exec form, no shell), a CMD-SHELL array (runs through /bin/sh -c), or a plain string (treated the same as CMD-SHELL). All three parse identically for the checks on this page.

When to use ComposeHealthCheck

ScenarioWhat to paste
Right before running docker compose up on a new file for the first timeYour full docker-compose.yml before you ever run it
App keeps getting "connection refused" against the database on startupThe compose file, to check whether depends_on is actually waiting for the database's healthcheck
A healthcheck reports unhealthy but the app logs look fineThe service's healthcheck block, to check whether it calls a binary that might not be in the image
Compose fails at startup with a dependency-related errorThe full file, to get the exact circular dependency chain instead of a generic error
Reviewing a teammate's or a tutorial's compose file before adopting itTheir shared docker-compose.yml, to sanity-check startup ordering before you copy it
Adding a new service with a dependency to an existing, working compose fileThe updated file, to confirm the new depends_on entry doesn't introduce a cycle

Frequently Asked Questions

What is ComposeHealthCheck and what does it check?

ComposeHealthCheck is a browser-based tool that reads your docker-compose.yml and checks the startup-order logic that the official schema validator doesn't cover. It flags depends_on entries that are missing condition: service_healthy on a target that actually has a healthcheck, healthcheck commands that call curl or wget without confirming those binaries exist in the image, missing timeout or retries fields, and circular dependency chains across the whole depends_on graph.

Everything runs entirely in your browser using a YAML parser bundled with the page. No data is sent to any server.

How is this different from docker compose config?
ComposeHealthCheckdocker compose config
Checks YAML syntaxYesYes
Checks schema validityPartialYes (authoritative)
Flags missing service_healthyYesNo
Detects circular dependencies with the actual cycle shownYesGeneric error only
Warns about curl/wget in minimal imagesYesNo
Requires Docker installedNo (browser only)Yes

docker compose config is the authoritative source for whether your YAML is structurally valid. ComposeHealthCheck is a complement, not a replacement: it looks for logical mistakes in depends_on and healthcheck configuration that a schema validator has no reason to flag, because they're all valid YAML, just not what you probably meant.

Is my compose file sent anywhere?

No. ComposeHealthCheck runs 100% client-side in your browser. The YAML you paste is parsed locally with JavaScript, and every check runs against that local, in-memory result. No network requests are made, and no data leaves your browser, so it's safe to paste a file with real service names, ports, and internal hostnames.

Why doesn't depends_on wait for my database to actually be ready?

By default, depends_on only waits for the target container to be in a running state, not for the process inside it to be ready to accept connections. Postgres, for example, reports as running well before it finishes initialization. To make a dependent service wait for actual readiness, add a healthcheck to the target and reference it with condition: service_healthy.

yaml
services:
  db:
    image: postgres:16-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  api:
    image: my-app
    depends_on:
      db:
        condition: service_healthy

💡 Tip

The short-form list syntax (depends_on: [db]) always uses condition: service_started under the hood. If db has a healthcheck, you almost always want the long form with condition: service_healthy instead.

What's the difference between service_started and service_healthy?
  • <strong>service_started</strong> (the default) — waits only until the target container's process has started. Says nothing about whether the app inside is ready to do anything.
  • <strong>service_healthy</strong> — waits until the target's healthcheck reports healthy. Requires the target to actually define a healthcheck block; if it doesn't, this condition can never be satisfied and Compose will error on startup.
  • <strong>service_completed_successfully</strong> — waits until the target container runs to completion and exits with code 0. Used for one-off init or migration containers, not long-running services.
Why does my healthcheck fail with "executable file not found"?

This almost always means your healthcheck's test command calls a binary, commonly curl or wget, that isn't installed in the image. Minimal base images (alpine, slim, distroless) frequently ship without either. Docker runs the healthcheck test inside the container itself, so if the binary isn't there, the command fails immediately and the container is reported unhealthy, even if the application inside is working perfectly.

dockerfile
# Alpine images usually need curl installed explicitly
RUN apk add --no-cache curl

Alternatively, use a binary you already know is present, such as a small script bundled with your app, or your language runtime's own HTTP client (node -e "..." or python3 -c "...") instead of adding a new package just for the healthcheck.

How do I fix a circular dependency error?

A circular dependency means two or more services depend on each other, directly or through a chain, so Compose has no valid order to start them in. ComposeHealthCheck shows you the exact chain (for example, worker → queue → worker) instead of Compose's generic error.

  • <strong>Remove one direction of the dependency</strong> if only one service genuinely needs to wait for the other at startup.
  • <strong>Introduce a third, lower-level service</strong> (like a shared queue or database) that both depend on instead of depending on each other directly.
  • <strong>Handle the dependency in application code</strong> with a retry/backoff loop instead of a startup-order guarantee, if the two services are meant to be mutually communicating peers rather than strictly ordered.

Related reading

Article

Cloud & DevOps Interview Questions

Container orchestration, deployment pipelines, and infrastructure questions that come up when discussing setups like this one.

Article

Kubernetes Interview Questions

Startup ordering and readiness checks are a Compose-specific version of a problem Kubernetes solves with liveness and readiness probes.

Zeeshan Tofiq

Zeeshan Tofiq

Full Stack Developer

Full stack developer with over 6 years of experience building production applications. Writes practical guides on JavaScript, TypeScript, React, Node.js, and cloud infrastructure. Focused on helping developers solve real problems with clean, maintainable code.

Enjoyed this article?

Get practical dev guides, tool updates, and new articles delivered straight to your inbox. No spam, unsubscribe anytime.

Works with any compose file that has a top-level services key.

100% client-side. Your compose file never leaves your browser. No data is sent to any server.