Docker Compose: Orchestrating Multi-Container Applications ๐งฉ
Source: Dev.to
What is Docker Compose? ๐ค
Docker Compose is a tool for defining and running multiโcontainer Docker applications. With a single YAML file and a few commands, you can configure all your applicationโs services and spin up the entire stack with one command.
Why Use Docker Compose?
- Simplicity โ Define your entire application stack in a single file.
- Reproducibility โ Everyone on your team gets the exact same environment.
- Service coordination โ Automatic networking between containers.
- Environment variables โ Easy configuration management.
- Oneโcommand operations โ Start, stop, and rebuild your entire application stack.
Writing docker-compose.yml Files
Basic Structure
version: '3'
services:
web:
image: nginx
ports:
- "80:80"
db:
image: postgres
environment:
POSTGRES_PASSWORD: example
- version: Specifies the Compose file format version.
- services: Defines the containers to be created.
- volumes (optional): Defines named volumes.
- networks (optional): Defines custom networks.
Defining Services
Each service represents a container. You can configure it in many ways:
services:
web:
image: nginx # Use an existing image
# OR
build: ./web # Build from a Dockerfile
build: # More build options
context: ./web
dockerfile: Dockerfile.dev
ports:
- "8080:80" # Port mapping
environment: # Environment variables
NODE_ENV: development
env_file: .env # Or use an env file
volumes: # Mount volumes
- ./web:/usr/share/nginx/html
depends_on: # Service dependencies
- api
restart: always # Restart policy
Managing Application Stacks
A Complete Example: Web App with Database and Cache
version: '3'
services:
web:
build: ./frontend
ports:
- "3000:3000"
volumes:
- ./frontend:/app
- /app/node_modules
environment:
- REACT_APP_API_URL=http://api:5000
depends_on:
- api
api:
build: ./backend
ports:
- "5000:5000"
volumes:
- ./backend:/app
- /app/node_modules
environment:
- DB_HOST=db
- REDIS_HOST=redis
depends_on:
- db
- redis
db:
image: postgres:13
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=secretpassword
- POSTGRES_USER=myuser
- POSTGRES_DB=myapp
redis:
image: redis:alpine
volumes:
- redis-data:/data
volumes:
postgres-data:
redis-data:
This setup includes:
- A React frontend
- A backend API
- A PostgreSQL database
- A Redis cache
- Persistent volumes for data
- Environment configuration
- Service dependencies
Environment Configuration
Inline in the Compose File
services:
web:
environment:
- NODE_ENV=development
- API_URL=http://api:5000
From a .env File
services:
web:
env_file:
- ./web.env
From the Shell Environment
services:
web:
environment:
- NODE_ENV
- API_KEY
For sensitive data, prefer using .env files that are gitโignored.
Compose Commands
Building and Running Services
# Start all services
docker-compose up
# Start in detached mode (background)
docker-compose up -d
# Build or rebuild services
docker-compose build
# Build and start
docker-compose up --build
# Stop services
docker-compose down
# Stop and remove volumes
docker-compose down -v
Viewing Logs and Status
# View logs of all services
docker-compose logs
# Follow logs of a specific service
docker-compose logs -f web
# See running services
docker-compose ps
Conclusion
Docker Compose has fundamentally changed how I develop and deploy multiโcontainer applications. What used to take dozens of commands and careful coordination can now be defined in a single file and launched with one command.
Key benefits:
- Development environments that perfectly match production
- Easy onboarding for new team members
- Consistent deployments across environments
- Simplified local development workflow
If youโre working with Docker and managing more than one container, Compose should definitely be part of your toolkit.
Next up: โDocker in Production: From Development to Deploymentโ