What is a docker-compose.yml file?

A docker-compose.yml is a config file for Docker Compose.

It allows to deploy, combine, and configure multiple docker containers at the same time. The Docker "rule" is to outsource every single process to its own Docker container.

Take for example a simple web application: You need a server, a database, and PHP. So you can set three docker containers with Apache2, PHP, and MySQL.

The advantage of Docker Compose is easy configuration. You don't have to write a big bunch of commands into Bash. You can predefine it in the docker-compose.yml:

db:
    image: mysql
    ports:
        - "3306:3306"
    environment:
        MYSQL_DATABASE: example_db
        MYSQL_USER: root
        MYSQL_PASSWORD: rootpw
php:
    image: php
    ports:
        - "80:80"
        - "443:443"
    volumes:
        - ./SRC:/var/www/
    links:
        - db

As you can see in my example, I define port forwarding, volumes for external data, and links to the other Docker container. It's fast, reproducible, and not that hard to understand.

The Docker Compose file format is formally specified which enables docker-compose.yml files being executed with something else than Docker, Podman for example.


Docker Compose is a tool that allows you to deploy and manage multiple containers at the same time.
A docker-compose.yml file contains instructions on how to do that.
In this file, you instruct Docker Compose for example to:

  • From where to take the Dockerfile to build a particular image
  • Which ports you want to expose
  • How to link containers
  • Which ports you want to bind to the host machine

Docker Compose reads that file and executes commands.
It is used instead of all optional parameters when building and running a single docker container.

Example:

version: '2'
services:
  nginx:
      build: ./nginx
      links:
          - django:django
          - angular:angular
      ports:
          - "80:80"
          - "8000:8000"
          - "443:443"
      networks:
       - my_net
  django:
      build: ./django
      expose:
          - "8000"
      networks:
       - my_net
  angular:
      build: ./angular2
      links:
          - django:django
      expose:
          - "80"
      networks:
        - my_net
networks:
  my_net:
    external:
      name: my_net

This example instructs Docker Compose to:

  • Build nginx from path ./nginx
  • Links angular and django containers (so their IP in the Docker network is resolved by name)
  • Binds ports 80, 443, 8000 to the host machine
  • Add it to network my_net
    (so all 3 containers are in the same network and therefore accessible from each other)

Then something similar is done for the django and angular containers.
If you would use just Docker commands, it would be something like:

docker build --name nginx .
docker run --link django:django angular:angular --expose 80 443 8000 --net my_net nginx

So while you probably don't want to type all these options and commands for each image/container, you can write a docker-compose.yml file in which you write all these instructions in a human-readable format.