Skip to content

Multi-Container Orchestration with Docker Compose

summary

Docker Compose is a tool for defining and running multi-container applications. Instead of managing individual containers via complex CLI commands, Compose allows you to use a declarative YAML file to manage your entire application stack as a single unit.


1. Concepts and Evolution

The Journey from Fig to Compose

Originally, a tool called Fig (developed by Orchard Labs) revolutionized Docker by allowing users to define multi-container microservices in a simple YAML file. Docker, Inc. acquired Orchard Labs and rebranded Fig as Docker Compose.

Today, Compose is driven by the Compose Specification, an open community-led standard. While Docker Compose is the reference implementation, the specification ensures consistent governance across different platforms.

Why Use Compose?

While primarily used for development, testing, and CI/CD environments, Compose introduces concepts that are foundational for the CKAD (Certified Kubernetes Application Developer) exam:

  • Self-healing & Scaling: Provides a simplified view of how microservices benefit from these patterns.
  • Service Discovery: Allowing containers to communicate via service names rather than IP addresses.
  • Declarative Configuration: Defining the "desired state" of your infrastructure in code.
  • Resource Isolation: Automatic creation of dedicated networks and volumes.

2. Architecture of a Compose App

When you deploy an application, Docker Compose parses your YAML file and orchestrates the creation of several objects: Services, Networks, and Volumes .etc

Resource Naming Conventions

Docker assigns a Project Name based on the directory name of your build context. It then names resources using the pattern: [project-name]-[service-name]-[index].

Resource Type Internal Name Example
Service multi-container-web-fe-1
Network multi-container_counter-net
Volume multi-container_counter-vol

It names resources using a predictable pattern to avoid conflicts.


3. The Compose File (compose.yaml)

Compose looks for a file named compose.yaml or compose.yml by default.

Standard Filenames

Modern Docker standards prefer compose.yaml. If you use a custom name like prod.yaml, you must specify it using the -f flag: docker compose -f prod.yaml up.

Sample Application Configuration

The following example defines a web frontend and a Redis backend.

services:
  web-fe:
    deploy:
      replicas: 1
    build: .
    command: python app.py
    ports:
      - target: 8080
        published: 5001
    networks:
      - counter-net

  redis:
    deploy:
      replicas: 1
    image: "redis:alpine"
    networks:
      - counter-net
    volumes:
      - type: volume
        source: counter-vol
        target: /data

networks:
  counter-net:

volumes:
  counter-vol:
graph TD
    subgraph "Docker Host"
    A[Compose Project] --> B(Service: web-fe)
    A --> C(Service: redis)
    B --- D((Network: counter-net))
    C --- D
    C --- E[[Volume: counter-vol]]
    end

    User((User)) -->|Port 5001| B

Key Directives Explained

  • services: The mandatory top-level key defining the application components.
  • build: .: Directs Docker to build an image from the Dockerfile in the current directory.
  • image: Specifies an existing image to pull (e.g., from Docker Hub).
  • ports: Maps the container port (target) to the host port (published).
  • command: The execution instruction.
  • networks: Connects containers to a shared network. This enables Service Discovery, allowing web-fe to reach redis simply by using the hostname redis.
  • volumes: Mounts a persistent volume. This ensures data is not lost if the container is stopped or deleted.
  • deploy.replicas : Defines the number of containers.

On Docker Desktop, you can usually only run 1 replica for services that bind to a specific host port (e.g., 5001), as multiple containers cannot bind to the same host port simultaneously.

4. Operational Lifecycle

Deployment and Management

The up command is the primary way to deploy. It builds images, creates networks/volumes, and starts containers.

    # Start in the background (detached mode) 
    docker compose up -d 

Check the health and processes of your multi-container stack.

# List container status, ports, and state
docker compose ps
# List processes running inside each container (Host PIDs)
docker compose top

Process IDs (PID)

The PID numbers returned by docker compose top are the PIDs as seen from the Docker Host, not from within the container's isolated namespace.

Stop the app without deleting resources, or perform a restart.

# Stop containers (preserves container state)
docker compose stop
# Restart stopped containers
docker compose restart

Restart Limitation

docker compose restart does not pick up changes made to the compose.yaml file. To apply configuration changes, you must run docker compose up again (which performs a recreation of affected services).

5. Teardown and Cleanup

Stops and removes containers and networks.

docker compose down 

Persistence of Volumes

By default, docker compose down does not delete volumes. This is a safety feature to prevent accidental data loss. You must explicitly use the --volumes (or -v) flag to remove them.

Removes volumes and images along with containers. Use this to ensure a completely clean slate.

docker compose down --volumes --rmi all 

6. CKAD Bridge: From Compose to Kubernetes

For those transitioning to Kubernetes, use the following mental model to map Compose concepts to K8s objects:

Docker Compose Kubernetes Equivalent
service Deployment (controls Pods/Replicas)
network Service (DNS/ClusterIP)
volume PersistentVolumeClaim (PVC)
image Container image inside a Pod
compose.yaml Kubernetes manifests (multiple YAML files or Helm Charts)

7. Command Summary Reference

Command Description
docker compose up -d Deploy the application stack in detached mode
docker compose ps View the status of containers in the current Compose project
docker compose top View host-level process IDs for each service
docker compose logs -f Tail and follow logs for all services in the stack
docker compose stop Stop services without removing containers or networks
docker compose down Stop and remove containers, networks, and related resources
docker compose ls List all running Docker Compose projects on the host

Comments