Docker mit Watchtower ohne Portainer

Ich möchte, dass meine Docker Container sich zyklisch Updaten und ich nicht jede Woche manuel ein docker compose pull && docker compose up -d
laufen lassen muss. In den Kommentaren von Goneuland hat ein User nach der Anleitung für Watchtower gefragt. Da ist mir doch direkt wieder eingefallen, dass ich Watchtower bereits kenne und auch schonmal konfiguriert habe. Watchtower schaut ob es für die Container neue latest Versionen gibt, pullt die und startet den Container ggf. neu. Es gibt eine ganz nette Anleitung in Kombination mit Portainer. Ich möchte es an dieser Stelle aber explizit ohne Portainer versuchen.
ACHTUNG: Watchtower macht automatische Updates! Wenn Watchtower eine Aktualisierung macht und das Latest-Image hat widererwartend einen Fehler könnte es passieren das nach der Aktualisierung der Container nicht mehr läuft oder es gar zum Datenverlust kam!
Versionierung
Datum | Änderung |
---|---|
17.06.2022 | Erweiterung um den Punkt „Images säubern“ |
16.06.2022 | Initialer Release |
Verzeichnis erstellen
Zu erst erstelle ich mir das passende Verzeichnis:
mkdir -p /opt/containers/watchtower
Docker Compose Datei erstellen
Nun erstellen ich mir die Docker Compose Datei. In diese Datei kopiere ich mir mal das Beispiel aus der Dokumentation:
nano /opt/containers/watchtower/docker-compose.yml
Inhalt:
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock
Watchtower starten
Ich starte diesen Container nun mal die beispielhafte Konfiguration:
docker compose -f /opt/containers/watchtower/docker-compose.yml up
Ausgabe:

Damit läuft der Container und gibt mir folgende Informationen aus:
- msg=“Watchtower 1.4.0″
–> Version des laufenden Watchtower - msg=“Using no notifications“
–> Das keine Benachrichtigungen konfiguriert sind - msg=“Checking all containers (except explicitly disabled with label)“
–> Es werden alle Container geprüft außer die die eine expliziten Hinweis gesetzt haben - msg=“Scheduling first run: 2022-06-17 18:57:19 +0000 UTC“
–> Geplante erste durchführung - msg=“Note that the first check will be performed in 23 hours, 59 minutes, 59 seconds“
–> Zeit bis zur ersten durchführung
Damit würde es grundsätzlich schonmal funktionieren und hat akut noch kein Update eingespielt sondern nur geplant. Wie ich den ausgegebene Informationen entnehmen kann gibt es wohl noch eine Vielzahl an möglichen Konfigurationen.
Weitere Konfigurationen
Benachrichtigungen konfigurieren
Es gibt einen Hinweis, dass ich Benachrichtigungen konfigurieren kann und es erscheint mir Sinnvoll diese auch zu konfigurieren damit ich einen Bericht bekomme über getätigte Updates bzw. Durchläufe. Dazu werfe ich einen kurzen Blick in die offizielle Dokumentation. Diese gibt mir folgende Möglichkeiten:
email
-> Benachrichtigung via Emailslack
-> Benachrichtigung via Slackmsteams
-> Benachrichtigung via MSTeamsgotify
-> Benachrichtigung via Gotifyshoutrrr
-> Benachrichtigung via containrrr/shoutrrr
Da ich mehrere Server betreibe und den Watchtower auch auf allen einsetzten möchte zugleich aber nicht zugespamt werden möchte wähle ich für mich Slack. Innerhalb meines Slack Workspaces lege ich mir einen Channel an und füge die App „Eingehende Webhooks“ zu Slack hinzu. Diese gibt mir eine Hook-URL aus welchen ich mir in die Konfiguration der docker-compose.yml mit einarbeite:
Inhalt:
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock
Geänderte Fassung:
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - WATCHTOWER_NOTIFICATIONS=slack - WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL="https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXX" # Hier füge ich den Hook-URL ein - WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIER=watchtower-server-01 # Hier lege ich meinen eigenen Identifier ein - WATCHTOWER_NOTIFICATION_SLACK_CHANNEL=#watchtower # Hier füge ich den Channel ein
Wenn ich nun den Container wieder starte gibt er mir aus, dass Slack nun zur Benachrichtigung definiert wurde:

