In der Docker Philosophie gibt es für jeden Dienst einen einzelnen Container. Sein Inhalt wird durch so genannte “Images” definiert. Diese liegen bei Docker Hub oder einer beliebigen anderen Registry und können von dort heruntergeladen und genutzt werden. Diese Images enthalten den Dienst und alle dafür notwendigen Systemkomponenten. Damit hat man eine fest definierte Systemumgebung und der Container wird auf jedem System gleich funktionieren. Es kann also zu keinen Seiteneffekten kommen, weil ein Tool nicht installiert ist oder in der falschen Version vorliegt.
Images sind unveränderlich
Docker Images werden einmal erstellt und dann zum Beispiel zu Docker Hub hochgeladen. Sie können nicht verändert werden. Das bedeutet aber auch, dass die Anwendung darin nicht einfach über einen Updater aktualisiert werden kann. Diese Änderungen würden verloren gehen, wenn der Container einmal neu aufgebaut wird, weil dann wieder nur die Daten aus dem ursprünglichen Image vorhanden sind.
Deswegen wird bei einer Aktualisierung ein neues Image erstellt und entsprechend zur Verfügung gestellt. Die Anwender müssen nun dafür sorgen, dass ihre Container mit der neueren Version laufen.
Manuelles Update
Wenn wir davon ausgehen, dass docker compose
eingesetzt wird, wie es in den bisherigen Anleitungen in diesem Blog der Fall ist, sieht der Update-Prozess folgendermaßen aus:
|
|
Da wir docker compose nutzen gelten diese Schritte für alle Container, die in der docker-compose.yml definiert sind.
Automatisches Update
Da einige Images sehr häufig aktualisiert werden, teilweise sogar täglich, wäre es zu begrüßen wenn dieser Prozess automatisiert werden kann. Dabei ist anzumerken, dass unbeaufsichtigte automatische Updates immer ein gewisses Risiko beinhalten.
So kann es passieren, dass es eine Änderung gibt die ein manuelles Eingreifen erfordern, damit die Anwendung wieder läuft. Oder aber ein Anbieter hat ein fehlerhaftes Image hochgeladen, was zwar nach ein paar Stunden korrigiert wurde, der Auto-Updater hat aber ggf. in der Zwischenzeit das fehlerhafte Image gezogen und die Anwendung ist offline.
In den allermeisten Fällen kommt es aber zu keinen Problemen, es sollte einem aber bewusst sein, dass es diese Möglichkeit gibt. Ich persönlich nehme lieber die sehr geringe Wahrscheinlichkeit eines Ausfalls in Kauf, als dass meine Anwendungen veralten und diese ggf. ein Sicherheitsrisiko darstellen.
Watchtower
Die Anwendung Watchtower bietet so eine automatisierte Aktualisierung an. Sie ist selbst ebenfalls ein Docker Container, erkennt alle anderen Container und prüft in einem definierten Zeitintervall, ob für ein Container ein neues Image vorliegt. Ist dies der Fall wird das Image automatisch geladen, der betroffene Container gestoppt und gelöscht und mit den gleichen Einstellungen wieder auf Basis des neuen Images hochgefahren.
Voraussetzungen
Es wird davon ausgegangen, dass ihr mit eurem Benutzer auf eurem System angemeldet seid und dieser in den Gruppen sudo und docker ist. Dies ist der Fall, wenn ihr unseren anderen Anleitungen gefolgt seid. Desweiteren wird diese Ordnerstruktur angenommen:
|
|
Sollte die Struktur passen, aber der Ordner noch nicht existieren, legt diesen einfach an und wechselt in das Verzeichnis:
|
|
Installation
Um Watchtower zu “installieren” bzw. eher als Container zu starten, legen wir eine neue “docker-compose.yml” an (nano docker-compose.yml
) und füllen sie mit folgendem Inhalt:
|
|
Speichern und schließen mit
Win: STRG+O, ENTER, STRG+X
Mac: CONTROL+O, ENTER, CONTROL+X
Anschließend wird der Container gestartet:
|
|
Wenn ihr euch die Ausgaben des Containers anzeigen lasst mit docker compose logs -f
, sollte etwas in dieser Art zu sehen sein:
|
|
Das Log verlasst ihr wieder mit STRG+C bzw. am Mac mit CONTROL+C
Erläuterung
Als Volume wird /var/run/docker.sock
als readonly in den Container gegeben. Dadurch ist Watchtower in der Lage, die anderen Container zu sehen und sie zu steuern.
WATCHTOWER_SCHEDULE gibt an, wie oft auf neue Images geprüft werden soll. Die Angabe im Beispiel bedeutet “Jeden Tag um 05:00 Uhr”. Dies kann beliebig auf eine andere Uhrzeit angepasst werden oder aber auch auf einen häufigeren Intervall verändert werden. Wenn ihr euch mit den Cron-Angaben nicht auskennt, kann crontab.guru weiterhelfen, um die richtige Angabe zu finden.
WATCHTWOER_CLEANUP sorgt dafür, dass die alten Images entfernt werden, damit der Speicher nicht mit alten Images zumüllt. Durch WATCHTOWER_INCLUDE_STOPPED werden auch Container aktualisiert, die aktuell gestoppt sind und nicht laufen, aber existieren.
Updatesuche einschränken
Mit den obigen Einstellungen sucht Watchtower ausnahmslos für alle Container, die er finden kann nach neuen Images und aktualisiert sie automatisch. Wenn ihr die Kontrolle darüber behalten wollt, welche Container automatisch aktualisiert werden sollen und welche nicht, ist auch dies möglich.
Dazu muss die docker-compose.yml
im Bereich “environment” um folgende Umgebungsvariable ergänzt werden:
|
|
Damit überprüft Watchtower nur noch Container, die ein bestimmtes Label haben. Das bedeutet aber auch, dass ihr bei jedem Container, der automatisch aktualisiert werden soll, dieses Label ergänzen müsst. Die Datei von Watchtower sähe damit so aus:
|
|
Die letzten beiden Zeilen müssen auch in jeden weiteren Container, der zukünftig aktualisiert werden soll. Nicht vergessen nach der Anpassung die Container neu zu erstellen: docker compose down && docker compose up -d
.
Abschluss
Mit Watchtower habt ihr nun eine einfache Möglichkeit im Einsatz, um eure Dienste jederzeit auf dem neuesten Stand zu halten. Zwar sollte man sich auch so immer regelmäßig auf die Systeme einloggen, wenn man selber Dienste hostet, aber in der Realität gibt es manchmal längere Abschnitte in denen das nicht passiert. Umso wichtiger ist es dann, dass die Dienste nicht veralten.