Get Docker Image Update Alerts with Diun
Use Diun to get Docker image update alerts without giving a container permission to restart your self-hosted apps.
Automatic Docker updates sound responsible until an application restarts halfway through a database migration, or a new major release changes an environment variable you had forgotten existed. Blindly updating every container is not maintenance. It is gambling with better branding.
Diun takes the calmer route. It watches the image tags you already run and sends a notification when an upstream image digest changes. You decide whether and when to pull, read the release notes, and restart the stack.
That separation matters. I prefer an alert at breakfast to discovering an unavailable service after an unattended update at 3 a.m.
What Diun does - and what it deliberately does not
Diun stands for Docker Image Update Notifier. It compares the image digest currently known for a tag such as ghcr.io/immich-app/immich-server:release with the registry’s latest digest, then notifies you when they differ.
It does not pull images, restart containers, or edit Compose files. That is the point. A notification is useful information; an automatic restart is a production decision.
Use Diun when you want to keep control over updates. If you run disposable test services and genuinely want automatic restarts, Watchtower may fit that narrow use case better. For a stack you care about, alerting first is the sane default.
Deploy Diun with Docker Compose
Create a directory for the service and save this as compose.yml:
services:
diun:
image: crazymax/diun:4
container_name: diun
command: serve
volumes:
- ./data:/data
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- TZ=Europe/Paris
- LOG_LEVEL=info
- DIUN_WATCH_WORKERS=10
- DIUN_WATCH_SCHEDULE=0 */6 * * *
- DIUN_PROVIDERS_DOCKER=true
- DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=false
- DIUN_NOTIF_GOTIFY_ENDPOINT=https://gotify.example.com
- DIUN_NOTIF_GOTIFY_TOKEN=${GOTIFY_TOKEN:?set GOTIFY_TOKEN}
restart: unless-stopped
Create a .env file beside it and put your Gotify application token there:
GOTIFY_TOKEN=replace-with-your-gotify-app-token
Then start the notifier:
docker compose up -d
docker compose logs -f diun
The WATCHBYDEFAULT=false setting is intentional. Diun will ignore every container until you explicitly opt it in. A homelab full of old experiments does not need to turn into a notification machine.
This example uses Gotify, but Diun also supports several other notification providers. The official Diun documentation lists the exact environment variables for Discord, Slack, Telegram, email, and more.
Opt in only the containers that matter
Add these labels to a service in its own Compose file:
services:
paperless:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
labels:
- diun.enable=true
# The rest of your Paperless configuration stays here.
Redeploy that stack after saving the labels:
docker compose up -d
Diun discovers the running container through the Docker socket and begins tracking its image. The next scheduled check will notify you only when the digest behind that tag changes.
Read the container log if you do not receive a notification. A bad Gotify endpoint, an expired token, or DNS that works on the host but not in containers are much more common than a Diun bug.
Pin versions when you can
A notification is only as meaningful as the tag you follow. latest tells you that something changed, not whether that change is a security patch or a surprise major version.
For most self-hosted applications, I would rather pin a major or release tag, review the upstream release notes, then move it deliberately. For example:
image: ghcr.io/immich-app/immich-server:v2
Exact version pins are even more predictable, but they require you to edit the Compose file for every upgrade. There is no universal answer: use a moving tag for low-risk services, and a pinned version where downtime would ruin your evening.
If your Compose files are in Git, Renovate is a strong companion to Diun. Diun catches changes to the tags you already run; Renovate proposes version bumps as reviewable pull requests. Neither needs permission to restart your server without you looking.
Treat the Docker socket like root access
Diun needs access to the Docker socket to inspect running containers. Mounting it read-only is better than read-write, but it is still sensitive access. Do not expose /var/run/docker.sock through a web interface, and do not casually add socket mounts to containers because a tutorial said so.
For a busier server, put a Docker socket proxy in front of Diun and allow only the API endpoints it needs. That is extra setup, but it limits blast radius if the notifier is ever compromised.
Also keep the notifier itself on a private server network. When you are checking alerts or administering a VPS from café Wi-Fi, protect the administrative path too.
🚀NordVPN
Use a reliable VPN when you need to manage your self-hosted server from an untrusted network.
Affiliate link — we may earn a commission at no extra cost to you.
The update workflow that does not create surprises
When Diun sends an alert, use this short loop:
- Read the upstream changelog and look for breaking changes.
- Back up the application’s data if the update touches a database or storage format.
- Pull and restart one stack at a time.
- Check the health endpoint and container logs before moving on.
Diun is not exciting software. Good maintenance rarely is. But knowing about an update before it changes your server is exactly the kind of boring control self-hosting is supposed to give you.
Try it now: opt in one non-critical container today. Let Diun prove the notification path works before you trust it with the services you actually depend on.
Stay in the loop 📬
Get self-hosting tutorials, tool reviews, and infrastructure tips delivered to your inbox. No spam, unsubscribe anytime.
Join 0 self-hosters. Free forever.