Zeitzone definieren
Mir ist aufgefallen, dass die Zeitzone bzw. die Zeit im Container auch nicht stimmt. Dazu gibt es in den Argumenten auch einen Hinweis es mit TZ zu definieren. Ich persönlich nutze lieber die Variante die Zeitzone vom Host zu übernehmen:
Inhalt:
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - WATCHTOWER_NOTIFICATIONS=slack - WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL="https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXX" # Hier füge ich den Hook-URL ein - WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIER=watchtower-server-01 # Hier lege ich meinen eigenen Identifier ein - WATCHTOWER_NOTIFICATION_SLACK_CHANNEL=#watchtower # Hier füge ich den Channel ein
Geänderte Fassung:
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock - /etc/localtime:/etc/localtime:ro environment: - WATCHTOWER_NOTIFICATIONS=slack - WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL="https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXX" # Hier füge ich den Hook-URL ein - WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIER=watchtower-server-01 # Hier lege ich meinen eigenen Identifier ein - WATCHTOWER_NOTIFICATION_SLACK_CHANNEL=#watchtower # Hier füge ich den Channel ein
Wenn ich diesen Container starte gibt er mir nun die Zeit + 24h aus. Diese Entspricht nun der Host-Zeit.
Container-Auswahl via Flag
Für mich ist es wichtig, dass nicht blind jeder Container aktualisiert wird, da ich auch Server habe auf denen zum Beispiel Mailcow läuft. Mailcow bringt sein eigenes Update-Script mit. Nun gibt es 2 Möglichkeiten:
- Standard: Alle Container bekommen ein Update außer welche mit expliziter Flag
- Kein Container bekommt ein Update außer welche mit expliziten Flag
Standardvariante
In der Standardvariante kann ich jedem beliebigen Container das Label com.centurylinklabs.watchtower.enable=false
mitgeben, welches das Update unterbindet.
Beispiel:
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock - /etc/localtime:/etc/localtime:ro environment: - WATCHTOWER_NOTIFICATIONS=slack - WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL="https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXX" - WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIER=watchtower-server-01 - WATCHTOWER_NOTIFICATION_SLACK_CHANNEL=#watchtower labels: - "com.centurylinklabs.watchtower.enable=false" # False -> Es wird kein Update für diesen Container gemacht
Alternative Variante
Ich persönlich bevorzuge die Variante, dass kein Container aktualisiert wird. Nur die Container welche ich explizit definiere. Dazu erweitere ich meine docker-compose.yml
um die notwendige Option:
Inhalt:
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock - /etc/localtime:/etc/localtime:ro environment: - WATCHTOWER_NOTIFICATIONS=slack - WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL="https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXX" - WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIER=watchtower-server-01 - WATCHTOWER_NOTIFICATION_SLACK_CHANNEL=#watchtower - WATCHTOWER_LABEL_ENABLE=true # Hiermit aktiviere ich die alternative Variante labels: - "com.centurylinklabs.watchtower.enable=true" # Jeder zu aktualisierender Container bekommt dies nun mitgegeben
Ab jetzt muss ich jedem Container entweder com.centurylinklabs.watchtower.enable=true
oder --label-enable
mitgeben damit Watchtower diese aktualisiert.
Zeitplan
Nun gilt es einen Zeitplan zu erstellen. Beim Zeitplan kann ich mit der bekannten Cron expression in 6 Feldern eine regelmäßigkeit in der docker-compose.yml
Konfigurieren :
Inahlt:
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock - /etc/localtime:/etc/localtime:ro environment: - WATCHTOWER_NOTIFICATIONS=slack - WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL="https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXX" - WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIER=watchtower-server-01 - WATCHTOWER_NOTIFICATION_SLACK_CHANNEL=#watchtower - WATCHTOWER_LABEL_ENABLE=true labels: - "com.centurylinklabs.watchtower.enable=true"
Angepasse Konfiguration:
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock - /etc/localtime:/etc/localtime:ro environment: - WATCHTOWER_NOTIFICATIONS=slack - WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL="https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXX" - WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIER=watchtower-server-01 - WATCHTOWER_NOTIFICATION_SLACK_CHANNEL=#watchtower - WATCHTOWER_LABEL_ENABLE=true - WATCHTOWER_SCHEDULE=0 0 4 * * * # Hier anpassen. Im Beispiel: Jede Nacht um 04:00 Uhr labels: - "com.centurylinklabs.watchtower.enable=true"
In desem Beispiel würde jede Nacht um 04:00 Uhr das Update durchgeführt.
Images säubern
Wenn ich immer wieder Updates auf neue Images mache wird mein Docker-System ganz schön zuwuchern mit alten Images. Für diesen Fall gibt es in der Dokumentation abhilfe. Diese Pflege ich auch in meine docker-compose.yml
ein:
Inhalt:
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock - /etc/localtime:/etc/localtime:ro environment: - WATCHTOWER_NOTIFICATIONS=slack - WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL="https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXX" - WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIER=watchtower-server-01 - WATCHTOWER_NOTIFICATION_SLACK_CHANNEL=#watchtower - WATCHTOWER_LABEL_ENABLE=true - WATCHTOWER_SCHEDULE=0 0 4 * * * labels: - "com.centurylinklabs.watchtower.enable=true"
Änderungen:
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock - /etc/localtime:/etc/localtime:ro environment: - WATCHTOWER_NOTIFICATIONS=slack - WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL="https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXX" - WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIER=watchtower-server-01 - WATCHTOWER_NOTIFICATION_SLACK_CHANNEL=#watchtower - WATCHTOWER_LABEL_ENABLE=true - WATCHTOWER_SCHEDULE=0 0 4 * * * - WATCHTOWER_CLEANUP=true # Mit dieser Option werden nach dem Start des neuen Images die alten entfernt labels: - "com.centurylinklabs.watchtower.enable=true"
Danke schonmal für die Zusendung.
Gerne 🙂
Habe die Anleitung auch direkt noch etwas erweitert. Weiter Konfigurationsmöglichkeiten folgen noch 🙂