Shove is an API-first Docker container deployment and management tool.
  • Go 98.3%
  • Shell 1.5%
  • Dockerfile 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Jonas Claes 929b2b07fd
All checks were successful
ci / test (push) Successful in 1m30s
release / release (push) Successful in 31s
ci / e2e (push) Successful in 1m26s
feat: treat Compose dir without shove.yaml as warning, not error
2026-10-09 20:19:58 +02:00
.forgejo test: fix running in ci 2026-09-29 20:54:56 +02:00
.idea feat: deploying and undeploying of stacks 2026-09-27 21:38:50 +02:00
cmd feat: treat Compose dir without shove.yaml as warning, not error 2026-10-09 20:19:58 +02:00
docs feat: treat Compose dir without shove.yaml as warning, not error 2026-10-09 20:19:58 +02:00
internal feat: treat Compose dir without shove.yaml as warning, not error 2026-10-09 20:19:58 +02:00
packaging feat: deploying and undeploying of stacks 2026-09-27 21:38:50 +02:00
.gitignore feat: deploying and undeploying of stacks 2026-09-27 21:38:50 +02:00
go.mod feat: deploying and undeploying of stacks 2026-09-27 21:38:50 +02:00
go.sum feat: deploying and undeploying of stacks 2026-09-27 21:38:50 +02:00
main.go feat: deploying and undeploying of stacks 2026-09-27 21:38:50 +02:00
README.md feat: deploying and undeploying of stacks 2026-09-27 21:38:50 +02:00

shove

Push-triggered Docker Compose deploys from an infra Git repository.

You keep your Compose stacks in one Git repository. On every push, CI runs shove deploy, which compares each stack at the pushed commit with what every server actually runs, and tells the servers to deploy, redeploy or tear down stacks until they match. Servers fetch the exact commit themselves and run docker compose; CI never copies files to them.

push ──▶ CI: shove deploy ──(tailnet)──▶ shove agent on each server ──▶ git fetch + docker compose up
  • Declarative: Git is the source of truth. Deleting a stack, or removing a server from its targets, tears it down there.
  • Minimal redeploys: only stacks whose directory changed are deployed, and within a stack only the services whose definition or files changed are recreated.
  • Safe by default: validation runs before anything is sent, a delayed CI run never downgrades a newer deploy, and a stack is never taken over from another repository.
  • Secrets: sops-encrypted secrets in the repository, decrypted in memory on the server, and per-server secrets files. Secret values are redacted from all output.
  • GitHub Actions and Forgejo Actions, with shove init ci to generate the workflow.

Quick start

1. Install the agent on each server (needs git and Docker Compose 2.24+):

curl -fsSL https://code.jonasclaes.be/jonasclaes/shove/releases/download/latest/install.sh | sudo sh
curl -fsSLO https://code.jonasclaes.be/jonasclaes/shove/releases/download/latest/shove-agent.service
sudo mv shove-agent.service /etc/systemd/system/
sudo systemctl edit shove-agent     # override ExecStart= to add --allowed-repository <repo>
sudo systemctl enable --now shove-agent

The agent has no authentication of its own: keep port 4212 reachable only from CI, for example over Tailscale. See docs/agent.md.

2. Lay out the infra repository:

shove.yaml                    # inventory
stacks/
  whoami/
    compose.yaml
    shove.yaml                # which servers run this stack
    secrets.enc.env           # optional, sops-encrypted
# shove.yaml
version: 1
servers:
  web-1:
    url: http://web-1.example.ts.net:4212
# stacks/whoami/shove.yaml
targets: [web-1]
secretsFile: secrets.enc.env   # optional

3. Add the CI workflow from the root of the infra repository:

shove init ci                       # GitHub, or a detectable Forgejo
shove init ci --provider forgejo    # self-hosted Forgejo

Add the Tailscale OAuth secrets (see docs/ci.md) and push.

Commands

Command What it does
shove deploy [stack…] Reconcile every server with head, or deploy the named stacks.
shove plan Offline: validate the repository and list the stacks that changed.
shove status Show what every server runs, with commit and health.
shove rollback <stack> Redeploy each target's previous commit.
shove undeploy <stack> Tear a stack down (named volumes are kept).
shove init ci Write the CI workflow.
shove agent Run the agent.

See docs/operations.md for flags, exit codes and reconcile rules.

Documentation

  1. Repository layout and shove.yaml, including secrets
  2. Installing and running the agent
  3. CI setup for GitHub and Forgejo
  4. Operations: commands, reconcile rules, rollback, undeploy, troubleshooting
  5. Implementation notes: design decisions and manual checks

Development

Requires Go (see go.mod), git and Docker with Compose. The sops tests also need sops and age-keygen, and skip without them.

go build -o shove .
go test ./...                                     # unit tests
go test -tags integration ./...                   # against the local Docker daemon
go test -tags e2e ./cmd -run TestE2E -v           # two agents in docker:dind

CI and releases run on Forgejo (.forgejo/workflows/). Pushing a v* tag builds the binaries and publishes a release with install.sh and the systemd unit.