Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

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

Sponsored

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_on does 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 with healthcheck and condition: 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

  1. Declare dependencies in the depends_on key of the dependent service.
  2. Docker Compose reads all service definitions and builds a dependency graph.
  3. Start order is computed: Services with no dependencies start first, then those depending on them, and so on.
  4. 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_on with 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_on waits 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 run for a single service.
  • Not combining depends_on with health checks in production setups, leading to race conditions.

Variations

  1. Use condition: service_started (default) to wait only for the container to start.
  2. Use condition: service_healthy if you have defined a health check for the dependency.
  3. Use external wait scripts like wait-for-it.sh or dockerize for more complex readiness checks.

Real-world use cases

  • A web app that depends on a PostgreSQL database — depends_on: - db ensures the database container starts first.
  • A microservices orchestration where the API gateway depends on the auth service — depends_on guarantees auth is up before the gateway.
  • A data pipeline where an ETL job depends on a message queue (e.g., RabbitMQ) — depends_on ensures the queue is running before the job starts.

Key takeaways

  • depends_on in 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_on with 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-ports with all required services.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.