Replaced Watchtower (auto-updater) with Diun (notification-only) for safer update management in production environments. Why the change: - Watchtower auto-updates can break production systems - Discord webhook integration was problematic with Watchtower - Diun provides notifications without auto-updating (safer) - Diun uses Discord webhook URLs directly (no Shoutrrr conversion) - Better control over when and how updates are applied Changes in arr-stack_template.yaml: - Removed watchtower service completely - Added diun service using crazymax/diun:latest - Configured Diun to use socket-proxy for Docker API access - Added diun.enable=true labels to 11 monitored services: * gluetun, qbittorrent, flaresolverr, sabnzbd * prowlarr, radarr, sonarr, bazarr * emby, jellyseerr, recyclarr - Diun configured with: * Watch by default: false (only labeled containers) * Discord notifications with render fields * Schedule-based checking * Memory limit: 128M (vs Watchtower's 256M) Changes in .env.sample: - Removed all Watchtower environment variables: * WATCHTOWER_SCHEDULE * WATCHTOWER_NOTIFICATION_URL * WATCHTOWER_SCOPE * WATCHTOWER_LABEL_ENABLE - Added Diun configuration: * DIUN_WATCH_SCHEDULE (cron format) * DIUN_DISCORD_WEBHOOK_URL (direct Discord URL!) - Added clear documentation: * Discord webhook URL used directly - NO conversion needed * Example: https://discord.com/api/webhooks/ID/TOKEN * Default schedule: every 6 hours (0 */6 * * *) Documentation updates: - Created comprehensive docs/DIUN.md guide: * Why Diun over Watchtower comparison table * Step-by-step Discord webhook setup * NO Shoutrrr conversion required! * Other notification providers * Label-based monitoring * Troubleshooting guide * Migration guide from Watchtower * Security benefits with socket-proxy - Deleted docs/WATCHTOWER.md - Updated README.md: * Replaced all Watchtower references with Diun * Updated troubleshooting section * Updated best practices * Updated documentation links * Fixed example commands (docker logs diun) Key Benefits: 1. Safer: Notifications only, you control when to update 2. Simpler: Discord webhooks work directly (no format conversion) 3. Flexible: Label-based control over what to monitor 4. Lighter: Uses less memory (128M vs 256M) 5. Professional: Better for production environments Discord Webhook Comparison: - Watchtower: discord://TOKEN@ID (Shoutrrr format, complex) - Diun: https://discord.com/api/webhooks/ID/TOKEN (direct, simple) Migration path: 1. Remove watchtower from compose 2. Update .env with DIUN_ variables 3. Use Discord webhook URL directly 4. Regenerate compose file 5. Deploy with docker-compose up -d Breaking change: Users must update .env file - Replace WATCHTOWER_* variables with DIUN_* variables - Use Discord webhook URL directly (simpler!) Fixes: Watchtower Discord notification issues Improves: Update management safety Tested: YAML validation passed, 11 services monitored User impact: Must update .env and regenerate compose files
10 KiB
Diun Configuration Guide
Diun (Docker Image Update Notifier) monitors your Docker containers for available image updates and sends notifications. Unlike Watchtower, Diun does NOT auto-update - it only notifies you, giving you full control.
Table of Contents
- Why Diun Over Watchtower
- Basic Configuration
- Discord Notifications
- Other Notification Services
- Advanced Configuration
- Troubleshooting
Why Diun Over Watchtower
| Feature | Diun | Watchtower |
|---|---|---|
| Updates containers | ❌ No (notify only) | ✅ Yes (auto-updates) |
| Safety | ✅ You control when to update | ⚠️ Auto-updates can break things |
| Discord webhooks | ✅ Direct URL (simple) | ❌ Requires Shoutrrr conversion |
| Notification options | ✅ Many providers | ✅ Many providers |
| Resource usage | ✅ Lightweight | ✅ Lightweight |
| Best for | Production environments | Home labs |
Recommendation: Diun is safer for production. You get notified, review changes, then manually update.
Basic Configuration
Schedule
Set check schedule in .env using cron format:
# Every 6 hours
DIUN_WATCH_SCHEDULE=0 */6 * * *
# Daily at 4 AM
DIUN_WATCH_SCHEDULE=0 0 4 * * *
# Every Sunday at 3 AM
DIUN_WATCH_SCHEDULE=0 0 3 * * SUN
Cron format: minute hour day-of-month month day-of-week
Disable Notifications
Leave the webhook URL empty to run without notifications:
DIUN_DISCORD_WEBHOOK_URL=
Diun will still log updates to console (check with docker logs diun).
Discord Notifications
Step 1: Create Discord Webhook
- Open Discord and go to your server
- Click Server Settings (gear icon)
- Go to Integrations → Webhooks
- Click New Webhook or Create Webhook
- Configure:
- Name:
Diun - Channel: Select where notifications should go
- Name:
- Click Copy Webhook URL
You'll get a URL like:
https://discord.com/api/webhooks/WEBHOOK_ID/WEBHOOK_TOKEN
Step 2: Add to .env File
NO CONVERSION NEEDED! Just paste the Discord URL directly:
DIUN_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/WEBHOOK_ID/WEBHOOK_TOKEN
That's it! Unlike Watchtower, Diun uses Discord URLs directly.
Step 3: Update Configuration
Edit your .env file:
DIUN_WATCH_SCHEDULE=0 */6 * * *
DIUN_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_TOKEN
Step 4: Restart Diun
docker-compose restart diun
Check logs to verify:
docker logs diun
You should see:
Diun version X.X.X
Loaded 11 containers to watch
Test Notification
To test immediately without waiting for the schedule:
docker exec diun diun notif test
This sends a test notification to your Discord channel.
Notification Examples
What Notifications Look Like
When an update is available, you'll receive a Discord message like:
🔔 Image Update Available
Image: ghcr.io/hotio/sonarr
Current: release-4.0.0.738
Latest: release-4.0.1.1234
Container: sonarr
With DIUN_NOTIF_DISCORD_RENDERFIELDS=true, you get a nice formatted embed with fields.
Other Notification Services
Telegram
DIUN_NOTIF_TELEGRAM_TOKEN=your_bot_token
DIUN_NOTIF_TELEGRAM_CHATIDS=your_chat_id
Slack
DIUN_NOTIF_SLACK_WEBHOOKURL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
Email (SMTP)
DIUN_NOTIF_MAIL_HOST=smtp.gmail.com
DIUN_NOTIF_MAIL_PORT=587
DIUN_NOTIF_MAIL_USERNAME=your-email@gmail.com
DIUN_NOTIF_MAIL_PASSWORD=your-app-password
DIUN_NOTIF_MAIL_FROM=your-email@gmail.com
DIUN_NOTIF_MAIL_TO=recipient@example.com
Pushover
DIUN_NOTIF_PUSHOVER_TOKEN=your_app_token
DIUN_NOTIF_PUSHOVER_RECIPIENT=your_user_key
Gotify
DIUN_NOTIF_GOTIFY_ENDPOINT=https://gotify.example.com
DIUN_NOTIF_GOTIFY_TOKEN=your_token
For complete list: https://crazymax.dev/diun/notif/overview/
Advanced Configuration
Control What's Monitored
By default, only containers with diun.enable=true label are monitored:
labels:
- "diun.enable=true"
To monitor ALL containers by default:
DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=true
Then exclude specific containers:
labels:
- "diun.enable=false"
Watch Specific Tags
Monitor specific image tags instead of latest:
labels:
- "diun.enable=true"
- "diun.watch_repo=true"
- "diun.include_tags=^\\d+\\.\\d+\\.\\d+$" # Semantic versions only
Custom Check Intervals Per Container
labels:
- "diun.enable=true"
- "diun.watch_schedule=0 0 * * *" # Daily for this container
Notification Threshold
Only notify if image is older than a certain time:
labels:
- "diun.enable=true"
- "diun.max_diff_hours=24" # Only notify if update is >24h old
Filter by Platform
Only watch specific platform images:
DIUN_WATCH_WORKERS=20
DIUN_WATCH_SCHEDULE=0 */6 * * *
DIUN_WATCH_FIRSTCHECKNOTIF=false # Don't notify on first check
Troubleshooting
No Notifications Received
Check Diun is running:
docker ps | grep diun
Check Diun logs:
docker logs diun
Look for:
Loaded X containers to watch
Verify webhook URL:
# Test Discord webhook manually
curl -X POST "YOUR_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{"content":"Test from Diun setup"}'
You should see the test message in Discord.
Common issues:
- Webhook URL is empty or incorrect
- Discord webhook was deleted
- No containers have
diun.enable=truelabel - Socket-proxy not running (Diun can't access Docker)
Diun Not Finding Containers
Verify socket-proxy connectivity:
docker logs diun | grep -i error
docker logs socket-proxy
Check labels:
docker inspect CONTAINER_NAME | grep -A 5 Labels
Should show:
"Labels": {
"diun.enable": "true",
...
}
Too Many Notifications
Increase check interval:
DIUN_WATCH_SCHEDULE=0 0 4 * * * # Once daily at 4 AM
Or add threshold:
labels:
- "diun.max_diff_hours=72" # Only notify if update >3 days old
Or disable first-check notifications:
DIUN_WATCH_FIRSTCHECKNOTIF=false
Discord Webhook Fails
Error: webhook URL is required
Fix: Ensure .env has:
DIUN_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/ID/TOKEN
Error: 401 Unauthorized
Fix: Webhook was deleted or token is wrong. Create a new webhook in Discord.
Error: 404 Not Found
Fix: Webhook ID is wrong. Copy the URL again from Discord.
Test Individual Container
Force check a specific container:
# Check all watched containers now
docker exec diun diun exec
# Test notification system
docker exec diun diun notif test
Migration from Watchtower
If you're migrating from Watchtower:
1. Remove Watchtower
docker-compose stop watchtower
docker-compose rm watchtower
2. Update .env
Replace:
WATCHTOWER_SCHEDULE=0 0 4 * * *
WATCHTOWER_NOTIFICATION_URL=discord://TOKEN@ID
With:
DIUN_WATCH_SCHEDULE=0 */6 * * *
DIUN_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/ID/TOKEN
3. Update Labels
Watchtower labels like:
labels:
- "com.centurylinklabs.watchtower.enable=true"
Are NOT used by Diun. The template already has diun.enable=true labels.
4. Deploy Diun
./substitute_env.sh arr-stack
docker-compose up -d
5. Verify
docker logs diun
Examples
Minimal Setup
# .env
DIUN_WATCH_SCHEDULE=0 0 4 * * *
DIUN_DISCORD_WEBHOOK_URL=
No notifications, just logs.
Production Setup
# .env
DIUN_WATCH_SCHEDULE=0 */6 * * *
DIUN_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/123/abc
Check every 6 hours, notify to Discord.
Conservative Monitoring
# .env
DIUN_WATCH_SCHEDULE=0 0 3 * * SUN
DIUN_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/123/abc
Check weekly on Sunday at 3 AM.
Best Practices
- Don't auto-update - Diun's strength is manual control
- Check logs first - Review what changed before updating
- Test updates in dev - Don't update production blindly
- Use semantic versioning - Pin to major versions when possible
- Monitor critical services - Add
diun.enable=trueto important containers - Regular schedule - Every 6 hours catches updates quickly
- Backup before updates - Always backup configs before updating
Security
Why Socket-Proxy?
Diun needs read-only Docker API access to:
- List containers
- Get container labels
- Get image information
Socket-proxy provides:
- ✅ Read-only access
- ✅ No execute permissions
- ✅ No secrets access
- ✅ Network isolation
What Diun Can Do
With socket-proxy, Diun can:
- ✅ List containers (CONTAINERS=1)
- ✅ Get image info (IMAGES=1)
With socket-proxy, Diun CANNOT:
- ❌ Execute commands in containers (EXEC=0)
- ❌ Access secrets (SECRETS=0)
- ❌ Modify containers
- ❌ Delete containers
References
- Diun Documentation: https://crazymax.dev/diun/
- Notification Providers: https://crazymax.dev/diun/notif/overview/
- Configuration Options: https://crazymax.dev/diun/config/
- Docker Provider: https://crazymax.dev/diun/providers/docker/
- Discord Webhooks: https://support.discord.com/hc/en-us/articles/228383668
Quick Reference
Common Commands
# View logs
docker logs diun
# Follow logs live
docker logs -f diun
# Restart Diun
docker-compose restart diun
# Force check now
docker exec diun diun exec
# Test notifications
docker exec diun diun notif test
# Check which containers are monitored
docker ps --filter "label=diun.enable=true"
Environment Variables Quick Reference
# Required
DIUN_WATCH_SCHEDULE=0 */6 * * *
# Discord (optional)
DIUN_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/ID/TOKEN
# Docker provider (already configured in template)
DIUN_PROVIDERS_DOCKER=true
DIUN_PROVIDERS_DOCKER_ENDPOINT=tcp://socket-proxy:2375
DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=false
# Logging (optional)
LOG_LEVEL=info
LOG_JSON=false
Label Quick Reference
# Enable monitoring
labels:
- "diun.enable=true"
# Custom schedule for this container
labels:
- "diun.enable=true"
- "diun.watch_schedule=0 0 * * *"
# Watch all tags, not just latest
labels:
- "diun.enable=true"
- "diun.watch_repo=true"
# Only notify if update is >24h old
labels:
- "diun.enable=true"
- "diun.max_diff_hours=24"