When I first started self hosting services at home, my docker-compose file had a single container definition: Plex. Fast forward 5 years and today my compose file has over 30 containers defined in just over 500 lines of yaml. While it's incredibly easy to drop a few more lines into the compose file to try out a new service in just a couple minutes, keeping things up to date starts to become a burden.
Let's talk about the
It's tempting to define every container using the
latest image, but as I found out the hard way, it's not a smart way to run containers you rely on. If you're not paying attention to what you're updating, you could find yourself with broken services (or even corrupted data).
The problem with the
latest tag is that it doesn't act as a pointer to the latest release of an image, it's basically just another tag. When you pull the
latest tag, that's not a pointer to
version-x.x.x, it's whatever's tagged as
latest. This means that the image you download isn't tagged with the version, so in 2 months when you need to know which image version you have running, all you have to go on is
Moral of the story: don't use the
So far, I haven't found a better way of safely updating containers than manually updating each image definition. For a compose setup with a few containers this isn't a big deal, but at 30+ containers it starts to get cumbersome. To ease this a bit, I use the
Docker Compose environment file
Docker Compose supports environment files for making environment variables available to docker-compose. By default, this is a file called
.env placed in the project directory. Aside from storing some commonly used variables like Time Zone and the root Appdata directory, I set variables for each image definition including the tag.
Trying to keep that many services up to date is time-consuming regardless, but putting all of the image definitions in the same place makes the process a little bit easier. If nothing else, it's easier to read.