Diun - get notified when your Docker images have updates#
What is Diun#
Diun (Docker Image Update Notifier) is an open-source tool from CrazyMax that keeps an eye on your Docker images and pings you the moment a new version drops.
Crucially, Diun doesn’t touch your containers - it just flags that a new image version is out there and leaves the actual updating to you. That matters a lot if you’d rather control when and how updates happen instead of getting surprised in production.
That’s the big difference from something like Watchtower, which doesn’t stop at checking - it goes ahead and installs the new version for you, whether you asked it to or not.
linuxserver.io actually recommends Diun as its go-to container monitoring tool.
Why bother with Diun#
Whether you’re running a home server, a Proxmox cluster, or just a handful of containers on a VPS, your images will get stale sooner or later. And checking for updates by hand, one by one, gets old fast.
Diun takes that off your plate:
- Checks Docker Hub, GHCR, Quay.io, GitLab, and private registries
- Runs on a cron schedule or at startup
- Sends notifications through dozens of services
- Supports filters and tags
- Can track containers, compose files, stacks, or registry lists
Installing Diun with Docker Compose#
Create a directory and a docker-compose.yml file inside it.
Here’s the exact compose file I used in the video.
services:
diun: # Define the Diun service within Docker Compose
image: crazymax/diun:latest # Official Diun image from Docker Hub
container_name: diun # Container name (convenient for `docker ps`)
command: serve # Main command - start Diun's web/cron service
volumes:
- "/path/to/user/directory/data:/data" # Local directory for storing Diun's database and configuration
- "/var/run/docker.sock:/var/run/docker.sock" # Access to the Docker API for tracking images and containers
environment:
- "TZ=Europe/Moscow" # Set the timezone (important for cron and timestamps)
- "LOG_LEVEL=info" # Logging level: trace | debug | info | warn | error | fatal | panic
- "DIUN_WATCH_WORKERS=50" # Number of parallel workers when checking images (speeds things up with many containers)
- "DIUN_WATCH_SCHEDULE=0 */6 * * *" # Cron schedule: check for updates every 6 hours
- "DIUN_WATCH_JITTER=30s" # Adds a random delay (up to 30 seconds) to avoid multiple jobs starting at the same time
- "DIUN_WATCH_RUNONSTARTUP=true" # Run a check right at container startup, without waiting for the schedule
- "DIUN_PROVIDERS_DOCKER=true" # Enables the Docker provider: Diun will track images of running containers
- "DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=true" # Enables monitoring of all containers by default, without needing to manually set the `diun.enable=true` label
# --- Telegram notification settings ---
- "DIUN_NOTIF_TELEGRAM_TOKEN=token" # Telegram bot token created via @BotFather
- "DIUN_NOTIF_TELEGRAM_CHATIDS=chatid" # Chat or user ID to send notifications to (multiple can be specified, comma-separated)
# --- Gotify notification settings ---
- "DIUN_NOTIF_GOTIFY_ENDPOINT=https://gotify.domain.ru" # URL of your Gotify server
- "DIUN_NOTIF_GOTIFY_TOKEN=token" # Gotify app token (created in the Gotify web interface)
- "DIUN_NOTIF_GOTIFY_PRIORITY=1" # Notification priority (0 - low, 5 - high)
- "DIUN_NOTIF_GOTIFY_TIMEOUT=10s" # Timeout for waiting on Gotify's response when sending a notification
labels:
- "diun.enable=true" # Label that allows Diun to track this container (optional if `WATCHBYDEFAULT=false`)
restart: always # Restart the container on failure or Docker host rebootOn first launch, Diun creates a data/diun.db database and starts monitoring every Docker container it can see. If you want the play-by-play, check the app’s logs.
Diun has a lot of knobs to turn - here’s a rundown of the ones actually worth knowing about.
Operating modes#
- Watch - Diun periodically sweeps through all your containers checking for updates.
- Events - triggers whenever a container starts, and checks if a newer image is out.
- Database mode - remembers the state of every image it’s already checked, so it won’t spam you with the same notification twice.
Container labels#
Want to be picky about what gets tracked? Add this to your docker-compose.yml:
labels:
- "diun.enable=true" or flip it around and exclude the ones you don’t care about.
Providers#
Diun can pull its list of what to watch from several different sources:
docker- talks to your local Docker daemonswarm- tracks images across a Docker Swarmfile- a plain list of images in a YAML filekubernetes- (still experimental) checks images running in podswatchtower- imports whatever config you already have in Watchtower
Here’s what a YAML provider config looks like:
db:
path: diun.db
watch:
workers: 20
schedule: "0 */6 * * *"
regopts:
- name: "myregistry"
username: fii
password: bor
timeout: 5s
- name: "docker.io/crazymax"
selector: image
username: fii
password: bor
- name: "docker.io"
selector: image
username: foo
password: bar
providers:
file:
filename: /path/to/config.yml### /path/to/config.yml
# Watch latest tag of crazymax/nextcloud image on docker.io (DockerHub)
# with registry options named 'docker.io/crazymax' (image selector).
- name: docker.io/crazymax/nextcloud:latest
# Watch 4.0.0 tag of jfrog/artifactory-oss image on frog-docker-reg2.bintray.io (Bintray)
# with registry options named 'myregistry' (name selector).
- name: jfrog-docker-reg2.bintray.io/jfrog/artifactory-oss:4.0.0
regopt: myregistry
# Watch coreos/hyperkube image on quay.io (Quay) and assume latest tag.
# Add foo=bar metadata to be used in notification template.
- name: quay.io/coreos/hyperkube
metadata:
foo: bar
# Watch crazymax/swarm-cronjob image and assume docker.io registry and latest tag
# with registry options named 'docker.io/crazymax' (image selector).
# Only include tags matching regexp ^1\.2\..* and only be notified on new tag.
- name: crazymax/swarm-cronjob
watch_repo: true
notify_on:
- new
include_tags:
- ^1\.2\..*
# Watch portainer/portainer image on docker.io (DockerHub) and assume latest tag
# with registry options named 'docker.io' (image selector).
# Only watch latest 10 tags and include tags matching regexp ^\d+\.\d+\..*
- name: docker.io/portainer/portainer
watch_repo: true
max_tags: 10
include_tags:
- ^\d+\.\d+\..*
# Watch alpine image (library) and assume docker.io registry and latest tag
# with registry options named 'docker.io' (image selector).
# Force linux/arm64/v8 platform for this image
- name: alpine
watch_repo: true
platform:
os: linux
arch: arm64
variant: v8There’s more detail on this in the official docs.
Notifications#
Diun can push notifications to more than 15 different services:
| Service | Environment variables |
|---|---|
| Telegram | DIUN_NOTIF_TELEGRAM_TOKEN, DIUN_NOTIF_TELEGRAM_CHATIDS |
| Discord | DIUN_NOTIF_DISCORD_WEBHOOKURL |
| Gotify | DIUN_NOTIF_GOTIFY_ENDPOINT, DIUN_NOTIF_GOTIFY_TOKEN |
| Slack | DIUN_NOTIF_SLACK_WEBHOOKURL |
DIUN_NOTIF_MAIL_SMTP_HOST, DIUN_NOTIF_MAIL_FROM, DIUN_NOTIF_MAIL_TO | |
| Webhook | DIUN_NOTIF_WEBHOOK_ENDPOINT |
You’re not limited to just one either - I’ve got several wired up at once in my own compose file.
Wrapping up#
Diun is basically a must-have if you’re running Docker anywhere in your self-hosted setup. It’s lightweight, rock-solid, doesn’t demand any elaborate setup, and slots in cleanly alongside whatever other DevOps tooling you’re already running.
If staying on top of your infrastructure matters to you, Diun is what tells you an update landed before it becomes a surprise.




