Working with Docker Compose
1. Creating docker-compose.yml File
The docker-compose.yml file is the configuration file for Docker Compose. It defines services, networks, and volumes for your application.
| Field | Description | Example |
|---|---|---|
| version | Specifies the Compose file format version. | "3.8" |
| services | Defines the containers to be created. | |
| image | Specifies the Docker image to use for a service. | nginx:latest |
| ports | Maps host ports to container ports. | - "80:80" |
| volumes | Mounts directories or files into the container. | - "./app:/app" |
| environment | Sets environment variables for the container. | - NODE_ENV=production |
Example: Basic docker-compose.yml
version: '3.8'
services:
web:
image: nginx
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
2. Defining Services (services:)
| Property | Description | Example |
|---|---|---|
| services.name | Unique name for the service | web |
| services.image | Base image to use for the service | nginx:latest |
| services.build | Build context for custom image | . |
| services.ports | Port mappings to expose | 80:80 |
| services.volumes | Mount volumes from host or named volumes | ./app:/app |
| services.environment | Environment variables to set | ENV=prod |
| services.depends_on | Service dependencies to start before this one | db |
| services.restart | Restart policy for the container | unless-stopped |
Example: Basic service definition
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./app:/app
Example: Service with environment and dependencies
services:
web:
image: node:18
depends_on:
- db
environment:
- NODE_ENV=production
- DB_HOST=db
3. Validating Compose File
| Command | Description | Notes |
|---|---|---|
| docker compose config | Validate and view the Compose file | Displays the parsed configuration or errors |
| docker compose config --quiet | Validate without outputting the config | Exits with code 0 if valid, 1 if invalid |
| docker compose config --log-level | Set log level for validation | Useful for debugging validation issues |
Note: The
--quiet flag is useful in CI/CD pipelines to check validity without printing the full config.
Warning: The
docker compose config command requires a valid Compose file in the current directory or specified with -f.
4. Building Services
| Property | Description | Example |
|---|---|---|
| build | Path to Dockerfile or build context | build: . |
| context | Build context directory | build: { context: ./app } |
| dockerfile | Custom Dockerfile name/path | build: { dockerfile: Dockerfile.prod } |
| args | Build arguments to pass | build: { args: { NODE_ENV: production } } |
| target | Multi-stage build target stage | build: { target: production } |
Example: Building a Node.js Service
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
- NODE_ENV=production
Note: The
build property supports both a string (for context path) and an object for more detailed configuration.
5. Starting Services
Example: Starting Services with Docker Compose
version: '3.8'
services:
web:
image: nginx
ports:
- "80:80"
db:
image: postgres
environment:
POSTGRES_PASSWORD: password
| Command | Description | Options |
|---|---|---|
| docker compose up | Starts all services defined in the Compose file | -d to run in detached mode |
| docker compose up <service> | Starts a specific service | -d to run in detached mode |
| docker compose up -d | Starts all services in detached mode (background) |
Note: By default,
docker compose up will build any images defined in the Compose file that are not already present.
Workflow: Starting Services in Docker Compose
- Ensure
docker-compose.ymlis present in the project directory - Run
docker compose upto start all services - Use
docker compose up -dto run in detached mode (background) - Use
docker compose up <service>to start a specific service
6. Stopping Services
| Command | Description | Options |
|---|---|---|
| docker compose stop | Stops running containers defined in the Compose file | -t, --timeout - Specify timeout in seconds (default 10) |
| docker compose stop <service> | Stops a specific service container | -t, --timeout - Specify timeout in seconds (default 10) |
Note: This command sends a
SIGTERM signal to the containers, allowing them to shut down gracefully. If the containers do not stop within the timeout period, a SIGKILL signal is sent.
7. Viewing Service Logs
| Command | Description | Options |
|---|---|---|
| docker compose logs | View logs for all services in the Compose file | -f to follow logs, --since to filter by time |
| docker compose logs <service> | View logs for a specific service | -f, --tail, --since |
Note: Logs are streamed from the container's stdout and stderr. Ensure services are running before viewing logs.
8. Executing Commands in Services
| Command | Description | Example |
|---|---|---|
| docker compose exec | Execute a command in a running service container | docker compose exec web ls -l |
| docker compose run | Run a one-time command in a new container based on the service's image | docker compose run web bash |
Note: The
exec command runs inside the existing container, while run creates a new one.
9. Scaling Services
| Service | Scale Command | Description |
|---|---|---|
| web | docker-compose up --scale web=3 |
Scales the web service to 3 containers |
| database | docker-compose up --scale database=2 |
Scales the database service to 2 containers |
Note: Scaling is managed by the Docker Compose file's service definitions and requires a compatible Docker Compose version.
10. Using Environment Files
| File Type | Description | Usage |
|---|---|---|
| .env | Default environment file for Docker Compose | docker-compose up automatically loads this file |
| .env.local | Local environment overrides (not committed to version control) | Loaded after .env if present |
| .env.<environment> | Environment-specific files (e.g., .env.production) |
Can be specified with --env-file flag |
Example: Environment file usage
version: '3.8'
services:
web:
image: nginx
env_file:
- .env
- .env.local
Note: Variables in environment files are not automatically available to the Docker daemon or CLI tools outside of Compose. They must be explicitly referenced in service definitions.
Example: Using environment variables in Compose
version: '3.8'
services:
database:
image: postgres
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USER}
env_file:
- .env
Warning: Never commit sensitive values like passwords or API keys to version control. Use
.env.local or .env.<environment> files that are ignored by Git.
Best Practices for Environment Files
- Use
.envfor default values shared across environments - Use
.env.localfor local overrides (e.g., personal dev settings) - Use
.env.<environment>for environment-specific configurations (e.g., production, staging) - Ensure all required variables are defined in the environment files
- Use
env_filedirective to load multiple files in order of precedence
11. Defining Dependencies
| Service | Dependencies | Description |
|---|---|---|
| depends_on | service_name |
Defines the order of service startup and shutdown. Ensures a service starts only after its dependencies are up. |
| links | service_name:alias |
Allows one service to access another by an alias. Deprecated in favor of depends_on and networks. |
| networks | network_name |
Specifies the networks a service should connect to. Services can communicate over these networks. |
Example: Using depends_on
services:
web:
image: nginx
depends_on:
- db
- redis
db:
image: postgres
redis:
image: redis
Note:
depends_on ensures services start in order but does not wait for the service to be ready or healthy. Use healthcheck for readiness checks.
12. Overriding Compose Files
| File | Override Syntax | Description |
|---|---|---|
| docker-compose.override.yml | extends: |
Extends base compose file with additional services or overrides |
| docker-compose.yml | extends: |
Main compose file defining base services and configuration |