Watchtower überwacht eure laufenden Docker-Container und prüft regelmäßig, ob es neue Image-Versionen gibt. Wenn ja, zieht Watchtower das Image und startet den Container neu.
Seit Docker Engine v29 ist die Minimum API Version 1.44 verpflichtend – das kann ältere Tools/Images brechen.
Typische Fehlermeldung dazu:
Error response from daemon: client version 1.25 is too old. Minimum supported API version is 1.44, please upgrade your client to a newer versionCode-Sprache: JavaScript (javascript)
Darum nutzen wir hier den gepflegten Fork nickfedor/watchtower da der ursprüngliche Code nicht mehr zeitnah gepflegt wird (leider selbst festgestellt und siehe Kommentare urspüngliche super Berschreibung).
| Datum | Änderungen |
|---|---|
| 13.01.2026 | Erstellung dieser Anleitung |
Dies ist die ursprüngliche Anleitung, welcher hier als Grundlage dient: https://goneuland.de/docker-images-automatisiert-aktualisieren-mit-watchtower/
1) Grundvoraussetzungen
- Docker Engine + Docker Compose
- Traefik mit Crowdsec ist installiert bspw https://goneuland.de/docker-traefik/
- Traefik läuft bereits und nutzt ein externes Docker-Netzwerk (z. B. proxy)
2) Wichtiger Hinweis vorweg
Watchtower macht automatische Updates! Wenn Watchtower eine Aktualisierung macht und das Latest-Image hat widererwartend einen Fehler könnte es passieren, dass nach der Aktualisierung der Container nicht mehr läuft oder es gar zum Datenverlust kommt!
Warum es sinnvoll ist, Docker-Container/Images regelmäßig zu aktualisieren:
- Security-Fixes: Die meisten Updates schließen Schwachstellen in der App oder in den enthaltenen Libraries/OS-Packages. Je länger du wartest, desto größer das Risiko, dass ein bekannter Exploit bei dir passt.
- Bugfixes & Stabilität: Viele Images beheben Speicherlecks, Crash-Bugs oder Race Conditions erst in späteren Releases.
- Kompatibilität: Docker Engine / Compose / Kernel / Reverse Proxies (Traefik etc.) entwickeln sich weiter. Wenn du Images jahrelang nicht anfässt, werden Upgrades irgendwann schmerzhaft (Breaking Changes “auf einmal”).
- Supply-Chain Hygiene: Images werden neu gebaut, Signaturen/Manifeste ändern sich, Base-Images bekommen Fixes. Regelmäßige Aktualisierung reduziert „technische Schulden“ im Betrieb.
Wann man vorsichtig sein sollte:
- Bei kritischen Services (DB, Mailserver hier Mailcow, Auth, Storage) lieber geplant updaten (Changelog lesen, Backup, Wartungsfenster) oder Images pinnen (Version/Digest) statt dauernd auto-updates.
- Watchtower deshalb am besten Opt-in, plus Notifications, damit du Änderungen mitbekommst.
Container regelmäßig zu aktualisieren ist wichtig, vor allem wegen Security-Fixes und Kompatibilität – mit Opt-in und Benachrichtigungen hältst du das Risiko von “Überraschungs-Updates” klein, ohne dass du alles manuell pflegen musst.
3) Verzeichnis erstellen
Zu erst erstellen wir das passende Verzeichnis:
mkdir -p /opt/containers/watchtower
cd /opt/containers/watchtower
4) Watchtower docker-compose.yml anlegen
Nun legen wir die eigentliche Docker Datei an. Diese dient dazu unseren späteren Container zu erstellen. Referenz: Dokumentation:
nano /opt/containers/watchtower/docker-compose.yml
services:
watchtower:
image: nickfedor/watchtower:latest
container_name: watchtower
restart: unless-stopped
env_file:
- .env
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /etc/localtime:/etc/localtime:ro
# API/Metrics nicht offen ins Internet stellen:
ports:
- "127.0.0.1:8081:8080"
networks:
- proxy
# Wenn du WATCHTOWER_LABEL_ENABLE=true nutzt, muss Watchtower selbst "enabled" sein,
# sonst updated er sich nicht.
labels:
- "com.centurylinklabs.watchtower.enable=true"
networks:
proxy:
external: trueCode-Sprache: PHP (php)
5) .env Datei anlegen
Benachrichtigungen sind optional: Watchtower funktioniert auch ohne Notification-Setup. Sinnvoll sind Notifications aber, damit du nach einem Lauf sofort siehst, ob Updates eingespielt wurden, welche Container betroffen waren und ob es Fehler/Neustart-Probleme gab – statt das erst später über Logs oder einen Ausfall zu merken. in diesem Beispiel ist Shoutrrr aktiv + Notfall-Mail auskommentiert. Siehe weiter unter
nano /opt/containers/watchtower/.env
# --- Opt-in per Label ---
WATCHTOWER_LABEL_ENABLE=true
# --- Zeitplan (6-Feld Cron inkl. Sekunden!) ---
WATCHTOWER_SCHEDULE="0 0 9 * * *"
# --- Verhalten ---
WATCHTOWER_CLEANUP=true
WATCHTOWER_TIMEOUT=30s
WATCHTOWER_INCLUDE_RESTARTING=true
WATCHTOWER_INCLUDE_STOPPED=true
# Wichtig für Stacks mit depends_on / linked containers (z.B. Immich):
# Rolling Restart ist damit nicht kompatibel -> deaktivieren
WATCHTOWER_ROLLING_RESTART=false
# --- Logging/Noise ---
WATCHTOWER_NOTIFICATIONS_LEVEL=info
WATCHTOWER_NO_STARTUP_MESSAGE=false
# --- Notifications (Standard: Shoutrrr / Pushover) ---
WATCHTOWER_NOTIFICATIONS=shoutrrr
WATCHTOWER_NOTIFICATION_URL=pushover://shoutrrr:PUSHOVER_APP_TOKEN@PUSHOVER_USER_KEY
# --- HTTP API / Metrics ---
WATCHTOWER_HTTP_API_METRICS=true
WATCHTOWER_HTTP_API_TOKEN=CHANGE_ME
################################################################################
# NOTFALL: Email Notifications (auskommentiert)
#
# Im nickfedor/watchtower Fork läuft Email über Shoutrrrs SMTP Service.
# Aktivierung:
# 1) WATCHTOWER_NOTIFICATIONS=email setzen (statt shoutrrr)
# 2) SMTP-URL unten entkommentieren und Platzhalter füllen
################################################################################
# WATCHTOWER_NOTIFICATIONS=email
# WATCHTOWER_NOTIFICATION_URL="smtp://SMTP_USER:SMTP_PASS@smtp.example.tld:587/?from=watchtower@example.tld&to=admin@example.tld"Code-Sprache: PHP (php)
Hinweis: Im Fork wird E-Mail über Shoutrrrs SMTP-Service umgesetzt; sowohl Legacy-Email-Variablen als auch Shoutrrr-URLs gehen, URLs sind empfohlen.
6) Watchtower starten
Zum Starten gebt ihr folgendes ein:
docker compose -f /opt/containers/watchtower/docker-compose.yml up -d
docker logs -f watchtower
7) Benachrichtigungen
Benachrichtigungen sind optional, aber sehr empfehlenswert, denn So bekommst du nach jedem Watchtower-Durchlauf direkt eine kurze Meldung, ob Updates gefunden und eingespielt wurden oder ob ein Container dabei Probleme gemacht hat, ohne ständig Logs prüfen zu müssen. Dazu werfen wir einen kurzen Blick in die offizielle Dokumentation. Diese gibt uns folgende Möglichkeiten:
email-> Benachrichtigung via Emailslack-> Benachrichtigung via Slackmsteams-> Benachrichtigung via MSTeamsgotify-> Benachrichtigung via Gotifyshoutrrr-> Benachrichtigung via containrrr/shoutrrr
7.1 Push-Nachrichten aufs Handy mit Pushover (Shoutrrr)
Für Benachrichtigungen nutzen wir Shoutrrr: Das ist ein kleines “Notification-Gateway”, das Watchtower an viele Dienste anbinden kann – unter anderem Push-Nachrichten aufs Handy. In dieser Anleitung verwenden wir Pushover, weil es schnell eingerichtet ist, zuverlässig funktioniert und du Updates direkt als Push-Mitteilung bekommst (statt z.B. nur per Mail).
Wie oben schon schon erwähnt ist in der .env der Push Dienst auszufüllen dafür müssen wir ;
A) Pushover registrieren & Keys holen
- Pushover Konto erstellen und in der App anmelden.
- Im Web-Dashboard findet ihr euren User Key → das ist PUSHOVER_USER_KEY.
- Unter Your Applications eine neue App anlegen („Create an Application/API Token“) → ihr bekommt den API Token/Key → das ist PUSHOVER_APP_TOKEN.
B) Watchtower .env setzen (Pushover via Shoutrrr)
# --- Notifications (Standard: Shoutrrr / Pushover) ---
WATCHTOWER_NOTIFICATIONS=shoutrrr
WATCHTOWER_NOTIFICATION_URL=pushover://shoutrrr:PUSHOVER_APP_TOKEN@PUSHOVER_USER_KEYCode-Sprache: PHP (php)
7.2 (optional) Nachrichten auf Email (Shoutrrr)
Falls Push (z.B. Pushover) mal nicht verfügbar ist oder du für einen Übergang schnell wieder auf Mail gehen willst, kannst du Email-Benachrichtigungen als Notfall-Option vorbereitet lassen – auskommentiert, aber sofort aktivierbar. Dafür Die Konfig mit shoutrrr und Watchtower auskommentieren
################################################################################
# NOTFALL: Email Notifications (auskommentiert)
#
# Im nickfedor/watchtower Fork läuft Email über Shoutrrrs SMTP Service.
# Aktivierung:
# 1) WATCHTOWER_NOTIFICATIONS=email setzen (statt shoutrrr)
# 2) SMTP-URL unten entkommentieren und Platzhalter füllen
################################################################################
WATCHTOWER_NOTIFICATIONS=email
WATCHTOWER_NOTIFICATION_URL="smtp://SMTP_USER:SMTP_PASS@smtp.example.tld:587/?from=watchtower@example.tld&to=admin@example.tld"Code-Sprache: PHP (php)
Mini-Falle: Sonderzeichen in User/Passwort bei SMTP-URL (URL-Encoding)
Wenn du für den Notfall-Mail-Modus eine SMTP-URL nutzt und dein SMTP-User oder Passwort Sonderzeichen enthält (z.B. @, :, /, #, Leerzeichen), kann das URL-Parsing brechen. Dann musst du User/Passwort percent-encoden (URL-Encoding).
Beispiele:
- @ → %40
- : → %3A
- / → %2F
- # → %23
- Leerzeichen → %20
smtp://user%40example.tld:pa%23ss%3Aword@smtp.example.tld:587/?from=watchtower@example.tld&to=admin@example.tldCode-Sprache: JavaScript (javascript)
8. Container-Auswahl per Label (Opt-in Standard) + Abhängigkeiten
Da wir in unserer .env standardmäßig Opt-in verwenden, werden nur Container aktualisiert, die explizit dafür freigegeben sind. Das reduziert das Risiko von ungewollten Updates (z.B. bei Mailservern, Datenbanken, komplexen Stacks).
8.1 Opt-in (empfohlen / Standard in dieser Anleitung)
Opt-in aktivierst du in Watchtower über:
WATCHTOWER_LABEL_ENABLE=trueCode-Sprache: JavaScript (javascript)
Ab dann gilt: Nur Container mit enable=true werden aktualisiert.
Beispiel-Label im jeweiligen Container/Service:
labels:
com.centurylinklabs.watchtower.enable: "true"Code-Sprache: CSS (css)
Optional kannst du zusätzlich Stacks gruppieren (Scope), z.B. für Immich (notwendig bei Abhängigkeiten innerhalb eines Stacks):
labels:
com.centurylinklabs.watchtower.enable: "true"
com.centurylinklabs.watchtower.scope: "immich"Code-Sprache: CSS (css)
8.2 Wichtig bei Abhängigkeiten (depends_on) / “linked containers”
Viele Compose-Stacks (z.B. App + Redis + Postgres) nutzen depends_on. Watchtower erkennt solche Abhängigkeiten als linked containers.
- Das ist grundsätzlich gut, weil Watchtower den Stack koordiniert stoppt/startet.
- Aber: Wenn du Rolling Restart aktivierst, kann Watchtower bei solchen Stacks mit einer Sanity-Check-Meldung abbrechen.
Darum setzen wir für Abhängigkeits-Stacks (wie Immich) in der .env:
WATCHTOWER_ROLLING_RESTART=falseCode-Sprache: JavaScript (javascript)
Damit laufen Updates auch bei Stacks mit depends_on zuverlässig durch.
8.3 Opt-out (optional)
Wenn du Opt-in nicht nutzt (also WATCHTOWER_LABEL_ENABLE weglässt/false setzt), überwacht Watchtower standardmäßig alle Container – außer du schließt sie explizit aus.
Ausschließen per Label:
labels:
com.centurylinklabs.watchtower.enable: "false"Code-Sprache: CSS (css)
9. Zeitplan, Cleanup & Timeout (empfohlene Basis-Settings)
9.1 Zeitplan (Cron mit 6 Feldern)
Watchtower kann per Cron-Expression mit 6 Feldern (inkl. Sekunden) geplant werden. Beispiel: täglich um 09:00 Uhr:
WATCHTOWER_SCHEDULE="0 0 9 * * *"Code-Sprache: JavaScript (javascript)
9.2 Images automatisch aufräumen (Cleanup)
Damit sich nicht unendlich viele alte Images ansammeln, empfiehlt sich:
WATCHTOWER_CLEANUP=trueCode-Sprache: JavaScript (javascript)
9.3 Timeout für Stop/Restart erhöhen
Gerade bei größeren Containern ist das Default-Timeout manchmal zu knapp. Ein pragmatischer Wert:
WATCHTOWER_TIMEOUT=30s
Tipp: Falls du in Logs siehst, dass Container beim Stoppen öfter “hart” gekillt werden, erhöhe den Timeout schrittweise (z.B. 60s).
