I built a tool called ComposeFlux to manage Docker Compose deployments across my homeservers using GitOps. If you want to know the backstoryβββwhat I was using before, what alternatives I tried, and why I built it:
Part 1: My Homeservers, Ansible, and the Pain Points
Part 2: Searching for the Right ToolβββKomodo, Dockhand, and Beyond
Part 3: ComposeFluxβββA Lightweight GitOps Tool for Docker Compose
Introduction
I manage 2 homeservers and a few cloud VMs, running around 15+ Docker Compose appsβββfrom Traefik and Jellyfin to Immich and Prometheus. Over time, deploying and managing these stacks across multiple servers became painful, especially when the same app (like Traefik) needed to be configured on multiple servers.
After using Ansible playbooks for almost 2 years and evaluating tools like Komodo and Dockhand, I built my own tool: ComposeFlux.
ComposeFlux is a lightweight, headless GitOps tool for Docker Compose. It continuously polls a Git repo, detects changes in your compose files, and deploys only the stacks that changed. No backend database, no UIβββjust Git and Docker Compose.
Here are the key features:
- True GitOps βββPush to Git, deployment happens automatically
- Smart change detection βββOnly redeploys stacks whose compose file hash changed
- External secrets support βββIntegrates with Bitwarden and Infisical
- Pure Go βββUses the Docker Compose SDK directly, no shell commands
- Flexible config βββStartup order, shared env vars, minimal YAML config
- Automatic image updates βββChecks registries on a cron schedule and updates containers via the Compose SDK
- Lightweight βββSingle binary, no database
For the full feature breakdown, check out Part 3 of my blog series, or the ComposeFlux docs.
Now, let me show how I actually use it.
Git Repo Structure
I use Docker Composeβs βincludeβ feature to create a base/overlay structureβββsimilar to Kustomize if youβre familiar with Kubernetes.
The stacks folder holds generic, reusable docker compose files. The servers folder contains a dedicated folder for each server, where apps just reference the base compose files:
.
βββ servers # Overlay β each server has a folder
β βββ helium # My Lenovo homeserver
β β βββ gocron
β β βββ immich
β β βββ it-tools
β β βββ n8n
β β βββ node-exporter
β β βββ omni-tools
β β βββ squoosh
β β βββ stack.yml
β β βββ traefik
β β βββ zeroclaw
β βββ wg1-ams # Oracle Cloud VM in Amsterdam
β β βββ adguardhome
β β βββ authelia
β β βββ stack.yml
β β βββ traefik
β β βββ wg-easy
βββ stacks # Base β reusable compose files
βββ actualbudget
β βββ compose.yml
βββ traefik
β βββ compose.yml
β βββ README.md
βββ qbittorrent
β βββ compose.config.yml
β βββ compose.scripts.yml
β βββ compose.yml
β βββ README.md
βββ zeroclaw
βββ compose.yml
βββ README.md
This structure means I fix a Traefik config once in stacks/traefik/compose.yml, and every server that includes it gets the update.
I also use Docker Compose Configs to store app configuration directly inside compose files, so that ComposeFluxβs hash-based change detection can pick up config changes too.
Deploying ComposeFlux with Ansible
I use an Ansible playbook to copy and deploy ComposeFlux on each target server. The playbook copies the ComposeFlux docker compose file to the server and brings it up.
There is a work-in-progress Ansible role to manage this deployment more cleanly.
See the Multi-Server Setup docs for how ComposeFlux uses the repo structure above to manage apps across servers.
GitOps in Action
ComposeFlux continuously polls a Git repo on a specific branch, watching a specific directory. For example, ComposeFlux deployed on the server wg1-ams watches the servers/wg1-ams/ directory:
.
βββ servers
β βββ wg1-ams # ComposeFlux on "wg1-ams" watches this directory
β β βββ adguardhome
β β βββ authelia
β β βββ stack.yml
β β βββ traefik
β β βββ wg-easy
βββ stacks
βββ ...
Whenever I push changes to this directoryβββboom, ComposeFlux picks up the change and deploys it on the server. No manual SSH, no running playbooks, no copy-pasting configs.
Testing Before Merge with Auto-Dev
Hereβs the part Iβm most happy about.
Imagine you create a PR to add a new docker compose file for an app, say βIT Toolsβ. The PR diff looks good, you merge to main. But you didnβt actually test the deployment on any server before merging. ComposeFlux picks up the change from main, tries to deploy, and fails because of some wrong config. Not great.
To solve this, I use autodev-actionβββan open source GitHub Action from my employer. We use this internally every day for GitOps repos.
Hereβs how it works: when you add a dev label to your PR, the action merges your feature branch changes into a dev branch (configurable) and also syncs changes from main. On the server, ComposeFlux is configured to watch the dev branch instead of main.
My deployment flow:
- Create a PR and review the diff
2. Add the dev label
Here are the action logs:
3. ComposeFlux deploys on the server
veerendra@hydrogen:~$ docker logs composeflux
time=2026-05-02T17:31:14+02:00 level=DEBUG msg="Fetch git updates" remote_sha=bdb996d local_sha=a1c40f7 updates=true
time=2026-05-02T17:31:16+02:00 level=DEBUG msg="Adding secrets to cache" count=17
time=2026-05-02T17:31:16+02:00 level=DEBUG msg="Adding env vars to cache" count=7
time=2026-05-02T17:31:16+02:00 level=INFO msg="Stack hash changed, redeploying" stack_name=homer
time=2026-05-02T17:31:16+02:00 level=INFO msg="New stack detected" stack_name=it-tools
time=2026-05-02T17:31:17+02:00 level=INFO msg="Deploying stacks" count=2 order=homer,it-tools
time=2026-05-02T17:31:26+02:00 level=INFO msg="Successfully deployed the stack" stack_name=homer
time=2026-05-02T17:31:37+02:00 level=INFO msg="Successfully deployed the stack" stack_name=it-tools
I can confirm the app appeared in my Homer dashboard:
4. Everything worksβββmerge the PR to ** main**
This gives me confidence that every deployment is tested before it hits production. Just like how we do it at work, but for my homeservers.
Wrapping Up
This setup has been running smoothly for my homeservers and cloud VMs. The combination of Git as the source of truth, ComposeFlux for automated deployments, and the auto-dev workflow for testing before merge gives me a workflow that feels professionalβββeven for a home setup.
If youβre managing Docker Compose apps across multiple servers and tired of manual deployments, give ComposeFlux a try. Check out the documentation to get started.

















