Tutorial

Watchtower vs Diun: managing Docker image updates on a VPS

Deployment8 min read4 steps

Docker images age silently: security patches accumulate, dependencies are affected, and nothing alerts you. Without a process in place, you either never patch or do it manually the day an incident hits. Watchtower and Diun address this problem with two opposing philosophies — one acts for you, the other informs you. This comparison helps you choose based on your context, and accounts for a recent fact: Watchtower was archived by its maintainers at the end of 2025.

Contents· The problem: Docker images aging in silence1/10
  1. 01The problem: Docker images aging in silence
  2. 02Watchtower: automatic updates, but archived since late 2025
  3. 03Watchtower in notify-only mode
  4. 04Diun: alerts only, you stay in control
  5. 05When to choose one or the other
  6. 06Installing Diun on a VPS: practical example
  7. 07Deploy Diun on your VPS
  8. 08Going further: pin versions and stay in control
  9. 09Diun also monitors stopped images
  10. 10Key takeaways from this comparison

The problem: Docker images aging in silence

On a production VPS, Docker containers often run for weeks or months without being updated. This is not negligence — there is simply no signal. The nginx:latest image you pulled in January is still there in September, carrying vulnerabilities that have since been patched.

The cost of inaction is documented: unpatched CVEs in base images are one of the most common entry vectors on self-hosted Docker infrastructure. Manual updates — connecting to the VPS, running docker pull, recreating the container — are the default practice. They are also the least reliable: you postpone, forget, and only update the "important" services.

Two tools have emerged to structure this process: Watchtower, which automates the update itself, and Diun (Docker Image Update Notifier), which sends an alert when a new image is available and leaves the action to your pipeline. They do not do the same thing, and confusing the two philosophies can cost you a production outage.

Watchtower: automatic updates, but archived since late 2025

Watchtower monitors your running containers, queries registries at regular intervals, and as soon as a new image is available, pulls the new tag, stops the existing container and recreates it with the same options — volumes, environment variables, network. All without human intervention.

What it does in practice:

- Configurable polling by duration (every N seconds) or cron expression
- Private registry support with authentication
- WATCHTOWER_NOTIFICATIONS mode to receive alerts without performing updates
- Docker label filtering to include or exclude specific containers

The risk in production is real. If a :latest image introduces an incompatible API change or breaking behavior, Watchtower will recreate your container with that image — without testing, without a maintenance window, potentially at 3 AM. The container restarts with the wrong version, and discovery happens through a monitoring alert or a support call.

Important status update: the Watchtower GitHub repository was archived by its maintainers on late 2025. It is now read-only. The last published version is v1.7.1. The project remains functional and existing Docker images continue to run, but it will no longer receive security fixes, new features, or support for future Docker versions. For a tool whose role is to update your images, the irony is not insignificant.

For development environments or homelabs where convenience outweighs stability, Watchtower remains a legitimate choice. For production, its archival reinforces a conclusion that already existed: automatic updates without a validation pipeline are an operational risk.

Watchtower in notify-only mode

If you already use Watchtower and want to disable automatic updates while keeping notifications, set the variable WATCHTOWER_MONITOR_ONLY=true. The container monitors images and sends alerts but does not act. This is a useful transition configuration if you are migrating to Diun.

Diun: alerts only, you stay in control

Diun (Docker Image Update Notifier) approaches the problem from the other direction: it monitors your images on registries and sends you a notification when a new version is available. It does not act. Your containers keep running unchanged — the decision to update stays in your pipeline.

Licensed under MIT, Diun is actively developed: version la version actuelle was published on recently. The project covers a wide range of sources (Docker, Containerd, Kubernetes, Swarm, Nomad, Dockerfile, configuration file) and notification channels.

Supported notification channels:

- Email, Slack, Telegram, ntfy, Gotify
- Microsoft Teams, Discord, generic webhooks
- Healthchecks.io to monitor the watcher itself

What Diun does not do:

- It never pulls an image
- It never restarts a container
- It never modifies any configuration file

This philosophy is precisely what makes it suitable for production. When Diun signals that a new image is available, you can trigger your usual deployment pipeline — with its tests, prior backup, and maintenance window. You remain in a controlled posture.

Diun is also compatible with stacks managed by tools like Portainer, Coolify or Dokploy: it observes images without interfering with their orchestration.

When to choose one or the other

Scroll the table

