Docker Compose Overview

Docker compose is a tool for defining and running multi-container applications. It simplifies the control of the entire application stack, making it easy to manage services, networks, and volumes in a single YAML configuration file. After the file is defined, a single command will start all the services specified in the configuration file. The compose file has the ability to

Why use Compose?

Key Benefits of Docker Compose

Common use cases of Docker Compose

Development Environments

Automated Testing Environments

$ docker compose up -d
$ ./run_tests
$ docker compose down

How Compose Works

The Compose Application Model

Components of a compose are defined as services. A service is an abstract concept that is "instantiated" by creating running a docker image with a specified configuration.

These services communicate with each other through networks. A network is a platform capability abstraction to establish an IP route between containers within services. By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by the service's name.

Services store and share persistent data in volumes. The Specification describes such data as high-level filesystem mounts with global options. Similar to volumes are configs. Configs are mounted as files into a container's filesystem. These options allow the application's behavior to adapt without having to recreate the docker image.

Secrets are a type of configuration data, but specifically for sensitive data that should not be exposed without security considerations.

The Compose File

The default path for a compose file is compose.yaml and by default is assumed to be in the working directory.

Compose files support fragments and extensions. Fragments basically crate references to previous blocks in the YAML file. These blocks can then be reused.

services:
  first:
    image: my-image:latest
    environment: &env
      - CONFIG_KEY
      - EXAMPLE_KEY
      - DEMO_VAR
  second:
    image: another-image:latest
    environment: *env

Extensions are basically user defined fields. Anything that starts with an x- is interpreted by Compose, but is silently ignores these fields if they are not recognized. Extensions in conjunction with fragments allows for modular compose files:

x-env: &env
  environment:
    - CONFIG_KEY
    - EXAMPLE_KEY

services:
  first:
    <<: *env
    image: my-image:latest
  second:
    <<: *env
    image: another-image:latest

Even more interestingly, multiple compose files can be merged together or one can simply include another compose file to be reused. That is to say, compose files are modular.

CLI

Some of the key compose commands are:

Example

An application is split into a frontend web application and a backend service.

The frontend is configured at runtime with an HTTP configuration file managed by infrastructure, providing an external domain name, and an HTTPS server certificate injected by the platform's secured secret store.

The backend stores data in a persistent volume.

Both services communicate with each other on an isolated back-tier network, while the frontend is also connected to a front-tier network and exposes port 443 for external usage.

Example Image

services:
  frontend:
    image: example/webapp
    ports:
      - "443:8043"
    networks:
      - front-tier
      - back-tier
    configs:
      - httpd-config
    secrets:
      - server-certificate

  backend:
    image: example/database
    volumes:
      - db-data:/etc/data
    networks:
      - back-tier

volumes:
  db-data:
    driver: flocker
    driver_opts:
      size: "10GiB"

configs:
  httpd-config:
    external: true

secrets:
  server-certificate:
    external: true

networks:
  # The presence of these objects is sufficient to define them
  front-tier: {}
  back-tier: {}

References

- https://docs.docker.com/compose/intro/compose-application-model/ - https://docs.docker.com/reference/compose-file/services/ - https://docs.docker.com/reference/compose-file/networks/ - https://docs.docker.com/reference/compose-file/configs/ - https://docs.docker.com/reference/compose-file/fragments/ - https://docs.docker.com/reference/compose-file/extension/