How to Configure Docker Compose for Multi-Container Apps: A Practical Guide
Modern applications rarely run in a single container. A typical stack includes a web server, a backend API, a database, and perhaps a message queue. Docker Compose lets you define and run these multi-container setups with a single YAML file, making local development and testing far simpler.
At its core, a docker-compose.yml file orchestrates three key elements: services (your containers), networks (how they communicate), and volumes (persistent data storage). Here’s how to configure each for a robust multi-container application.
1. Declare Your Services Clearly
Each container is a service. Define its image, ports, and environment variables. For a simple web app with a database, your file starts like this:
services:
web:
build: .
ports: - "8080:80"
environment:
- DB_HOST=db
db:
image: postgres:16
environment:
- POSTGRES_PASSWORD=secret
2. Link Services with depends_on and Networks
Use depends_on to control startup order. By default, Compose creates a shared network, giving each service a DNS name matching its service name (e.g., db). For stricter isolation, define custom networks and attach services to them.
services:
web:
depends_on:
- db
networks: [frontend, backend]
db:
networks: [backend]
3. Persist Data with Named Volumes
Database data disappears if its container is removed. Use named volumes to keep data intact across restarts:
volumes:
dbdata:
services:
db:
volumes:
- dbdata:/var/lib/postgresql/data
4. Run and Manage the Stack
Use docker compose up -d to start everything in detached mode. Check logs with docker compose logs -f, stop with docker compose down, and remove everything (including volumes) with docker compose down -v.
With these configurations, you have a reproducible, scalable foundation for any multi-container project.