New Maintainers Tutorial
Package your first recipe¶
Overview¶
Packaging a recipe is basically knowing a bag of about 20 tricks. Once you learn them, there is nothing more to learn. It can seem daunting at first but it's simple and easy to do once you know the tricks.
The nice thing about packaging is that only one person has to do it and then we all benefit. We've seen that over time, the core of the configuration doesn't really change. New options and versions might come but the config remains quite stable. This is good since it means that your packaging work stays relevant and useful for other maintainers & operators as time goes on.
Depending on your familiarity with recipes, it might be worth reading how a recipe is structured and making clear you understand what a recipe is before continuing.
Making a plan¶
The ideal scenario is when the upstream project provides both the packaged image and a compose configuration which we can build from. If you're in luck, you'll typically find a Dockerfile
and a docker-compose.yml
file in the root of the upstream Git repository for the app.
- Tired: Write your own image and compose file from scratch
- Wired: Use someone else's image (& maybe compose file)
- Inspired: Upstream image, someone else's compose file
- On fire: Upstream image, upstream compose file
Writing / adapting the compose.yml
¶
Let's take a practical example, Matomo web analytics. We'll be making a Docker "swarm-mode" compose.yml
file.
Luckily, Matomo already has an example compose file in their repository. Like a lot of compose files, it's intended for use with docker-compose
, instead of "swarm mode", but it should be a good start.
First, let's create a directory with the files we need:
abra recipe new matomo
cd ~/.abra/recipes/matomo
Then, let's download and edit the docker-compose.yml
file:
mkdir matomo && cd matomo
wget https://raw.githubusercontent.com/matomo-org/docker/master/.examples/apache/docker-compose.yml -O compose.yml
Open the compose.yml
in your favourite editor and have a gander 🦢. There are a few things we're looking for, but some immediate changes could be:
- Let's bump the version to
3.8
, to make sure we can use all the latest swarm coolness. - We load environment variables separately via
abra
, so we'll strip outenv_file
. - The
/var/www/html
volume definition on L21 is a bit overzealous; it means a copy of Matomo will be stored separately per app instance, which is a waste of space in most cases. We'll narrow it down according to the documentation. The developers have been nice enough to suggestlogs
andconfig
volumes instead, which is a decent start. - The MySQL passwords are sent as variables which is fine for basic use, but if we replace them with Docker secrets we can keep them out of our env files if we want to publish those more widely.
- The MariaDB service doesn't need to be exposed to the internet, so we can define an
internal
network for it to communicate with Matomo. - Lastly, we want to use
deploy.labels
and remove theports:
definition, to tell Traefik to forward requests to Matomo based on hostname and generate an SSL certificate.
The resulting compose.yml
is available here.
Updating the .env.sample
¶
Open the .env.sample
file and add the following
DB_PASSWORD_VERSION=v1
DB_ROOT_PASSWORD_VERSION=v1
The resulting .env.sample
is available here
Test deployment¶
Running Co-op Cloud server required!
The rest of this guide assumes you have a Co-op Cloud server going -- we'll use swarm.example.com
, but replace it with your own server address. Head over to the operators tutorial if you need help setting one up.
Now, we're ready to create a testing instance of Matomo:
abra app new matomo --secrets \
--domain matomo.swarm.example.com \
--server swarm.example.com
Depending on whether you defined any extra environment variables -- we didn't so
far, in this example -- you might want to run abra app config swarm.example.com
to check the configuration.
Otherwise, or once you've done that, go ahead and deploy the app:
abra app deploy swarm.example.com
Then, open the DOMAIN
you configured (you might need to wait a while for Traefik to generate SSL certificates) to finish the set-up. Luckily, this container is (mostly) configurable via environment variables, if we want to auto-generate the configuration we can use a config
and / or a custom entrypoint
(see coop-cloud/mediawiki
for examples of both).
Finishing up¶
You've probably got more questions, check out the packaging handbook!