Chapter 13 • Multi-Container & Compose

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

CommandOperational BehaviorWhen to Use
docker compose up -dIdempotently creates/starts all missing or modified services in detached mode.Daily startup & continuous deployment.
docker compose up -d --buildForces image rebuilding prior to container recreation.After modifying local Dockerfile or source code.
docker compose downStops containers and removes private networks. Preserves persistent volumes.Standard graceful teardown.
docker compose down -vStops containers and permanently deletes all attached named volumes.Clean slate reset of local databases.
docker compose psLists 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=4
Port Conflict Rule: When scaling a service to multiple replicas, you cannot bind a static host port (e.g. ports: ["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 --build

Next 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 →

Explore Related Tools

Hand-picked utilities and calculators related to this tool.

Related Tools