ContextWatchtowerDiun
Dev / staging environmentAcceptable (convenience)Overkill
Prod with versioned tags (not :latest)Avoid — recreates on same tagRecommended
Prod with third-party API dependenciesRisky without prior testingRecommended
Homelab / personal servicesPracticalGood if alerts are active
Stack managed by Coolify, Dokploy, PortainerPossible conflict with orchestratorRecommended
Project without a deployment pipelineAcceptable with monitor-onlyRecommended with ntfy/Slack

Installing Diun on a VPS: practical example

Installing Diun takes a few minutes with Docker Compose. The following example monitors all containers on the local Docker socket and sends notifications via ntfy.

Deploy Diun on your VPS

  1. Create the docker-compose.yml file

    Create a dedicated directory and the Compose file:

    mkdir -p /opt/diun && cd /opt/diun

    Content of the docker-compose.yml file:

    services:
      diun:
        image: crazymax/diun:latest
        restart: unless-stopped
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - ./data:/data
        environment:
          - TZ=Europe/Paris
          - LOG_LEVEL=info
          - DIUN_WATCH_WORKERS=20
          - DIUN_WATCH_SCHEDULE=0 */6 * * *
          - DIUN_PROVIDERS_DOCKER=true
          - DIUN_PROVIDERS_DOCKER_WATCHSTOPPED=true
          - DIUN_NOTIF_NTFY_ENDPOINT=https://ntfy.example.com
          - DIUN_NOTIF_NTFY_TOPIC=diun-updates

    Replace ntfy.example.com with the URL of your ntfy instance (self-hosted on the same VPS or external).

  2. Enable label-based monitoring (optional)

    By default, Diun monitors all containers. For finer control, switch to label mode:

    - DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=false

    Then add the label to the containers you want to monitor:

    labels:
      - "diun.enable=true"

    This approach is useful for excluding system containers (proxies, databases) from notifications, and only monitoring application containers.

  3. Start and verify

    docker compose up -d
    docker compose logs -f diun

    Diun performs an initial discovery pass at startup. The logs confirm the images detected and the next monitoring cycle. A test notification can be triggered with:

    docker compose exec diun diun notif test
  4. Trigger the update from your pipeline

    When Diun sends a notification, the update should not be done by hand. The right approach is to trigger your usual pipeline — a Gitea webhook, a GitHub Action, or a Woodpecker job that pulls the new image, runs your tests, and recreates the container.

    If you do not yet have a pipeline, the minimum viable option is a script called from the ntfy webhook:

    #!/bin/bash
    # update-container.sh <container_name>
    CONTAINER=$1
    docker compose -f /opt/${CONTAINER}/docker-compose.yml pull
    docker compose -f /opt/${CONTAINER}/docker-compose.yml up -d

    The key point is that the update is triggered intentionally, not silently.

Going further: pin versions and stay in control

Automatic updates without a fixed tag are the real risk — whether you use Watchtower or a pipeline triggered by Diun. The :latest tag is an alias that can point to any version published by the maintainer. An update to :latest can introduce a breaking change without anything in your configuration changing.

The practice recommended by the Docker community:

Pin versions in your production docker-compose.yml files:

# Avoid in prod
image: nginx:latest

# Prefer a version tag
image: nginx:1.27

Reserve :latest for development and staging environments, where a regression is detectable before it touches production.

With versioned images, Diun detects new releases (new tags) and notifies you — you choose the version to migrate to, update your docker-compose.yml, and deploy with full control. This is what the Docker Compose production checklist calls "declaring your dependencies explicitly".

If you manage multiple containers on the same VPS, a log monitoring tool like Dozzle usefully complements Diun: Diun monitors images upstream, Dozzle observes container logs after an update.

Diun also monitors stopped images

By default, Diun ignores stopped containers. Enable DIUN_PROVIDERS_DOCKER_WATCHSTOPPED=true to also monitor images of paused or stopped containers — useful if you manage batch services or maintenance containers that you restart periodically.

Key takeaways from this comparison

  • Watchtower acts without asking — useful in dev, risky in prod, and archived since late 2025.
  • Diun informs without acting — compatible with any existing deployment pipeline and actively maintained (la version actuelle).
  • For production, Diun coupled with your pipeline is the most robust choice.
  • Pinning versions in docker-compose.yml remains the foundation — neither Watchtower nor Diun replaces explicit tag management.
  • If you have Watchtower in place, WATCHTOWER_MONITOR_ONLY=true mode is an immediate transition to safer behavior.

Launch your Docker stack on a ServOrbit VPS

Root access, NVMe SSD, dedicated IPv4: the conditions to reproduce these examples exactly. Diun and your deployment pipeline run on the same machine as your application containers.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab