Tutorial: Docker-Container automatisch aktualisieren und aufräumen
Wenn Anwendungen in Docker-Containern laufen, nützt ein normales apt upgrade auf dem Host-System nichts, um die Apps selbst zu aktualisieren. Die Software innerhalb der Container bleibt so lange auf dem alten Stand, bis das zugrundeliegende Docker-Image aktualisiert und der Container neu gestartet wird.
Anstatt jeden Server manuell abzuklappern, nutzen wir in diesem Tutorial ein mächtiges Ansible-Playbook. Es holt sich die neuesten Image-Versionen (z. B. von Docker Hub), startet die betroffenen Container bei Bedarf ohne Ausfallzeiten neu und bereinigt im Anschluss den Server von altem Datenmüll.
Teil 1: Die Logik des Docker-Updates
Ein sicheres und sauberes Docker-Update-Playbook folgt einer klaren Dreier-Kette:
-
Images aktualisieren (
docker pull): Ansible prüft auf den Zielservern, ob für die genutzten Container neuere Versionen (Tags) in den Registries vorliegen und lädt diese herunter. -
Container neu starten: Liegt ein neueres Image vor, stoppt Ansible den alten Container und startet ihn mit dem neuen Image augenblicklich neu. Die Konfigurationen und Daten (Volumes) bleiben dabei unberührt.
-
Datenmüll entfernen (
docker system prune): Beim Herunterladen neuer Images bleiben die alten Image-Dateien als ungenutzte Fragmente (sogenannte Dangling Images) auf der Festplatte zurück. Über ein automatisches Pruning holen wir uns wertvollen Speicherplatz zurück.
Teil 2: Das automatisierte Ansible-Playbook
Erstelle in deinem Projektordner ~/ansible-inframanagement/ eine neue Datei namens update-docker-containers.yaml:
nano update-docker-containers.yaml
Füge dort das folgende vollständige Playbook ein:
---
- name: Docker-Container aktualisieren und Server bereinigen
hosts: docker_hosts
become: true
gather_facts: false
tasks:
- name: 🔍 Informationen über laufende Container sammeln
community.docker.docker_host_info:
containers: true
containers_filters:
status: "running"
register: docker_apps
- name: 🔄 Docker-Images aktualisieren und betroffene Container neu starten
community.docker.docker_container:
name: "{{ item.Names[0] | regex_replace('^/', '') }}"
image: "{{ item.Image }}"
state: started
pull: true # Prüft, ob ein neueres Image auf Docker Hub vorliegt
restart_policy: always
loop: "{{ docker_apps.containers }}"
loop_control:
label: "{{ item.Names[0] | regex_replace('^/', '') }}"
when: docker_apps.containers | length > 0
- name: 🧹 Speicherplatz freigeben (Ungenutzte Docker-Reste entfernen)
community.docker.docker_prune:
containers: true
images: true
images_filters:
dangling: "true" # Entfernt nur verwaiste, alte Image-Schichten
networks: true
volumes: false # WICHTIG: Volumes auf 'false' lassen, um keine App-Daten zu löschen!
Wie funktioniert dieses Playbook?
-
community.docker.docker_host_info: Ansible scannt den Server und merkt sich alle aktuell laufenden Container sowie deren exakte Start-Parameter. -
pull: true: Das ist der Schlüsselmechanismus. Das Modul vergleicht das lokale Image mit der Online-Registry. Nur wenn sich das Image geändert hat, lädt Ansible es herunter und baut den Container im Hintergrund neu. Wenn das Image identisch ist, wird der Container nicht neu gestartet (keine unnötige Downtime). -
volumes: false: Das ist die wichtigste Sicherheitsvorkehrung beim Aufräumen (docker_prune). Deine persistenten Anwendungsdaten (wie Datenbanken oder Nextcloud-Dateien) liegen in Docker-Volumes. Diese dürfen niemals automatisch gelöscht werden.
Teil 3: Ausführung und Verifizierung
Führe das Playbook von deiner Ansible-Zentrale aus:
ansible-playbook -i hosts update-docker-containers.yaml
In der Konsole siehst du nun in der Schleife (loop) jeden Container vorbeiziehen. Steht dort ok, war das Image bereits aktuell. Steht dort changed, wurde der Container erfolgreich auf die neueste Version angehoben. Ganz am Ende siehst du beim Prune-Task, wie viel Megabyte oder Gigabyte an Speicherplatz auf dem Host freigegeben wurden.
Teil 4: Die Automatisierung via Cronjob
Da Anwendungs-Updates (wie für Bitwarden, Portainer oder Web-Apps) regelmäßig erscheinen, sollte dieser Wächter wöchentlich laufen. Wir platzieren den Job so, dass er kurz nach den regulären System-Updates ausgeführt wird.
-
Öffne die Crontab auf der Zentrale:
crontab -e -
Füge die folgende Zeile hinzu (Beispiel: Jeden Sonntag um 03:30 Uhr nachts):
30 3 * * 7 cd /root/ansible-inframanagement && /usr/bin/ansible-playbook update-docker-containers.yaml > /var/log/ansible-docker-updates.log 2>&1
Log-Kontrolle
Ob deine Container nachts erfolgreich aktualisiert wurden, kannst du ganz einfach über das dedizierte Logfile prüfen:
cat /var/log/ansible-docker-updates.log
Deine containerisierte Infrastruktur ist damit vollständig automatisiert, absolut wartungsarm und hält sich selbstständig frisch und sauber!