No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Christian Säum 23ded011af
All checks were successful
CI – Validate & Release / validate (push) Successful in 13s
CI – Validate & Release / mirror (push) Successful in 2s
CI – Validate & Release / release (push) Has been skipped
Merge pull request 'chore(license): AGPL-3.0-or-later + Copyright-Hinweis' (#1) from chore/add-license into main
2026-09-02 19:47:20 +00:00
.forgejo/workflows fix(ci): retry Codeberg pushes on 502/504, prefer compose v2 2026-06-21 18:48:53 +02:00
.idea refactor(autoheal): convert stack to reusable .env-based template 2026-06-13 12:54:20 +02:00
.env refactor(autoheal): convert stack to reusable .env-based template 2026-06-13 12:54:20 +02:00
.gitignore New Commit CICD 2026-06-21 14:07:27 +02:00
AGENTS.md refactor(autoheal): convert stack to reusable .env-based template 2026-06-13 12:54:20 +02:00
CICD-Actions.md docs(ci): align docs with hardened pipeline (compose v2 runner image, Codeberg 502/504 retry) 2026-06-21 18:57:47 +02:00
CLAUDE.md refactor(autoheal): convert stack to reusable .env-based template 2026-06-13 12:54:20 +02:00
docker-compose.yml refactor(autoheal): convert stack to reusable .env-based template 2026-06-13 12:54:20 +02:00
LICENSE chore(license): add AGPL-3.0-or-later license and copyright notice 2026-09-02 21:31:54 +02:00
Projekt.md refactor(autoheal): convert stack to reusable .env-based template 2026-06-13 12:54:20 +02:00
README.md chore(license): add AGPL-3.0-or-later license and copyright notice 2026-09-02 21:31:54 +02:00

Autoheal – Automatischer Container-Neustart

Autoheal überwacht Docker-Container anhand ihres Healthcheck-Status und startet Container die als unhealthy markiert sind automatisch neu. Er fungiert als einfaches Self-Healing-System ohne vollständigen Orchestrator wie Kubernetes.

Template-Hinweis: Konfiguration läuft über die .env. Vor dem Einsatz die .env prüfen/anpassen (insb. WEBHOOK_URL optional).


Voraussetzungen

  • Docker & Docker Compose v2
  • Zugriff auf den Docker-Socket (/var/run/docker.sock)
  • Die zu überwachenden Container müssen einen Docker-Healthcheck konfiguriert haben

Verzeichnisstruktur

docker-autoheal-neustart/
├── .env                ← Konfiguration (Image-Tag, TZ, AUTOHEAL_*-Werte)
├── docker-compose.yml  ← Autoheal Stack-Datei
└── README.md

Stack starten

docker compose up -d

Konfiguration

Alle Einstellungen werden über die .env gesetzt und in der docker-compose.yml als ${VARIABLE} referenziert.

Variable (.env) Default Beschreibung
AUTOHEAL_IMAGE_TAG 1.2.0 Gepinnte Image-Version (letzte benannte Release)
AUTOHEAL_CONTAINER_LABEL autoheal Welche Container überwacht werden. all = alle, sonst Label-Name
AUTOHEAL_INTERVAL 5 Prüfintervall in Sekunden
AUTOHEAL_START_PERIOD 60 Wartezeit in Sekunden nach eigenem Start bevor Überwachung beginnt
AUTOHEAL_DEFAULT_STOP_TIMEOUT 10 Wartezeit in Sekunden zwischen SIGTERM und SIGKILL beim Neustart
AUTOHEAL_ONLY_MONITOR_RUNNING true true = nur Container im Status running überwachen (nicht starting)
CURL_TIMEOUT 30 Timeout in Sekunden für Docker-API-Anfragen
WEBHOOK_URL – (leer) URL die bei jedem Neustart per POST benachrichtigt wird (optional)

Wichtig: AUTOHEAL_CONTAINER_LABEL=autoheal statt all verwenden, um gezielt nur explizit markierte Container zu überwachen. Mit all würde Autoheal jeden Container mit einem Healthcheck überwachen — auch solche die absichtlich unhealthy sind.


Container für Autoheal markieren

Damit Autoheal einen Container überwacht, muss der Container:

  1. Einen Healthcheck in seiner docker-compose.yml konfiguriert haben
  2. Das Label autoheal=true tragen

Beispiel

services:
  mein-service:
    image: mein-image
    healthcheck:
      test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:8080/healthy || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    labels:
      - autoheal=true                  # Für Autoheal-Überwachung markieren
      - autoheal.stop.timeout=10       # Optionaler individueller Stop-Timeout

Per-Container Label-Optionen

Label Beschreibung
autoheal=true Markiert den Container zur Überwachung durch Autoheal
autoheal.stop.timeout=<s> Überschreibt AUTOHEAL_DEFAULT_STOP_TIMEOUT für diesen Container individuell

Webhook-Benachrichtigung (optional)

Autoheal kann bei jedem Neustart eine HTTP-POST-Anfrage an eine Webhook-URL senden. Damit lassen sich Benachrichtigungen in Slack, Mattermost, Ntfy, Uptime Kuma oder ähnliche Systeme integrieren.

In der .env:

WEBHOOK_URL=https://ntfy.domain.de/server-alerts

Der POST-Body enthält Container-Name, ID und Zeitstempel des Neustarts.


Nützliche Befehle

# Autoheal starten
docker compose up -d

# Autoheal stoppen
docker compose down

# Logs von Autoheal verfolgen (zeigt jeden überwachten Neustart)
docker logs -f autoheal

# Healthcheck-Status aller laufenden Container anzeigen
docker ps --format "table {{.Names}}\t{{.Status}}"

# Healthcheck-Status eines bestimmten Containers prüfen
docker inspect --format='{{.State.Health.Status}}' <container-name>

# Letzten Healthcheck-Output anzeigen
docker inspect --format='{{json .State.Health}}' <container-name> | jq

Ablauf: Was passiert bei einem Neustart?

  1. Autoheal erkennt Container mit Status unhealthy
  2. Autoheal sendet SIGTERM an den Container
  3. Autoheal wartet stop.timeout Sekunden
  4. Falls der Container noch läuft: SIGKILL
  5. Docker startet den Container neu (via restart: unless-stopped oder always)
  6. Falls WEBHOOK_URL gesetzt: POST-Benachrichtigung wird gesendet
  7. Autoheal überwacht den neu gestarteten Container weiter

Troubleshooting

Autoheal startet keinen Container neu obwohl er unhealthy ist:

  • Prüfen ob das Label autoheal=true am Container gesetzt ist: docker inspect <container-name> | grep autoheal
  • Prüfen ob AUTOHEAL_CONTAINER_LABEL in der .env mit dem Label übereinstimmt
  • Sicherstellen dass der Container einen Healthcheck hat: docker inspect --format='{{json .State.Health}}' <container-name>

Autoheal startet Container zu früh neu (während des normalen Starts):

  • AUTOHEAL_ONLY_MONITOR_RUNNING=true setzen
  • AUTOHEAL_START_PERIOD erhöhen (sollte >= start_period des überwachten Containers sein)

docker inspect zeigt Health: null:

  • Der Container hat keinen Healthcheck konfiguriert — Autoheal kann diesen Container nicht überwachen
  • Healthcheck in der docker-compose.yml des Containers ergänzen

Autoheal hat keinen Zugriff auf Docker:

  • Sicherstellen dass /var/run/docker.sock ins Volume gemountet ist
  • Prüfen ob der User in der docker-Gruppe ist

CI/CD & Spiegelung

Die Pipeline (.forgejo/workflows/ci.yml) läuft self-hosted auf Forgejo, ganz ohne externe Actions (Checkout per git clone):

  • validate (jeder Push/PR auf main + Tags): docker compose config -q, yamllint (relaxed) und gitleaks (nur Working-Tree). Es wird docker compose v2 genutzt (Runner-Image catthehacker/ubuntu:act-latest; nötig u. a. für v2-Keys wie dockerfile_inline), apt nur als Fallback – kein 64-MB-github-Download.
  • mirror (nur Push, needs: validate): spiegelt main + Tags erst nach grünen Checks nach Codeberg (Org Docker-Stacks), mit Retry gegen transiente 502/504. Forgejos eingebauten Push-Mirror dafür nicht zusätzlich aktivieren.
  • release (nur Tag v*): baut ein schlankes Deploy-ZIP und hängt es an ein Forgejo-Release und – als Backup – an ein Codeberg-Release (die Releases-Unit am Codeberg-Repo wird dabei automatisch aktiviert).

Release auslösen:

git tag v1.1
git push origin v1.1

Details siehe CICD-Actions.md.

Lizenz

Copyright (C) 2026 Christian Säum – web-seo-consulting.eu

Dieses Projekt steht unter der GNU Affero General Public License, Version 3 oder (nach deiner Wahl) einer späteren Version (AGPL-3.0-or-later). Der vollständige Lizenztext steht in der Datei LICENSE.

Du darfst die Software nutzen, weitergeben und – auch kommerziell – verkaufen. Gibst du eine veränderte Fassung weiter oder betreibst du sie über ein Netzwerk (z. B. als Dienst), muss deren vollständiger Quellcode ebenfalls unter der AGPL-3.0-or-later verfügbar sein. Der Copyright-Hinweis und die Nennung des ursprünglichen Autors dürfen nicht entfernt werden.

Diese Angabe betrifft nur die in diesem Repository enthaltenen eigenen Dateien (Konfiguration, Skripte, Anpassungen). Eingebundene Fremdsoftware und Container-Images unterliegen weiterhin ihren eigenen Lizenzen.