freshdock
A modern, health-gated Docker container auto-updater — a maintained successor to Watchtower, in a single Rust binary.
Quickstart · Docs · Configuration · From Watchtower
What it does
freshdock watches your running containers, notices when a newer image is published, and updates them safely — a broken new image rolls back automatically instead of leaving you with a dead service.
| Capability | What you get |
|---|---|
| Health-gated rollback | A container counts as updated only after its healthcheck passes (or a grace period for those without one). If the new image fails to come up, the previous container is restored — and you're notified. |
| Per-container modes | Drive each container with Docker labels: live, nightly, weekly, monthly, watch, off. Mix them freely on one daemon. |
| Five registries | Docker Hub, GHCR, Quay.io, lscr.io, and any OCI bearer-token registry — anonymous or authenticated. |
| Four notifiers | Webhook, Discord, Telegram, and SMTP, each subscribable to the events it cares about. |
| Optional cleanup | Remove superseded images after a healthy update; optionally prune dangling images. |
| Single static binary | ≤ 10 MB, no runtime dependencies. No JVM, no Go runtime, no 100 MB image to manage your homelab. |
Opt-in by design. freshdock ignores every container until you set
freshdock.enable=true, and an enabled container with no explicit mode defaults towatch(detect-and-notify, never restart). Nothing is touched until you ask.
Quickstart
Label a container to opt it in, then watch it with a read-only socket:
# docker-compose.yml
services:
web:
image: nginx:1.27
labels:
- "freshdock.enable=true" # opt in; mode defaults to watch
freshdock:
image: ghcr.io/turbootzz/freshdock:latest
command:
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: unless-stopped
Ready to let it update something? Switch to freshdock.mode=nightly (and give the
daemon a writable socket). Full walkthrough → Quickstart.
Install
# crates.io
# container image (multi-arch: amd64, arm64, armv7)
Prebuilt static-musl binaries (amd64 / arm64 / armv7) are attached to each
release. From source:
git clone … && just build (binary at target/release/freshdock).
Update modes
| Mode | Behaviour |
|---|---|
live |
Poll frequently; pull and recreate on every new digest. |
nightly / weekly / monthly |
Check on a cron schedule (default 04:00); recreate if newer. |
watch |
Detect updates and notify only — never pull or restart. |
off |
Ignore the container entirely. |
Set the mode (and an optional cron override) with labels:
labels:
- "freshdock.enable=true"
- "freshdock.mode=weekly"
- "freshdock.schedule=0 2 * * 1" # 02:00 every Monday (overrides the default)
Full label vocabulary and cron syntax → Configuration and Scheduling.
Documentation
| Quickstart | Up and running in a minute. |
| Configuration | Every label, freshdock.toml table, and env var (the single source of truth). |
| CLI reference | check, recreate, run, and all flags. |
| Scheduling & modes | Update modes and cron syntax. |
| Notifications | Webhook, Discord, Telegram, SMTP. |
| Health & rollback | The recreate lifecycle and image cleanup. |
| Registry auth | Private registries and credentials. |
| Deployment | Container, systemd, socket permissions, compatibility. |
| Troubleshooting | Symptom-first fixes for common first-run issues. |
| Migrating from Watchtower | Label/flag translation. |
| Architecture & roadmap | Design, phases, goals, risks. |
Runnable example stacks: examples/compose/. A commented
config template: freshdock.toml.example.
Why freshdock
Watchtower — the de-facto Docker auto-updater for years — was archived by its maintainers on 17 December 2025, and shipped an embedded Docker SDK (API 1.25) incompatible with Docker Engine 29+. The community has forks, but none combine what matters for a small homelab:
- Modern Docker API — tested against Docker 24.x through 29+, auto-negotiated via bollard.
- Safe updates — a broken new image rolls back automatically instead of leaving a dead container.
- Small footprint — a single static binary, not a 100+ MB image to manage your other containers.
Compatibility
| Platform | Status |
|---|---|
| Plain Docker (24.x – 29+) | Primary target. |
| Docker Desktop (Linux, macOS, Windows) | Supported. |
| Portainer (CE and Business) | Supported via the same Docker socket. |
| Podman 4+ | Supported via the Docker-compatible socket. |
| Compose-based UIs (Dockge, Komodo, …) | Containers updated individually; compose files untouched. |
| Kubernetes / Swarm | Out of scope — use platform-native mechanisms. |
Status & roadmap
Phases 0–7 are complete and freshdock is at its first stable release, 1.0.0.
The full plan and architecture live in docs/PLAN.md; release
mechanics in RELEASE.md; per-version notes in
CHANGELOG.md.
Contributing
Contributions are welcome — see CONTRIBUTING.md for local setup, the quality gates, and dependency hygiene. Security reports: SECURITY.md.
Support
freshdock is free and open source. If it keeps your homelab up to date, you can support its development through GitHub Sponsors. Sponsoring is entirely optional — stars, bug reports, and pull requests help just as much.
License
freshdock is licensed under the Apache License 2.0.
Acknowledgements
- Watchtower for being the standard for ten years and shaping the design space.
- bollard for the Rust Docker SDK that makes any of this possible.