docker-compose kafka wait for zookeeper and schema-registry wait for kafka
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Docker Compose, depends_on controls start order, but it does not guarantee that a service is actually ready to accept connections. For Kafka stacks, that distinction matters because Kafka may start before ZooKeeper is usable, and Schema Registry may start before Kafka is ready to serve broker requests.
Know What depends_on Does and Does Not Do
A Compose dependency ensures one container is started before another. It does not mean the dependent service has finished initializing its network listener, internal metadata, or health state.
That is why a simple Compose file can still fail even when the services appear in the “correct” order.
This starts the containers in order, but it does not prove readiness.
Add Health Checks for Real Readiness Gates
A stronger approach is to give ZooKeeper and Kafka health checks, then gate dependents on those checks when your Compose version supports health-based conditions.
This makes the dependency meaningful instead of just chronological.
Make Schema Registry Wait for Kafka Readiness
Schema Registry needs Kafka to be reachable, not merely started. The same pattern applies.
If health-based depends_on is unavailable in your environment, use a wait script in the entrypoint instead.
Use Wait Scripts When Health Conditions Are Not Enough
A small shell wrapper can block startup until the upstream service really answers.
This pattern is especially useful when the image already has a standard run script and you only need to gate it.
Remember That “Port Open” Is Not Always “Service Ready”
A service can bind a port before it is actually usable. Kafka is a good example because metadata and broker state may still be settling. A broker-specific health command is usually better than only checking whether the TCP port is open.
Use the most service-aware readiness probe you can reasonably maintain.
Keep the Compose File Honest
The cleanest Compose setup reflects operational dependencies directly:
- ZooKeeper becomes healthy first.
- Kafka waits for healthy ZooKeeper.
- Schema Registry waits for healthy Kafka.
That model is easier to debug than a pile of unexplained sleeps in entrypoint scripts.
Common Pitfalls
- Assuming
depends_onalone guarantees service readiness. - Checking only whether a port is open when the application behind it is still initializing.
- Letting Schema Registry start against Kafka before broker metadata is usable.
- Adding fixed sleep delays instead of real readiness checks.
- Forgetting that Compose feature support can vary by version and execution environment.
Summary
- '
depends_oncontrols start order, not application readiness.' - Add health checks so Kafka can really wait for ZooKeeper and Schema Registry can really wait for Kafka.
- Use wait scripts when Compose health conditions are not available or sufficient.
- Prefer service-aware checks over simple TCP port checks.
- Model dependencies explicitly so the stack behaves predictably during startup.

