The magical world of Docker-Compose
Contents
The magical world of Docker-Compose¶
I’ve known about this tool for a long time, however only invested time into learning and understanding it over the summer of 2020. In these notes are recipes, little how-to’s, and general command and configuration reference.
Table of Contents¶
Compose files¶
We use docker-compose.yml
or .yaml
to specify how we want to deploy a series of docker containers. A simple such file to spawn instances of the hello-world
image may be written
version "3.8" # use the latest version
services:
helloworld:
image: hello-world
which we can then start with
docker-compose up
NB: if you have multiple configuration files, with different names, you can specific which compose file to use with the -f
flag, such as
docker-compose -f test.yml [COMMAND]
For full documentation on writing compose files, see the official docs.
Structuring a service¶
We can structure normal command line flags, such as for binding ports, volumes, or setting env variables, in the compose file as such
version: "3.8"
services:
some_service:
image: some/image:tag
ports:
- 80:8080
expose:
- 25655/udp
volumes:
- ~/www:/www
- ${CONFIG_PATH}:/config
environment:
- ACCEPT_EULA=yes
user: "${UID}:${GID}"
Lets examine a little bit what is going on here: we are using environment variables from the current tty
, such as UID
and GID
to specify the permissions with which the container should run. This can be crucial when sharing volumes from the host machine, since it may require read/write permission, which by default it may not have.
We are also using CONFIG_PATH
which can either be set in the tty
, or configured in an environment variable file.
Environment variables¶
Compose files read variables from tty
and by default the .env
file in the same directory as the compose file. This .env
is formatted as key value pairs:
CONFIG_PATH=/path/to/config/
HTTP_PORT:80
...
More on environment variables and environment files can be found in the official docs, and syntax guide.
Controlling startup and tear-down order¶
For more, see the official docs.
Networks¶
Networks are replacing the legacy link
statements in docker, as can be read in the networking reference.
Volumes¶
TODO
Configs (docker-swarm)¶
At the moment, this feature is only available to docker swarm, which I will explore and document later.
Docker-Compose commands¶
Scaling¶
You can spawn multiple instances of a service defined in your config file using
docker-compose up --scale some_service=5
This way, we spawn 5 containers of some_service
.
## Discussions
In this section I want to elaborate on some thoughts I’ve had whilst using docker-compose
.
The importance of down
¶
When configuring e.g. complicated networks to run between your containers, you need to ensure they are properly taken down so that any changes you try to make, actually get implemented instead of throwing errors. Similarly, if you are tampering with services, by default sig-term in docker-compose up
won’t delete the previous containers, such that if you ran the command again, the containers would just be restarted, instead of new ones being created.
As we see in the official docs, the down
command takes care of this for us by
removing containers defined in the compose file
removing networks defined in the compose file
removing the default network if one was created
Installing on *nix¶
OSX has a simple installation with brew, however on e.g. Debian, the apt
version only supports version 2 compose files. For a up-to-date install, use this guide:
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
and enable execution
sudo chmod +x /usr/local/bin/docker-compose
Example use cases¶
In this section are the compose file, and where relevant some explanation, for potential use cases:
VerneMQ cluster¶
Consider trying to set up a VerneMQ cluster using this simple docker-compose.yml
version: "3.7"
services:
verne_host:
image: vernemq/vernemq
environment:
DOCKER_VERNEMQ_ACCEPT_EULA: "yes"
networks:
backend:
ipv4_address: 172.18.5.2
verne_slaves:
image: vernemq/vernemq
depends_on:
- verne_host
environment:
DOCKER_VERNEMQ_DISCOVERY_NODE: "172.18.5.2"
DOCKER_VERNEMQ_ACCEPT_EULA: "yes"
networks:
- backend
networks:
backend:
ipam:
config:
- subnet: 172.18.5.0/24
And start the scalable cluster with
docker-compose up --scale verne_slaves=10
NB: I couldn’t get host name resolves to work on the dockersized version of VerneMQ, hence the static IP assign. I have opened an issue in vernemq/docker-vernemq
.