Defining Service Relationships in Docker Compose
Learn how to define service dependencies in Docker Compose. Master the `depends_on` directive to control startup order and link services in your infrastructure.

Previously in this course, we covered managing container states and mapping host ports to expose individual services. Now that you can run single containers reliably, it’s time to move toward orchestration.
In a real-world application, your web service rarely lives in a vacuum. It usually needs a database, a cache, or an API gateway. When you start these components together, you need a way to tell Docker which services must exist before others, ensuring your application doesn't crash because a dependency wasn't ready.
The Role of Orchestration
When we talk about orchestration in the context of Docker Compose, we mean managing the lifecycle of multiple containers as a single unit. Without explicit instructions, Docker Compose starts containers in parallel, which is fast but dangerous if your web app attempts to connect to a database that hasn't finished booting yet.
Defining Dependencies with depends_on
The depends_on key in your docker-compose.yml file is the primary tool for defining service relationships. It dictates the order of operations: Docker will ensure the "dependency" service is started before the dependent service.
Here is a basic structure for a two-service stack:
YAMLversion: '3.8' services: web: build: . ports: - "8080:80" depends_on: - db db: image: postgres:15
In this example, Docker guarantees that the db container starts before the web container.
Important Nuance: The "Ready" State

A common pitfall for beginners is assuming that depends_on means the database is ready to accept connections. It only means the database container's process has started.
If your web application needs to perform a migration or query the database the moment it boots, it will likely fail because the database might still be initializing its internal storage. This is why we use debugging docker compose healthcheck to ensure the service is actually "healthy" before proceeding.
Worked Example: Linking Services
Let's evolve our project. Assume we have a web application that needs to talk to a Redis cache. We will create a docker-compose.yml that defines this relationship.
YAMLservices: app: build: ./app depends_on: - redis environment: - REDIS_HOST=redis redis: image: redis:alpine
By defining the redis service, Docker Compose automatically creates a shared network. The app container can reach the redis container simply by using the service name redis as the hostname. You don't need IP addresses; Docker's internal DNS handles the resolution for you.
Hands-on Exercise
- Create a
docker-compose.ymlfile in your project directory. - Define two services:
frontend(use a simple Nginx image) andbackend(use a generic Python or Node image). - Add a
depends_onblock to thefrontendservice so it waits for thebackend. - Run
docker compose upand observe the output logs to confirm thebackendstarts first.
Common Pitfalls
- Assuming Readiness: As noted,
depends_ondoes not wait for an application to be "ready" (e.g., ports open, data loaded), only for the container to start. - Cyclic Dependencies: If service A depends on B, and B depends on A, Compose will fail to start. Keep your dependency graph linear or tree-structured.
- Ignoring Service Names: If you change a service name in
docker-compose.yml, you must update all environment variables and code references that point to that service, as the internal DNS name changes with it.
FAQ
Does depends_on work with docker run?
No, depends_on is a feature specific to Docker Compose and the orchestration layer. It has no effect if you start containers manually using the docker run command.
What happens if a dependency fails to start?
If the dependency (the db container) crashes immediately, the dependent container (web) will still try to start unless you explicitly implement health checks.
Can I chain dependencies? Yes. You can have Service C depend on B, and B depend on A. Compose will start them in the order A -> B -> C.
Recap
You’ve learned that orchestration is about managing the relationship between containers. By using depends_on, you control the startup order, and by relying on Docker’s internal DNS, you create stable communication channels between your services. Remember that depends_on is only the first step in creating a robust architecture; managing real "readiness" usually requires debugging docker compose service dependency failures through health checks.
Up next: We will connect our web application to a database and inject the connection strings using environment variables.
Work with me

CI/CD Pipeline & Docker Containerization
Ship with confidence: automated CI/CD pipelines and Docker setups so every push is tested and deployed — no more manual, error-prone releases.

VPS Server Setup, Deployment & Hardening
Get your app live on a fast, secure server — properly configured, hardened, and deployment-ready. No more wrestling with the command line.

