Here are practical Diun configuration examples tailored for self-hosting (Docker Compose + local Docker provider). These are pulled straight from the official docs and reflect the most common homelab setups.
Diun is super flexible — you can configure it entirely with environment variables (easiest) or a diun.yml file (cleaner for complex setups). Both approaches are equivalent.
1. Minimal Docker Compose (Environment Variables Only) — Recommended Starting Point
This watches all running containers by default every 6 hours and uses the Docker socket.
name: diun
services:
diun:
image: crazymax/diun:latest
container_name: diun
command: serve
volumes:
- "./diun-data:/data" # Persistent database
- "/var/run/docker.sock:/var/run/docker.sock:ro"
environment:
- TZ=Asia/Kolkata # Change to your timezone
- LOG_LEVEL=info
- LOG_JSON=false
# Watch settings
- DIUN_WATCH_WORKERS=20
- DIUN_WATCH_SCHEDULE=0 */6 * * * # Every 6 hours
- DIUN_WATCH_JITTER=30s
- DIUN_WATCH_FIRSTCHECKNOTIF=false # Don't notify on first run
- DIUN_WATCH_RUNONSTARTUP=true
# Docker provider
- DIUN_PROVIDERS_DOCKER=true
- DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=true # Watch ALL containers
# Optional: Only watch containers that have the label (safer)
# - DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=false
restart: unless-stopped
How to use:
- Create a folder (e.g.
~/diun/), drop this as docker-compose.yml, run docker compose up -d.
- Diun will automatically monitor any container that has the label
diun.enable=true (or all if WATCHBYDEFAULT=true).
2. Full Example with Config File + Notifications (Most Popular Setup)
Many people prefer this for readability and adding multiple notifiers.
docker-compose.yml
name: diun
services:
diun:
image: crazymax/diun:latest
container_name: diun
command: serve
volumes:
- "./diun-data:/data"
- "./diun.yml:/diun.yml:ro" # Your config
- "/var/run/docker.sock:/var/run/docker.sock:ro"
environment:
- TZ=Asia/Kolkata
- LOG_LEVEL=info
- LOG_JSON=false
restart: unless-stopped
diun.yml (in the same folder)
db:
path: diun.db
watch:
workers: 20
schedule: "0 */6 * * *" # Every 6 hours (or "0 0 * * *" for daily at midnight)
jitter: 30s
firstCheckNotif: false
runOnStartup: true
defaults:
watchRepo: false # Only watch the exact tag, not the whole repo
notifyOn:
- new
- update
providers:
docker:
watchByDefault: false # Safer: only containers with label diun.enable=true
# watchStopped: true # Uncomment to also check stopped containers
# Example notifications - pick ONE or more
notif:
# Gotify (very popular in self-hosting)
gotify:
endpoint: http://gotify.yourdomain.com
token: your-gotify-token-here
priority: 5
timeout: 10s
# OR Telegram
# telegram:
# token: 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
# chatIDs:
# - 123456789
# timeout: 10s
# OR Discord
# discord:
# webhookURL: https://discord.com/api/webhooks/...
# timeout: 10s
# OR ntfy.sh (simple, no account needed)
# ntfy:
# endpoint: https://ntfy.sh
# topic: my-diun-alerts
# priority: 3
3. How to Tell Diun Which Containers to Watch (Labels)
Add these labels to any service in your other docker-compose files:
services:
your-app:
image: linuxserver/sonarr:latest
labels:
- diun.enable=true # Required
- diun.watch_repo=false # Optional overrides
- diun.notify_on=new,update
Pro tip: If you set watchByDefault: true, you don’t even need the label on every container.
Quick Tips for Self-Hosters
- Data persistence: The
/data volume stores the database so Diun remembers what it has already seen.
- Schedule:
0 */6 * * * = every 6 hours. Use 0 0 * * * for once per day at midnight.
- Security: Run Diun with the read-only socket mount (
:ro).
- File provider alternative: If you prefer a static list instead of labels, use the
file provider and point to a images.yml with explicit image names.
- Test it: After starting, check logs with
docker logs diun — you should see it scanning.
1. Diun with Multiple Notifiers (Gotify + Telegram + Discord + ntfy)
You can define as many notifiers as you want under the notif: section. Diun sends the same update message to all of them.
diun.yml (full example)
db:
path: diun.db
watch:
workers: 20
schedule: "0 */6 * * *" # every 6 hours
jitter: 30s
firstCheckNotif: false
runOnStartup: true
defaults:
watchRepo: false
notifyOn:
- new
- update
providers:
docker:
watchByDefault: false # only containers with diun.enable=true label
# ── MULTIPLE NOTIFIERS ─────────────────────────────────────
notif:
gotify:
endpoint: http://gotify.yourdomain.com
token: A1234567890abcdef
priority: 5
timeout: 10s
telegram:
token: 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
chatIDs:
- 123456789 # your personal chat
- -987654321 # optional group chat (negative ID)
timeout: 10s
discord:
webhookURL: https://discord.com/api/webhooks/...
timeout: 10s
ntfy:
endpoint: https://ntfy.sh
topic: my-diun-alerts
priority: 3
tags: ["docker", "update"]
timeout: 10s
Just mount this file as before. Diun will fire notifications to all four services whenever an update is found.
2. File Provider Setup (Static Image List – No Docker Labels Needed)
Perfect if you want a central static list instead of (or in addition to) labels on every container.
docker-compose.yml (same as before, just change providers)
services:
diun:
image: crazymax/diun:latest
volumes:
- "./diun-data:/data"
- "./diun.yml:/diun.yml:ro"
- "./images:/images:ro" # ← folder for static list
- "/var/run/docker.sock:/var/run/docker.sock:ro"
# ... environment and restart same
diun.yml
# ... db, watch, defaults same as above ...
providers:
file:
directory: /images # Diun will read every *.yml in this folder
# Optional: you can also put images directly here (newer Diun versions support it)
# images:
# - name: nginx:1.27-alpine
# - name: postgres:16-alpine
Create a folder ./images/ next to diun.yml and drop one or more files like this:
images/my-stack.yml
- name: linuxserver/sonarr:develop
watchRepo: true
notifyOn: [new, update]
- name: postgres:16-alpine
- name: your-private-registry.com/app:1.2.3
regopt: myprivate # see section 3 below
This is great for servers where you don’t want to touch every compose file.
3. Registry Auth for Private Registries (regopts)
Add this top-level section to diun.yml:
regopts:
- name: "myprivate" # reference name
username: myuser
password: supersecret
timeout: 30s
insecureTLS: false # set true for self-signed certs
- name: "docker.io" # optional: override Docker Hub rate limits
selector: image
username: yourdockerhubuser
password: yourdockerhubpat
- name: "ghcr.io" # GitHub Container Registry example
username: yourgithubuser
passwordFile: /run/secrets/ghcr_pat # safer than plain text
Then reference it in any image (File provider or Docker label):
Alternative (even simpler): Just mount your existing Docker credentials:
volumes:
- "/root/.docker/config.json:/root/.docker/config.json:ro"
Diun will automatically use them.
4. How to Combine Diun with Renovate (Best Self-Hosting Workflow)
This is the sweet spot most people run today:
- Renovate = Git-based updater (opens PRs for your
docker-compose.yml files)
- Diun = Runtime notifier (tells you when new images are available, even if Renovate hasn’t merged yet)
Typical setup:
-
Put all your compose files in a private Git repo (Gitea, GitHub, etc.).
-
Install Renovate (self-hosted or GitHub App) with a config like:
{
"extends": ["config:recommended"],
"docker-compose": {
"fileMatch": ["(^|/)(?:docker-)?compose[^/]*\\.ya?ml$"]
},
"packageRules": [
{
"matchUpdateTypes": ["patch", "minor"],
"automerge": true,
"automergeType": "branch"
}
]
}
Renovate will automatically bump image tags (e.g. nginx:1.26 → nginx:1.27) and create PRs.
-
Run Diun exactly as above (Docker provider + labels or File provider).
-
Optional: Add a label in your compose files so Diun ignores Renovate-managed images if you want:
labels:
- diun.enable=true
- diun.watchRepo=false # only exact tag, not whole repo
Workflow you’ll actually use:
- Renovate opens a PR every few days → you review/merge (or auto-merge patch versions).
- Diun pings you on Gotify/Telegram/etc. the moment a newer image appears (great for critical security updates).
- You
git pull && docker compose up -d once a week.
This gives you audit trail + automatic PRs + instant notifications with almost zero manual work.