I got annoyed with having to use Portainer / Komodo for continuously deploying docker compose stacks from Github. Barnacle is a simple Golang tool built deployed as a container that polls a git repo and deploys docker compose stacks found in subfolders. It's a bit like Flux for Kube, but simpler and sticks onto a docker host to deploy your stacks. Hence, Barnacle.
- Minimal and understandable code, About 400 LOC aside from webhooks.
- Polls a git repo using a deploy key at a configurable duration
- Detects compose stack changes then runs a compose up / down to deploy the changed stack.
- Clones your repo / stacks to
/opt/reponame - Stacks can be ignored using a
ignorefile to not operate on them. - Can webhook updates and deployment status to Slack and Discord.
2025/10/26 00:08:14 Updated from bc646f6 to c52fc93
2025/10/26 00:08:14 Repository updated, deploying changed stacks...
2025/10/26 00:08:15 Discord webhook sent successfully
2025/10/26 00:08:15 Current stacks on disk: [traefik whoami dockge]
2025/10/26 00:08:15 New stack detected: whoami
2025/10/26 00:08:15 Affected stacks: [whoami]
2025/10/26 00:08:15 Deploying stack: whoami
Network whoami_default Creating
Network whoami_default Created
Container whoami-whoami-1 Creating
Container whoami-whoami-1 Created
Container whoami-whoami-1 Starting
Container whoami-whoami-1 Started
2025/10/26 00:08:15 Successfully deployed stack: whoami
2025/10/26 00:08:15 Deployment complete: 1 stack(s) deployed
2025/10/26 00:08:16 Discord webhook sent successfull
Your repo should be structured like this. It probably already is. Add an ignore file to ignore a stack.
As this hard pulls to avoid untracked changes / desync, I'd recommend using volumes or .gitignoring local config in repository structure.
your-repo/
├── stack1/
│ └── docker-compose.yml
├── stack2/
│ ├── docker-compose.yml
│ └── ignore # This stack will be skipped
└── stack3/
└── compose.yml
Generate an SSH key pair and add this to your repo
ssh-keygen -t ed25519 -C "deploy-key" -f deploy_keyEdit the docker-compose.yml file
environment:
- REPO_URL=git@github.com:youruser/yourrepo.git # Your repo
- BRANCH=main # Desired branch
- DISCORD_WEBHOOK=https://discord.com/api/webhooks/YOUR_WEBHOOK_URL # OptionalUpdate the SSH key path in volumes if needed:
volumes:
- ./deploy_key:/ssh/deploy_key:ro # Path to your deploy keyRun the project with docker compose up -d. This can be from your stacks repo, but I'd recommend adding an ignore flag on Barnacle itself.