docker compose provides a nice configuration mini-language for managing docker containers. However, once you get past a small handful of containers, keeping two or three dozen things in one compose.yaml gets tough to manage, especially if you want multiple .env files.
The solution is to split up your compose file into multiple compose files. Exactly how to break them up is up to you – my approach is a folder structure like this:
compose.yaml: includes the subfolder compose.yaml's (network, services)
network/
compose.yaml: includes the subfolder compose.yaml's
dns/
compose.yaml: pihole and unbound
reverseproxy/
compose.yaml: nginx proxy manager
docker-registry-proxy/
compose.yaml: docker registry proxy
services/
compose.yaml: includes the subfolder compose.yaml's
homeassistant/
compose.yaml: homeassistant container
immich/
compose.yaml: all the immich containers
(this is only a small excerpt; I have quite a lot of containers)
In order to keep the management aspect easy, I like to be able to run one simple docker compose up -d command and have all of the containers rebuild as necessary. To that end, the tree of compose.yaml files uses includes until the very bottom of the tree:
# The root compose.yaml
include:
- network/compose.yaml
- services/compose.yaml# in network/compose.yaml
include:
- dns/compose.yaml
- reverseproxy/compose.yaml
- docker-registry-proxy/compose.yamland then only at the very bottom of the tree do I actually define the service(s). This also provides a nice way to disable services you don’t want; you can simply comment out the inclusion line at whatever level is appropriate.
Version Control
Because compose files are YAML, which is plain text, this approach lends itself nicely to a git repo.
Private information
Be careful that you don’t expose any private keys, secrets, domains, etc, etc. to the open internet! Typically,
.envfiles are.gitignore’d out of the repo!