Photo by Glen Carrie on Unsplash
Understanding Composability, One Service at a Time
Docker Compose finally makes sense to me.
The docker-compose.yml
file. For me, just one of those config files. For years I’ve worked on projects that use this file, but the file was always defined by others. I’ve never had to seriously care what it contains. All I needed to know was that docker compose up -d
sets up and starts all the necessary stuff. After all, isn’t Docker about making “it works on my machine” an excuse of the past? Plus, I understood some of the options and words whenever I had to glance through the file. So it wasn’t all that bad, I could ultimately ignore the file… until something breaks! 😁 Well, I’ve finally created a simple docker compose file containing just one service, for myself. The proverbial lightbulb has flickered on! 💡
Suppose you want to start a simple postgres db instance on your computer (or a server). You could go through the manual installation, port configuration, user and role management, blah, blah, blah… or you could just use a postgres docker image. Let’s use a postgres docker image 🙂. You probably don’t want to lose all your db data if/when the docker container stops. For that you need a docker volume to persist the data in a location outside the docker container. In Code This Means you should run the following shell command:
docker volume create postgres
Creates the volume, names it postgres
, done. Straightforward enough. Now you need to actually start the docker container and your postgres db instance. You should give the container a name, obviously. You should specify that it uses that volume you just created. You should specify that the container should be detached from your terminal, because you will close down that terminal sooner or later. That’s only for the container, how about for postgres? You should specify some basic values: username, password, database name, and port. You should specify the postgres image you actually want to run. Translating allll that into docker cli options, we get this shell command:
docker run -d \
--name postgres \
-v postgres:/var/lib/postgresql/data \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=my_db \
-p 5435:5432 \
postgres:13.4
Explaining very quickly:
-d
says detach from the terminal-v
says the location in the container whose data should be persisted to thepostgres
volume you created earlier-e
specifies environment variables inside the container-p
specifies the host computer’s port (left side of:
) that should be mapped to the container’s port (right side of:
)
Now, here’s a docker-compose.yml
file that combines the 2 commands you’ve used so far:
version: '3'
services:
postgres:
image: 'postgres:13.4'
volumes:
- 'postgres:/var/lib/postgresql/data'
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: my_db
ports:
- '5435:5432'
volumes:
postgres:
I don’t even have to translate anything! Except services
, maybe? You might have expected containers
instead. Think of using Docker for setting up microservices 😉. It’s “services” because any particular service could be backed by multiple underlying containers. Composability, yay! To start your container, you already know what to do:
docker compose up -d
The -d
option is still necessary to detach the container from your terminal.
And should you ever need to stop the container, docker compose down
does that for you. If you’re determined to remove all traces of your activities 👻, add the -v
option to delete your container and all its associated resources.
In light of all that, I’d explain the value prop of Docker Compose like this:
define all your docker cli instructions and options in one place,
in language that is more friendly and approachable,
with the ability to define multiple containers and services together, and
the ease of starting/stopping/managing them together and (roughly) in sync.
Now I (and perhaps you too) can appreciate why Docker Compose is so valuable for managing both simple and complex server infrastructure.
Questions? Feedback? Nice words, or mean ones? Feel free to reach out to @CodeWithOz on all the socials, or on LinkedIn.