crazy-max/diun: get notified when a container image changes
Receive notifications when an image is updated on a Docker registry
At a glance
- What is it?
- Diun watches container images and reports new tags or digest changes through the notification services you already run. It is a notification tool, not an updater, and that distinction decides whether it fits your stack.
- Who is it for?
- Adopt Diun if you want a record of image drift and already have a notification channel such as Gotify, Slack, Telegram, Discord, Rocket.Chat, Pushover, MQTT, AMQP or email, and if you accept that acting on the alert is your job. Do not adopt it expecting an automatic updater: the README describes a watcher that tells you when an update is available, and nothing in the repository suggests it restarts or recreates containers.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 27 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Diun watches, and who needs it
A container image reference such as a base image tag can move without anything in your deployment changing. The tag stays the same, the digest behind it does not. If you pin by tag, you inherit that drift silently. Diun exists to make the drift visible: the README states that it checks registries for new tags or digest changes so you can track base image updates, application releases and security rebuilds without manually checking every repository. The audience is self-hosted and automated environments, which the README names explicitly. That covers a homelab running Docker or Swarm, a Nomad or Kubernetes cluster, and small teams who want an audit trail of what changed upstream rather than a tool that mutates running workloads. Diun is a single Go binary or a Docker image, so it fits where you already run containers and do not want another agent with privileged access to the host.
The mechanism: registry checks, a local database, and providers
Diun does not sit in the pull path. It periodically resolves each configured image reference against its registry and compares the result with what it recorded last time. A change in the tag list or in the digest is what triggers a notification. State lives in a local bbolt database, which the go.mod lists as go.etcd.io/bbolt, so the comparison has memory across restarts. That database file is the thing to back up and the thing to mount on persistent storage; if it is lost, Diun has no baseline and behaves like a fresh install. Notification delivery is split into providers, and the dependency list shows how wide that surface is: Telegram through gotgbot, Slack through nlopes/slack, MQTT through paho, AMQP through rabbitmq/amqp091-go, mail through wneessen/go-mail, plus HTTP-based services. Metrics are exposed through prometheus/client_golang and health through crazy-max/gohealthchecks. The scheduler is a fork of the cron library, and the config loader is crazy-max/gonfig, which is why the same file can be supplied as YAML, JSON or TOML. Registry access is not limited to Docker Hub: podman image libraries, containerd APIs and the OCI image spec and go-digest packages are all in the dependency tree, which is consistent with the README's claim that Diun connects to container platforms and config files.
Installing Diun and sending a first notification
The README points to two distribution paths: a standalone executable from the releases page and a Docker image at crazymax/diun on Docker Hub. The documentation site at crazymax.dev/diun is where the configuration reference lives. The repository's Dockerfile builds the binary with xx-go build -trimpath and verifies it as a static executable, and the Makefile exposes a vendor target that runs docker buildx bake, so building from source is expected to go through Docker rather than a bare go build. The README does not print a run command, so the shape below follows the image name the README gives and the config file the documentation describes; check the documentation for the exact keys your version expects. Because the README does not show a full example config, the safest first step is to read the docs page for the provider you intend to use and start with a single image and a single provider, then confirm the notification arrives before adding more. The repository layout is a useful map while you do that: cmd holds the binary entry point, internal and pkg hold the implementation, docs holds the documentation source, and the committed vendor directory means the dependency set is fixed at build time. If you run the published image, the only decisions you make are which config file to mount and where the database file should live.
Where Diun stops: it notifies, it does not update
The name of the project and the word update sit close together, and that causes the most common misreading. Diun watches and tells you. Nothing in the README describes pulling, recreating or restarting a container. If your actual problem is that a service is running an old image and you want it replaced automatically, Diun is the wrong tool and will leave you with a mailbox full of alerts and unchanged workloads. There is a second boundary: a notification only exists if a provider is configured and reachable. The README does not document rollback, retry semantics for failed deliveries, or what happens to a notification that fails while a provider is down. The bbolt database means a lost or unwritable data volume silently resets the baseline, and the next check will not report a change because there is nothing to compare against. Neither the README nor the repository layout tells you how Diun behaves when a registry is unreachable or rate-limits the check, so plan for that gap rather than assuming it is handled.
Diun versus Watchtower: watch and report against pull and replace
The comparison people reach for is Watchtower, and the difference is architectural rather than a matter of features. Watchtower operates on your local Docker daemon: it pulls a newer image and recreates the container so the running workload moves forward. Diun operates on registries: it resolves remote references, compares them with a stored baseline, and sends a message. One changes your system, the other describes it. That makes them complementary rather than competing. A team that wants zero-touch updates on a homelab picks Watchtower. A team that needs to know a base image was rebuilt for a security fix, and wants a human or a pipeline to decide when to redeploy, picks Diun. Running both is coherent: Diun tells you what moved, Watchtower or your CI applies it. The trade-off is latency and control. Watchtower acts within its own polling window; Diun waits for a person or an automation to respond, which is slower but auditable.
Maintenance, licensing and what an upgrade costs you
The repository is not archived, and the last push was on 2026-09-03. Releases are frequent enough that version drift matters: v4.31.0 landed on 2025-12-24, v4.32.0 on 2026-05-28 and v4.33.0 on 2026-05-30. The Go module path is versioned as github.com/crazy-max/diun/v4, and go.mod targets Go 1.26.0, so anyone building from source needs a matching toolchain. The Makefile's vendor target runs docker buildx bake, which means vendoring is expected to happen through Docker rather than a bare go mod vendor, and the vendor directory is committed. The Dockerfile builds with CGO disabled and verifies a static binary, so the shipped artifact has no libc dependency. Upgrading carries a config-migration risk: the notification providers are numerous and each has its own block, and a release can change how those blocks are parsed. Read the CHANGELOG before bumping the image tag. The licence is MIT, which is permissive and imposes no copyleft obligation on your own code; the LICENSE file is the authoritative text, and this is not legal advice.
Editorial conclusion
Adopt Diun if you want a record of image drift and already have a notification channel such as Gotify, Slack, Telegram, Discord, Rocket.Chat, Pushover, MQTT, AMQP or email, and if you accept that acting on the alert is your job. Do not adopt it expecting an automatic updater: the README describes a watcher that tells you when an update is available, and nothing in the repository suggests it restarts or recreates containers. Before rolling it out, verify which providers your config actually enables, whether the bbolt database path is on persistent storage, and what the healthchecks and Prometheus endpoints expose, because those three things determine whether a missed notification is visible to you or silent.
Frequently asked questions
What does "docker DinD" mean?
Diun does not use Docker-in-Docker. It runs as a single executable or as the crazymax/diun Docker image and watches registries for tag or digest changes, which is a different concern from running a Docker daemon inside a container.
Is Docker Hub free or paid?
The README does not state Docker Hub pricing. It only notes that Diun publishes an image at crazymax/diun on Docker Hub and that Diun can check registries for new tags or digest changes.
What is the difference between a digest and an image ID?
The README does not define the difference. It does say Diun checks registries for new tags or digest changes, and its dependency list includes the OCI image spec and go-digest packages.
What is Docker Hub used for?
The README does not explain Docker Hub's purpose. It only says Diun's Docker image is published there as crazymax/diun, alongside a standalone executable on the releases page.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/crazy-max-diun)