docker-compose

The power of Docker Compose

Earlier I wrote about how to start with Docker. Though Docker by itself is a powerfull tool, you can do a whole lot more with it (in less time) when you get the hang of Docker Compose. And the best part: like Docker, it is very easy to start with


Install Docker Compose

Docker Compose comes as an installer in the Linux packagesource, but it usually isn’t the latest version. Docker has provided a how-to to download it from Github.

sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

You can check for the latest version over here: https://github.com/docker/compose/releases

To check which version you have on your system run

docker-compose --version

Docker Compose files

A docker-compose.yml file always starts with version: '#' and services:. Currently version 3.6 is the latest, where each version has added functionality. More about this over at Docker Docs. Be aware, Synology DSM currently supports up to version 2.

With that out of the way, take a look at the content of a docker-compose file below. This is the same as used in my blog about MQTT in Docker

version: '3'

services:
  mqtt:
    image: toke/mosquitto:latest
    container_name: mqtt
    restart: always
    ports:
      - 1883:1883/tcp
    networks:
      - bridge
    volumes:
      - ./config:/mqtt/config:ro
      - ./data:/mqtt/data

networks:
  bridge:


This code does exactly the same as when you’d use the command

docker run --name mqtt -d --restart always -p 1883:1883/tcp -v /home/docker/mqtt/config:/mqtt/config:ro -v /home/docker/mqtt/data:/mqtt/data toke/mosquitto:latest

Why use Docker Compose

So if the outcome of running those is the same, why go through the hassle of installing extra software and creating all those files? For me, the main reason is so that when you have to recreate the container, you don’t have to remember with which parameters you started the container. Basically, to remember those you probably write them down anyway. Another reason is that you can start several containers at the same time. If for example, you want to start multiple websites via Nginx, you just add them all into one docker-compose.yml file and start them up with one simple command. Speaking of which, the docker-compose command to start containers is easy to remember

docker-compose -f /home/docker/mqtt/docker-compose.yml up

or

cd /home/docker/mqtt
docker-compose up

Some more reasons to use Docker Compose
– Ability to auto update images/containers with Watchtower
– Ability to scale up containers
– Time saving
– Simple isolation of containers in a Docker network


Allow for easy upgrading containers

Without Docker Compose updating a container is quite a hassle. First you download the newer image, you have to stop and remove the running container. Then you have to type in the whole command, hoping you’re not forgetting a parameter, and finally you’re done. With Docker Compose, life is easier. You download the newer image and simply the same command as when you started the container. Docker Compose will stop and remove the old container and then start the newer container for you.


Isolation of networks

In the examples above you’ll notice the network: parameter. I usually just call them bridge, simply because I’m lazy and copy/paste a lot. This isn’t a problem because Docker Compose creates a new network for each docker-compose.yml file that is in a different location. So for example when you start two containers via

docker-compose -f /home/docker/mqtt/docker-compose.yml up
docker-compose -f /home/docker/nginx/docker-compose.yml up

You’ll end up with two networks. One would be mqtt-bridge and the other nginx-bridge. Both of these will not be able to communicate with eachother, making this a very easy managible way of isolating different parts of your network. You can have your websites in one network and all of your Home Automation containers in another.


Scaling up containers

In my opinion, this is a very powerfull tool of Docker Compose. What this does is starting several containers with the same config, allowing for fallback containers if one fails. Or is down for maintenance. Although you can’t use this on its own, since you can’t map the same port to multiple containers, but when used with for example Traefik this allows you to start up 2 or more containers to host the same website. Traefik will do the loadbalancing (default round-robin) and portmapping for you. If you stop one container, your website will still be up. So how does this work? Let’s create a docker-compose.yml to run a couple of websites via Nginx

version: '3'

services:
  website:
    image: nginx:latest
    restart: always
    networks:
      - bridge
    volumes:
      - /home/docker/nginx/website:/usr/share/nginx/html:ro
	  
  website-dev:
    image: nginx:latest
    restart: always
    networks:
      - bridge
    volumes:
      - /home/docker/nginx/website-dev:/usr/share/nginx/html:ro

networks:
  bridge:

If you read this closely and compare it to the MQTT file above (and you should) you probably notice we are missing some parameters. There is no container_name and no ports. The reason why is simple. As said portmapping can only be used by one container as your host can only map, for example, port 80 once. Container names have to be unique aswell. If a container_name is stated in the docker-compose.yml, every container started using that file will try to claim that name. It can’t so it would fail.
To start up three containers of the service website use the command

docker-compose -f /home/docker/nginx/docker-compose.yml up --scale website=3

About: lolgast


Leave a Reply

Your email address will not be published.