Manchmal muss ein Docker-Container neu gestartet werden, weil er nicht mehr richtig funktioniert. Häufig wird dies durch manuelles Eingreifen erledigt, wenn das Monitoring eine Warnung generiert. Auch Skripte, die regelmäßig aufgerufen werden, sind ein gängiger Ansatz. Die erste Variante erfordert jedoch flottes reagieren und die Zweite benötigt viel Pflege- und Einrichtungsaufwand.
In diesem kurzen Artikel möchte ich dir daher eine elegantere Methode vorstellen. Nämlich die Verwendung von Autoheal in Verbindung mit den Docker eigenen Healthchecks. Im Gegensatz zu Kubernetes kann Docker nur im Swarm-Modus schadhafte Container neu zu starten. Da diese Betriebsart aber in der Praxis kaum eingesetzt wird, muss man dieses essenzielle Feature selbst nachrüsten.
Und genau hier kommt das praktische Tool Autoheal ins Spiel. Er kann alle als schadhaft markierten Container neu starten. Durch die Konfiguration von Umgebungsvariablen kannst du alle wichtige Einstellungen vornehmen. In nur wenigen Minuten kannst du mittels Autoheal dein Docker-Setup erheblich verbessern. Mehr darüber erfährst du in diesem Beitrag.
Wie man Autoheal verwendet:
Autoheal kann entweder alle Container deiner Docker-Instanz überwachen oder nur bestimmte. Wenn du die Umgebungsvariable AUTOHEAL_CONTAINER_LABEL=all setzt, werden sämtliche Container überwacht. Allerdings muss in diesem Szenario sichergestellt sein, dass alle Container einen Status in Form von healthy oder unhealthy bereitstellen.
Da dies nicht immer der Fall ist, kannst du stattdessen das Label autoheal=true in den Compose-Files der zu überwachenden Container setzen. Wer sich gut mit Docker auskennt, könnte allerdings einwenden: In jedem Compose-File kann man einen eigenen Healthcheck, und das sogar mit einem spezifischen Befehl und weiteren Parametern definieren.
Das ist auch richtig so und damit als Vorgehen in produktiven Setups empfehlenswert. Für eine erste Erprobung mit ausgewählten Containern kannst du aber bis auf Weiteres das Label autoheal=true setzen und dich so an die flächendeckende Benutzung herantasten. Und damit du auch direkt starten kannst, hier ein Code-Beispiel für Docker Compose, wie ich es selbst nutze:
version: "3"
services:
autoheal:
container_name: autoheal
image: willfarrell/autoheal:1.2.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /etc/localtime:/etc/localtime:ro
restart: always
environment:
AUTOHEAL_CONTAINER_LABEL: autoheal
AUTOHEAL_INTERVAL: 5
AUTOHEAL_START_PERIOD: 60
AUTOHEAL_DEFAULT_STOP_TIMEOUT: 60
Die wenigen Zeilen Code sollten selbsterklärend sein. Alle fünf Sekunden wird nach Containern in Zustand unhealthy gesucht. Der Autoheal-Container selbst startet allerdings erst nach 60 Sekunden mit seiner Überwachungsroutine. Damit die Container ausreichend Zeit zum Herunterfahren bekommen, habe ich den Timeout-Wert auf 60 Sekunden erhöht.
Standardmäßig wartet Docker nur 10 Sekunden, was in meinem speziellen Anwendungsfall mit trägen Java-Anwendungen auf dem Host-System zu kurz ist. Da nicht jeder mit der Konfiguration von Healthchecks in Docker vertraut ist, werde ich zum Abschluss des Artikels noch ein praktisches Beispiel präsentieren. So wird alles Geschriebene klarer und damit verständlicher:
version: '3.6'
services:
wordpress_srv:
image: wordpress:latest
container_name: wordpress_srv
healthcheck:
test: curl -f http://localhost:80/ || exit 1
interval: 60s
timeout: 10s
retries: 3
start_period: 30s
depends_on:
- wordpress_db
restart: always
environment:
WORDPRESS_DB_HOST: wordpress_db:3306
WORDPRESS_DB_USER: db_wordpress_user
WORDPRESS_DB_PASSWORD: 1234Passw0rt
volumes:
- ./wordpress:/var/www/html
labels:
- autoheal=true
wordpress_db:
image: mysql:8.3
container_name: wordpress_db
healthcheck:
test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD || exit 1
interval: 60s
timeout: 10s
retries: 3
start_period: 30s
volumes:
- ./mysql_data_db:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: 1234Passw0rt
MYSQL_DATABASE: wordpress
MYSQL_USER: db_wordpress_user
MYSQL_PASSWORD: 1234Passw0rt
labels:
- autoheal=true