How Docker Compose works

How Docker Compose works

Posted on 07 Nov 2019

This is the seventh article of the Getting started with Docker series. In this article, I will discuss Docker Compose and how to use it to improve the code developed so far for our PostgreSQL cluster.

Image build and runtime configuration

In the code developed so far, we used some helper scripts to create and clean up the postgresql image and volumes, to start and stop the containers. If the application you are building requires more than one container you can manage the image build and runtime configuration with a new Docker tool: Docker Compose.

What is Docker Compose?

Docker Compose is a command-line tool that talks with the docker engine and it is able to manage multi containers applications deployed on a single node. The tool is able to build the application docker image and runtime configuration like port mapping, bind and volumes mounts, networking, IPC, and so on.

You can think of the Docker Compose command line as a wrapper that extends the functionalities of the docker command line.

Docker Compose takes in input a YAML file and uses it to create one or more services (the applications) deployed in one or more containers. The YAML file, for each service, specifies the Docker image to use and how to configure it at runtime.

Docker Compose commands

The following commands work exactly the same as their docker counterparts, the only difference is that they can affect more than one container.

docker-compose pull
docker-compose build
docker-compose run
docker-compose exec
docker-compose create
docker-compose start
docker-compose stop
docker-compose restart
docker-compose pause
docker-compose unpause
docker-compose top
docker-compose logs
    

The most important Docker Compose commands are:

docker-compose up
docker-compose down
    

The former builds the required docker image if they don’t exist and start the containers. The latter stop the containers and other docker resources.

For more details on docker-compose commands read the official documentation.

Create the PostgreSQL cluster with Docker Compose

The goal of this section is to modify our PostgreSQL application to leverage on Docker Compose to improve the code removing all the helpers’ scripts used so far.

To do that, we need to create the YAML file where we define three PostgreSQL services (applications), each one having:

  • the definition of the PostgreSQL docker image
  • a docker volume where store the data;
  • networking connection with IP, Port, and hostname assigned;

The YAML File

Here you can see the YAML file. The tag version specifies the version of the YAML file.

version: '3.6'
    

Then we define the three service volumes.

volumes:
    volume1:
    volume2:
    volume3:
    

The services tag defines the three services (applications) to manage: node1, node2, and node3.

services:
    node1:
        ...

    node2:
        ...

    node3:
        ...
    

Let’s see in detail the definition of one of these services. The container has a name and it has the image postgresql as a template. If the image doesn’t exist in the local docker registry a new one is built using the Dockerfile in ../src.

node1:
    container_name: node1
    build:
        context: ../src
        dockerfile: Dockerfile
        image: postgresql:latest
    

The service will use the following environment variable whose values are in the .env file.

environment:
    NODE_NAME: node1
    MASTER_NAME: $MASTER_NAME
    

Container port 5432 maps on host 5432 port. The other two containers map the local 5432 port host port 5433 and 5434.

ports:
    - "5432:5432"
    

All three containers store logs and data directory in /home/postgres/data mapped with docker volumes.

volumes:
    - volume1:/home/postgres/data
    

Finally, the container connects to the network bridge driver and has IP 10.0.2.31 and hostname node1.domain.com.

networks:
    cluster:
        ipv4_address: 10.0.2.31
        aliases:
            - node1.domain.com
    

Here the definition of the bridge driver with subnet 10.0.2.1/24.

networks:
    cluster:
        driver: bridge
        ipam:
            config:
                - subnet: 10.0.2.1/24
    

How to test the cluster?

To start the cluster you can type the following command.

docker-compose up -d
    

The test of the upgrade and failover scenarios is exactly the same as the previous article. The only difference is that this time you can use the docker-compose command instead of the docker one.

To shut down the cluster you can type the following command.

docker-compose down
    

This command does not remove the volume so the data still exists. If you start again the cluster no data loss occurs. If you want to remove the volume you can add the -d option to the command.

What’s next?

In this article, we explained what Docker Compose is and how to use it to deploy multi containers application on a single host. However, have a database cluster with all containers on a single node is ok in development and test environments but makes no sense in production because if the node goes down the whole cluster crash. In the next article, to solve this issue and implement a real High Availability solution we need to leverage on Docker Swarm.