Docker Compose CLI Operations & Workflows
Controlling a multi-container microservices application requires a firm command over theDocker Compose CLI. In this guide, explore idempotent deployments, log isolation, the subtle difference between exec and run, horizontal replica scaling, and multi-file environment layering.
1. Everyday Stack Operations Reference
| Command | Operational Behavior | When to Use |
|---|---|---|
docker compose up -d | Idempotently creates/starts all missing or modified services in detached mode. | Daily startup & continuous deployment. |
docker compose up -d --build | Forces image rebuilding prior to container recreation. | After modifying local Dockerfile or source code. |
docker compose down | Stops containers and removes private networks. Preserves persistent volumes. | Standard graceful teardown. |
docker compose down -v | Stops containers and permanently deletes all attached named volumes. | Clean slate reset of local databases. |
docker compose ps | Lists status, port mappings, and health states across the current project stack. | Health auditing and verification. |
docker compose logs -f <svc> | Streams stdout/stderr logs from a specific service container in real-time. | Debugging API crashes and exceptions. |
2. Critical Distinction: exec vs run
DevOps engineers frequently confuse these two commands, leading to unexpected behaviors:
docker compose exec
Executes a command inside an already existing, currently running service container. Does not allocate new network endpoints or duplicate memory.
# Open bash shell in live running API: docker compose exec api sh # Run live database query: docker compose exec db psql -U app_user -d app_db
docker compose run
Spawns a brand new, isolated, one-off container using the service's image and network. Ideal for tasks that should run in isolation without interfering with active services.
# Run DB migrations in ephemeral container: docker compose run --rm api npm run db:migrate # Generate temporary seed data: docker compose run --rm api python seed.py
3. Horizontal Service Scaling (--scale)
You can scale stateless application services to multiple concurrent replica instances to handle surge traffic:
# Scale the API service to 4 running container replicas:
docker compose up -d --scale api=4ports: ["5000:5000"]), because only one container can bind to host port 5000 at a time! Instead, use expose: ["5000"] and place an Nginx or Traefik reverse proxy in front to distribute incoming traffic.4. Multi-File Overrides for Dev vs Production
Compose supports layering multiple configuration files to share common base configurations while overriding environment-specific settings without duplicating YAML:
# 1. Base Configuration: compose.yaml
# 2. Production Overrides: compose.prod.yaml (removes volume bind-mounts, enables restart policies)
# 3. Development Overrides: compose.override.yaml (automatically loaded by default in local dev)
# Deploy to production by specifying layered compose files:
docker compose -f compose.yaml -f compose.prod.yaml up -d --buildNext Up: Multi-Stage Image Builds
In Chapter 14, discover how to reduce production container image sizes from 1.2 GB down to 25 MB using multi-stage builds.
Chapter 14: Multi-Stage Image Builds →