depends_on Start Order
Use depends_on to control container start order in Docker Compose — a hands-on lesson for progressive mastery.
Focus: use depends_on to control start order
When your application depends on a database, cache, or queue, you can't just start everything at once — the dependent service might crash if the required service isn't ready. Docker Compose's depends_on option solves this by letting you control the startup order of containers, ensuring that dependencies are started before their dependents.
The problem this lesson solves
Without startup order control, a web application may fail to connect to a database that hasn't finished initializing. This leads to connection errors, retries, or even a crash loop. depends_on provides a declarative way to express these dependencies in your docker-compose.yml, so Compose starts containers in the correct order.
Core concept / mental model
Think of depends_on like a job scheduler — a task only starts after its prerequisite tasks complete. In a multi-container app, a web server depends on a database; the database must be up and running before the web server tries to connect. depends_on defines that relationship, so Compose launches containers in the right sequence.
Pro tip:
depends_ondoes not wait for the service to be "healthy" or ready to accept connections — it only waits for the container to start. For readiness checks, combine it withhealthcheckandcondition: service_healthy.
Definitions
- Dependency: A service that must start before another service.
- Dependent: A service that relies on a dependency.
- Start order: The sequence in which containers are launched by Docker Compose.
How it works step by step
- Declare dependencies in the
depends_onkey of the dependent service. - Docker Compose reads all service definitions and builds a dependency graph.
- Start order is computed: Services with no dependencies start first, then those depending on them, and so on.
- Containers start in that order. If a dependency fails to start, the dependent will not start.
Example dependency graph
services:
db:
image: postgres:15
web:
build: .
depends_on:
- db
Here, db starts first, then web. If db fails to start, web is never launched.
Hands-on walkthrough
Let's build a simple two-service app: a web server that depends on a Redis cache.
1. Project structure
myapp/
├── docker-compose.yml
└── app.py
2. Application file (app.py)
import redis
import time
r = redis.Redis(host='redis', port=6379)
# Wait for Redis to be fully ready
time.sleep(2)
r.set('key', 'Hello from Python!')
print(r.get('key').decode())
3. Docker Compose file (docker-compose.yml)
version: '3.8'
services:
redis:
image: redis:7-alpine
app:
build: .
depends_on:
- redis
4. Dockerfile
FROM python:3.10-slim
RUN pip install redis
COPY app.py .
CMD ["python", "app.py"]
5. Run the stack
$ docker-compose up --build
Expected output:
Creating myapp_redis_1 ... done
Creating myapp_app_1 ... done
Attaching to myapp_redis_1, myapp_app_1
redis_1 | 1:C 10 Jan 2023 12:00:00.000 # oO0OoO0OoO0Oo ...
app_1 | Hello from Python!
The app container starts only after redis has started, so the connection succeeds.
Compare options / when to choose what
| Feature | depends_on |
healthcheck + depends_on |
External wait script (e.g., wait-for-it.sh) |
|---|---|---|---|
| Starts order | Yes | Yes | Yes |
| Waits for readiness | No | Yes (with condition: service_healthy) |
Yes (e.g., polls TCP port) |
| Built-in | Yes | Yes (requires health check) | No (external tool) |
| Complexity | Low | Medium | Higher |
| Use case | Simple ordering | Production-grade dependency | Legacy or custom checks |
Pro tip: For production, always combine
depends_onwith a health check to ensure the service is actually ready, not just started.
Troubleshooting & edge cases
Error: depends_on does not prevent race conditions
If your web app starts before the database is ready to accept connections, you'll get connection refused errors. depends_on only guarantees container start order, not service readiness.
Fix: Add a retry mechanism in your app, or use condition: service_healthy.
Circular dependencies
Compose will refuse to start if you create a circular dependency (e.g., A depends on B, B depends on A).
Fix: Refactor your services to remove the cycle; consider using an async pattern or a broker.
depends_on with docker-compose run
When running a single service with docker-compose run, dependencies are not automatically started. Use --service-ports or start dependencies manually.
Fix: Run docker-compose up -d redis before docker-compose run app.
What you learned & what's next
You learned how to use depends_on to control container startup order in Docker Compose. You now understand that it ensures dependencies start first but does not guarantee service readiness. For production, you should combine it with health checks.
Next step: Learn how to use healthcheck in Docker Compose to verify that a service is actually healthy before starting its dependents. This is covered in the next lesson: "Use health checks to verify service readiness".
Practice recap
Create a multi-service app: a Flask web server that depends on a PostgreSQL database. In your docker-compose.yml, add a depends_on entry for the database. Then run docker-compose up and verify the web server starts after the database. Add a health check to the database and change the condition to service_healthy. Re-run and observe the difference in startup behavior.
Common mistakes
- Assuming
depends_onwaits for the service to be ready to accept connections — it only waits for the container to start. - Creating circular dependencies between services, which causes Compose to refuse to start.
- Forgetting to start dependencies when using
docker-compose runfor a single service. - Not combining
depends_onwith health checks in production setups, leading to race conditions.
Variations
- Use
condition: service_started(default) to wait only for the container to start. - Use
condition: service_healthyif you have defined a health check for the dependency. - Use external wait scripts like
wait-for-it.shordockerizefor more complex readiness checks.
Real-world use cases
- A web app that depends on a PostgreSQL database —
depends_on: - dbensures the database container starts first. - A microservices orchestration where the API gateway depends on the auth service —
depends_onguarantees auth is up before the gateway. - A data pipeline where an ETL job depends on a message queue (e.g., RabbitMQ) —
depends_onensures the queue is running before the job starts.
Key takeaways
depends_onin Docker Compose controls the order in which containers start, based on declared dependencies.- It does not wait for the service to be ready — only for the container to start.
- Always combine
depends_onwith health checks (condition: service_healthy) in production for reliable startup. - Circular dependencies are not allowed; refactor your services if you hit one.
- When using
docker-compose run, start dependencies manually or use--service-portswith all required services.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.