This is a field guide to Docker Compose. Docker Compose is a Docker “tool for defining and running multi-container Docker applications.” From a single defined YAML file, users can run multiple services and containers with a single command.

Docker Compose works in three steps:

  1. Defining your app’s environment with a Dockerfile.
  2. Defining your services with a Docker Compose YAML file.
  3. Running Docker Compose on the Docker Compose YAML file.

Useful Docker Compose Commands

  1. docker swarm init
    # Initialize swarm

    This command initializes a Docker swarm. The Docker engine targeted by this command becomes the manager node (indeed, the only node) in the new swarm.

    This command has these options:

    • advertise-addr: Advertised address (format: [:port])
    • autolock: Enable manager autolocking (requiring an unlock key to start a stopped manager)
    • availability: Availability of the node (“active”|”pause”|”drain”) (default: “active”)
    • cert-expiry: Validity period for node certificates (ns|us|ms|s|m|h) (default: “2160h0m0s”)
    • data-path-addr: Address or interface to use for data path traffic (format: )
    • dispatcher-heartbeat: Dispatcher heartbeat period (ns|us|ms|s|m|h) (default: 5s)
    • external-ca: Specifications of one or more certificate signing endpoints
    • force-new-cluster: Force create a new cluster from current state

    • listen-addr: Listen address (format: [:port]) (default:
    • max-snapshots: Number of additional Raft snapshots to retain
    • snapshot-interval: Number of log entries between Raft snapshots (default: 10000)
    • task-history-limit: Task history retention limit (default: 5)

  2. docker swarm init --advertise-addr
    # Initialize swarm (with IP address)

    This command may be required if your computer has multiple IP addresses on different interfaces.

  3. docker swarm leave --force
    # Remove a worker from the swarm

    This command removes the current worker from the swarm. The “–force” component ensures that this command is executed, even if the node leaving the swarm is a manager maintaining the swarm’s quorum.

    This command has these options:

    • --force, f: Force this node to leave the swarm, ignoring warnings

  4. docker stack ls
    # List available Docker stacks

    This command lists currently running Docker stacks.

  5. docker stack deploy -c docker-compose.yml exampleApp
    # Build or update the stack

    This file runs the selected Docker Compose file to create a Docker stack, creating a Docker app.

    This command has these options:

    • bundle-file: Path to a Distributed Application Bundle file
    • compose-file, -c: Path to a Compose file
    • prune: Prune services that are no longer referenced
    • resolve-image always: Query the registry to resolve image digest and supported platforms (“always”|”changed”|”never”)
    • with-registry-auth: Send registry authentication details to Swarm agents

  6. docker stack deploy -c docker-compose.yml exampleApp
    # Redeploy the stack
  7. docker stack rm exampleApp
    # Remove the stack and app

    This command takes down the current app and its stack from the current swarm.

  8. docker service ls
    # List running Docker services

    This command lists services running in a swarm, when targeting a manager node for that swarm.

    This command has these options:

    • filter, -f: Filter output based on conditions provided
    • format: Pretty-print services using a Go template
    • quiet, -q: Only display IDs

  9. docker service ps <service>

    This command lists tasks that are running in a swarm, when targeting a manager node for that swarm.

    This command has these options:

    • filter, -f: Filter output based on conditions provided
    • format: Pretty-print tasks using a Go template
    • no-resolve: Do not map IDs to Names
    • no-trunc: Do not truncate output
    • quiet , -q: Only display task IDs

  10. docker inspect <task or container>
    # Inspect a task or container

    This command inspects a task or container, returning low-level information about it.

    This command has these options:

    • format, -f: Format the output using the given Go template
    • size, -s: Display total file sizes if the type is container
    • type: Return JSON for specified type

  11. docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <task or container>
    # Retrieve an IP address
  12. docker inspect --format='{{range .NetworkSettings.Networks}}{{.MacAddress}}{{end}}' <task or container>
    # Retrieve a MAC address
  13. docker inspect --format='{{.LogPath}}' <task or container>
    # Retrieve a log path
  14. docker inspect --format='{{.Config.Image}}' <task or container>
    # Retrieve an image name
  15. docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' <task or container>
    # Loop over all port bindings
  16. docker inspect --format='{{(index (index .NetworkSettings.Ports “8787/tcp”) 0).HostPort}}' <task or container>
    # Retrieve a port binding
  17. docker inspect --format='{{json .Config}}' <task or container>
    # Get a JSON inspection subsection

Docker Swarms

  1. docker-machine create --driver virtualbox myvm1
    # Create Docker machine

    This command creates a Docker machine using VirtualBox.

    This command requires the “driver” flag to indicate the provider on which the machine should be created, either locally or remotely.

  2. docker-machine create --driver virtualbox myvm2
  3. docker-machine create --driver virtualbox myvm3
  4. docker-machine ls
    # List Docker machines

    This command lists available Docker machines.

  5. docker-machine ssh myvm1
    # Access Docker machine

    This command logs into or runs a command on a Docker machine.

    It requires the machine name (from docker-machine ls).

  6. docker-machine ssh myvm1 free
    # Run Docker machine command
  7. docker-machine ssh myvm1 docker swarm init --advertise-addr
    # Initialize Docker swarm

  8. docker-machine ssh myvm2 docker swarm join --token <token> <ip-of-original-machine>:2377
    # Join swarm as worker

    This command joins the current docker machine as a node to a swarm.

    Port 2377 is the standard Docker machine swarm management port and should be used.

  9. docker-machine ssh myvm1 docker swarm join-token manager
    # Add manager to swarm

    This command provides instructions for joining a node to the swarm as a manager.

  10. docker-machine ssh myvm1 docker node ls
    # View Docker nodes
  11. docker-machine env myvm1
    # Get new environment
  12. eval $(docker-machine env myvm1)
    # Change machine environment
  13. docker-machine ls
    # Confirm new environment

    The active machine should be changed to myvm1 in the output.

  14. docker stack deploy -c docker-compose.yml getstartedlab
    # Deploy app in new environment
  15. docker stack ps getstartedlab
    # Confirm distributed app

    Services and containers should be distributed between the swarm’s virtual machines.

  16. docker stack rm getstartedlab
    # Tear down the stack
  17. eval $(docker-machine env -u)
    # Unset environment variables
  18. docker-machine stop $(docker-machine ls -q)
    # Stop Docker machines

    This commands stops all running Docker machines.

  19. docker-machine rm $(docker-machine ls -q)
    # Remove Docker machines

    This command removes a Docker machine from a swarm.

  20. docker-machine scp docker-compose.yml myvm1:~
    # Copy file to machine

    This command copies files from the local host to a machine.

Sample Files

These files support the Docker Compose language guide above. They were taken from the Docker Compose docs.

Sample docker-compose YAML file.

Copy this text and paste it into a file named “docker-compose.yml” in the project directory.

The name “docker-compose.yml” is only a convention. The YAML file can be named whatever you want.

  1. version: "3"
  2. services:
  3.   web:
  4.     image: username/repo:tag
    # Custom user and image

    Replace “username”, “repo”, and “tag” with the registry values of a repository you control.

  5.     # image: friendlyhello
    # Local image

    Reference a local image instead of one on a registry.

  6.     deploy:
  7.       replicas: 5
  8.       restart_policy:
  9.         condition: on-failure
  10.       resources:
  11.         limits:
  12.           cpus: "0.1"
  13.           memory: 50M
  14.     ports:
  15.       - "80:80"
  16.     networks:
  17.       - webnet
  18.   visualizer:
  19.     image: dockersamples/visualizer:stable
  20.     ports:
  21.       - "8080:8080"
  22.     volumes:
  23.       - "/var/run/docker.sock:/var/run/docker.sock"
  24.     deploy:
  25.       placement:
  26.         constraints: [node.role == manager]
  27.     networks:
  28.       - webnet
  29.   redis:
  30.     image: redis
  31.     ports:
  32.       - "6379:6379"
  33.     volumes:
  34.       - /home/docker/data:/data
  35.     deploy:
  36.       placement:
  37.         constraints: [node.role == manager]
  38.     command: redis-server --appendonly yes
  39.     networks:
  40.       - webnet
  41. networks:
  42.   webnet: