Tugtainer: Docker-Container automatisch aktualisieren (Self-Hosted)
Aktualisiere Docker-Container automatisch mit Tugtainer, einem Self-Hosted-Tool mit Web-UI, Multi-Host-Agents, Rollback und Alerts. Der Vergleich mit Watchtower.
Aktualisiert Veröffentlicht 30 Min. Lesezeit

Affiliate-Hinweis
Einige Links in diesem Artikel sind Affiliate-Links. Wenn du darüber kaufst, erhalten wir möglicherweise eine kleine Provision – ohne zusätzliche Kosten für dich. Das hilft uns, diese Empfehlungen weiter zu testen und zu aktualisieren.
Docker-Container automatisch aktualisieren, ohne auf jedem Server docker compose pull zu babysitten. Tugtainer ist ein Self-Hosted-Tool, das Registries auf neue Images prüft, Container in Abhängigkeitsreihenfolge neu erstellt, fehlgeschlagene Updates zurückrollt und dir sagt, was passiert ist. Du bekommst eine Web-UI, Multi-Host-Agents und Kontrolle pro Container – du entscheidest also exakt, was wann aktualisiert wird. Diese Anleitung deckt das Deployment mit Dokploy oder Docker Compose ab, das Agent-Setup für Remote-Hosts und alles bis einschließlich v1.41.0 (September 2026). Wenn du neu bei Docker bist, starte mit unserem Guide zu den wichtigsten Docker-Befehlen.
Was ist Tugtainer?
Tugtainer ist eine Self-Hosted-App, die deine Docker-Container aktuell hält. Sie vergleicht den Image-Digest, den jeder Container ausführt, mit der Registry, markiert Container mit neueren Images und erstellt sie nach einem Zeitplan neu, den du kontrollierst. Updates laufen in Abhängigkeitsreihenfolge, und wenn ein neues Image seinen Healthcheck vermasselt, rollt Tugtainer den Container automatisch auf das vorherige Image zurück.
Alles läuft auf deiner Infrastruktur. Kein SaaS-Account, keine Gebühr pro Host, und automatische Updates sind standardmäßig aus – du schaltest sie Container für Container zu. Eine Web-UI mit Authentifizierung liegt obendrauf, und jeder zusätzliche Server läuft einen leichtgewichtigen Agent, sodass eine einzige Instanz alle verwalten kann.
So passen die Teile zusammen:
Die Hauptinstanz spricht über einen Socket-Proxy mit Docker statt den Docker-Socket direkt zu mounten – das begrenzt, was ein kompromittiertes Tugtainer anstellen könnte. Auf Remote-Hosts macht der Agent denselben Job lokal und exponiert eine kleine API für die primäre Instanz. Benachrichtigungen fächern sich über Apprise zu Discord, Telegram, Slack, E-Mail und dutzenden anderen Diensten auf.
Hetzner Cloud jetzt ausprobieren Hostinger VPS ausprobierenDie VPS-Preise sind 2026 überall gestiegen – wenn du eine gemietete Maschine neu überdenkst, schau dir an, was sich geändert hat und wann ein Mini-PC gewinnt.
Produktivnutzung
Die Anwendung wird „as is” verteilt, und die Entwickler empfehlen sie nicht für kritische Produktivumgebungen ohne Tests. Auto-Updates bewegen deine Container zwischen Image-Versionen ohne Mensch in der Schleife – Backups wichtiger Daten sind also nicht verhandelbar, bevor du sie aktivierst.
Was du brauchst, bevor du startest
- Einen Linux-Host oder VPS mit installiertem Docker und Compose-Plugin
- Port 9412 frei für die Tugtainer-Web-UI, plus 9413 für jeden Agent-Host (beide überspringen, wenn du die UI über Dokploy exponierst)
- Einen DNS-Record, der auf deinen Server zeigt, wenn du die UI hinter HTTPS willst
- Einen starken, einzigartigen
AGENT_SECRET, wenn du Remote-Hosts verwalten willst - Backups aller statefulen Container (Datenbanken, Uploads), bevor du Auto-Updates aktivierst
- Credentials für deinen Notification-Dienst: eine Discord-Webhook-URL, einen Telegram-Bot-Token, SMTP-Daten, was immer du nutzt
Tugtainer ist kostenlos und Open Source. Es läuft bequem auf einem Entry-Level-VPS in der 4–5-€/Monat-Klasse (2 vCPU, 4 GB RAM reichen locker) oder neben deinem bestehenden Dokploy-Stack. State lebt im tugtainer_data-Volume, es gibt also keine separate Datenbank zu babysitten. Wenn du es lieber zu Hause auf eigener Hardware laufen lassen willst, hat ein kompakter Mini-PC-Home-Server wie der GMKtec M5 Ultra jede Menge Headroom dafür.
Tugtainer vs. Watchtower und Ouroboros
Mehrere Tools können deine Docker-Container automatisch aktualisieren. So vergleicht sich Tugtainer mit Watchtower und Ouroboros:
| Feature | Tugtainer | Watchtower | Ouroboros |
|---|---|---|---|
| Web-UI | Ja (mit Authentifizierung) | Nein | Nein |
| Multi-Host-Support | Ja (über Agents) | Nein | Nein |
| Benachrichtigungen | Ja (Apprise – 80+ Dienste) | Ja | Ja |
| Abhängigkeitsbewusste Updates | Ja (automatisch) | Nein | Nein |
| Konfiguration | GUI | Umgebungsvariablen | Umgebungsvariablen |
| Private Registries | Ja | Ja | Ja |
| Granulare Kontrolle | Ja (pro Container) | Ja (pro Container) | Ja (pro Container) |
| Healthcheck-Monitoring | Ja (Auto-Restart, v1.41+) | Nein | Nein |
| Socket-Proxy-Support | Ja (Standard-Setup) | Nein | Nein |
| Self-Update | Nur manuell | Ja | Ja |
| Pruning | Ja (auto/manuell) | Ja | Ja |
Wissenswert: Watchtowers Entwicklung ist weitgehend eingeschlafen, mit wenigen Releases seit 2023. Es funktioniert noch, aber check das Repo, bevor du dich festlegst.
Wichtige Begriffe
- Abhängigkeitsbewusst: Tugtainer baut pro Host einen Abhängigkeitsgraphen und aktualisiert in der richtigen Reihenfolge. Abhängige Dienste (wie die App vor einer Datenbank) werden zuerst gestoppt, dann startet alles, wobei Abhängigkeiten vor dem hochkommen, was sie braucht.
- Socket-Proxy: Ein Security-Container, der nur erlaubte Docker-API-Calls exponiert. Tugtainer nutzt ihn standardmäßig statt eines rohen Socket-Mounts. Tugtainer kann sich selbst, den Agent oder den Socket-Proxy nicht von innen aktualisieren.
Meine Empfehlung: Nimm Tugtainer, wenn du ein Web-Interface statt Umgebungsvariablen konfigurieren willst, wenn du Container über mehrere Server hinweg verwaltest oder wenn du Dependency-Handling, Update-Delays und Rollback brauchst. Watchtower ergibt weiterhin Sinn für ein simples Single-Host-Setup, bei dem du das absolute Minimum willst. Ouroboros passt, wenn du lieber minimale Konfiguration über Umgebungsvariablen machst.
Wenn dein eigentliches Problem breiteres Container-Management ist (Stacks deployen, nicht nur aktualisieren), schau dir Arcane, einen self-hosted Docker-Container-Manager an. Tugtainer ist absichtlich enger: Es macht Updates gut und bleibt aus dem Weg.
Hauptfeatures
Alles auf Stand von v1.41.0:
- Web-UI mit Authentifizierung: Jeden Container von einem Dashboard aus verwalten
- Multi-Host-Support: Der Tugtainer-Agent verbindet Remote-Server mit einer primären Instanz
- Socket-Proxy per Default: Least-Privilege-Zugriff auf die Docker-API statt eines rohen Socket-Mounts
- Granulare Kontrolle: Jeden Container auf „check only” oder „auto-update” setzen
- Abhängigkeitsbewusste Updates: Baut einen Graphen aus Compose-Dateien und Labels, aktualisiert in der richtigen Reihenfolge
- Automatisches Rollback: Fehlgeschlagene Healthchecks nach einem Update lösen eine Rückkehr zum vorherigen Image aus
- Update-Delay-Puffer: N Sekunden warten, nachdem ein neuer Digest erscheint, bevor geplante Updates greifen
- Healthcheck-Monitoring mit Auto-Restart: Erkennt unhealthy Container, startet mit Backoff neu und führt Historie (neu in v1.41.0)
- Job-Fortschritt in Echtzeit: Checks und Updates live über WebSockets verfolgen (v1.39.0)
- Benachrichtigungen: Discord, Telegram, Slack, E-Mail und mehr via Apprise, mit Jinja2-Templates
- Lifecycle-Hooks: Optionale Pre-/Post-Update-Befehle in Containern (opt-in)
- Private Registries, Crontab-Scheduling und Image-Pruning runden das Ganze ab
Wie du Tugtainer deployst
Zwei Wege: Dokploy, wenn du es schon laufen hast, schlichtes Docker Compose, wenn nicht. So oder so bekommst du dieselben Container.
Option 1: Deploy mit Dokploy
Dokploy erledigt SSL-Zertifikat und Reverse Proxy für dich – das ist, was ich für die Web-UI empfehle. Wenn du Dokploy noch nicht hast, folge unserer Dokploy-Installationsanleitung und lies, wie du eine Docker-Compose-App in Dokploy deployst, für die tieferen Compose-Details.
- Service erstellen: In deinem Dokploy-Projekt auf „Add Service” klicken und „Compose” wählen
- Benennen: Gib ihm einen Namen wie
tugtainer - Konfiguration einfügen: Füge das hier in den Compose-Editor ein (aus der offiziellen Compose-Datei angepasst, mit entferntem Port-Mapping, da Dokploy die Domain routet):
networks:
tugtainer:
driver: bridge
volumes:
tugtainer_data:
services:
socket-proxy:
image: lscr.io/linuxserver/socket-proxy:latest
container_name: socket-proxy
environment:
CONTAINERS: 1
EVENTS: 1
IMAGES: 1
INFO: 1
LOG_LEVEL: warning
PING: 1
NETWORKS: 1
POST: 1
VERSION: 1
ALLOW_LOGS: 1
ALLOW_START: 1
ALLOW_STOP: 1
ALLOW_RESTARTS: 1
ALLOW_PAUSE: 1
ALLOW_UNPAUSE: 1
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: unless-stopped
read_only: true
tmpfs:
- /run
networks:
- tugtainer
labels:
dev.quenary.tugtainer.protected: True
tugtainer:
depends_on:
- socket-proxy
container_name: tugtainer
image: ghcr.io/quenary/tugtainer:1
volumes:
- tugtainer_data:/tugtainer
restart: unless-stopped
environment:
DOCKER_HOST: tcp://socket-proxy:2375
# Required once you add remote agents:
# AGENT_SECRET: set-a-long-random-string
networks:
- tugtainer
labels:
dev.quenary.tugtainer.protected: True- Domain konfigurieren: Im „Domains”-Tab deine Domain hinzufügen (z. B.
updates.yourdomain.com) und auf Port 80 mappen - Deployen: Auf „Deploy” klicken. Dokploy startet beide Container und stellt das Zertifikat aus
Verifizieren, dass es geklappt hat:
docker psauf dem Server zeigttugtainerundsocket-proxyim Lauf- Öffne
https://updates.yourdomain.com/api/public/healthund erwarte eine ok-Antwort (HTTP 200) https://updates.yourdomain.com/api/public/versionzeigt die laufende Version- Der erste Besuch der UI zeigt den Wizard zum Setzen des Admin-Passworts
Wenn der Health-Endpoint nie hochkommt, check Dokploys Deploy-Logs. Die üblichen Ursachen sind der Domains-Tab, der auf den falschen Container-Port zeigt (es sollte 80 sein), oder ein Socket-Proxy-Container im Crash-Loop, weil der Docker-Socket-Pfad falsch ist.
Option 2: Deploy mit Docker Compose
Die offizielle Compose-Datei bringt zwei Services mit: den Socket-Proxy und die App. Wähl die Variante, die zu deiner Risikotoleranz passt:
Socket-Proxy (empfohlen)
networks:
tugtainer:
driver: bridge
volumes:
tugtainer_data:
services:
socket-proxy:
image: lscr.io/linuxserver/socket-proxy:latest
container_name: socket-proxy
environment:
CONTAINERS: 1
EVENTS: 1
IMAGES: 1
INFO: 1
LOG_LEVEL: warning
PING: 1
NETWORKS: 1
POST: 1
VERSION: 1
ALLOW_LOGS: 1
ALLOW_START: 1
ALLOW_STOP: 1
ALLOW_RESTARTS: 1
ALLOW_PAUSE: 1
ALLOW_UNPAUSE: 1
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: unless-stopped
read_only: true
tmpfs:
- /run
networks:
- tugtainer
labels:
dev.quenary.tugtainer.protected: True
tugtainer:
depends_on:
- socket-proxy
container_name: tugtainer
image: ghcr.io/quenary/tugtainer:1
volumes:
- tugtainer_data:/tugtainer
restart: unless-stopped
environment:
DOCKER_HOST: tcp://socket-proxy:2375
# Required once you add remote agents:
# AGENT_SECRET: set-a-long-random-string
# Allow LAN/Docker-network agents (default only allows 127.0.0.1:8001):
# AGENT_ALLOW_NETWORKS: 192.168.0.0/24
# AGENT_ALLOW_ENDPOINTS: 10.0.0.5:9413
networks:
- tugtainer
ports:
- '9412:80'
labels:
dev.quenary.tugtainer.protected: TrueDie ALLOW_*-Liste ist der Least-Privilege-Satz, den Tugtainer braucht. Die Start-/Stop-/Restarts-/Pause-/Unpause-Permissions wurden für Container-Kontrollen erforderlich und NETWORKS für Updates in v1.37.0. Wenn du eine Socket-Proxy-Config aus einer älteren Anleitung kopiert hast, schlagen Updates mit kryptischen Permission-Fehlern fehl, bis du sie hinzufügst.
Direkter Socket-Mount (einfacher, unsicherer)
services:
tugtainer:
image: ghcr.io/quenary/tugtainer:1
container_name: tugtainer
restart: unless-stopped
ports:
- '9412:80'
volumes:
- tugtainer_data:/tugtainer
- /var/run/docker.sock:/var/run/docker.sock:ro
volumes:
tugtainer_data:Ein Container, ein Volume, ein Mount. Es funktioniert, aber alles, was den Tugtainer-Prozess kompromittiert, bekommt die volle Docker-API. Ich würde das nur auf einer Single-Purpose-Homelab-Maschine nutzen.
Den Stack hochfahren und verifizieren:
docker compose up -d
curl http://localhost:9412/api/public/healthErwarte ein 200 vom Health-Endpoint, dann logge dich unter http://server-ip:9412 ein und setze das Admin-Passwort. Wie „kaputt” aussieht:
- Port 9412 schon belegt: ändere die Host-Seite des Mappings, z. B.
'8412:80', oder gib den Port frei mitss -tlnp | grep 9412 - Permission denied auf docker.sock (Direct-Mount-Variante): Dein User ist nicht in der docker-Gruppe oder der Socket-Pfad weicht ab.
ls -l /var/run/docker.sockzum Prüfen - Update-Jobs schlagen mit Permission-Fehlern fehl: Deinem Socket-Proxy fehlen die neueren
ALLOW_*-Variablen
Self-Update-Limitation
Tugtainer kann sich selbst, den Agent oder den Socket-Proxy nicht aus der App heraus aktualisieren. Alle drei tragen genau aus diesem Grund das dev.quenary.tugtainer.protected-Label. Aktualisiere sie manuell mit docker compose pull && docker compose up -d, über Dokploys Redeploy (siehe, wie man Docker-Compose-Stacks in Dokploy aktualisiert) oder mit einem anderen Tool wie Portainer.
Remote-Hosts mit dem Tugtainer-Agent verwalten
Du brauchst keine volle Tugtainer-Instanz auf jedem Server. Deploye den Agent, der lokal dasselbe Socket-Proxy-Muster fährt und eine API für die primäre Instanz exponiert:
networks:
tugtainer_agent:
driver: bridge
services:
socket-proxy:
image: lscr.io/linuxserver/socket-proxy:latest
container_name: socket-proxy
environment:
CONTAINERS: 1
EVENTS: 1
IMAGES: 1
INFO: 1
LOG_LEVEL: warning
PING: 1
NETWORKS: 1
POST: 1
VERSION: 1
ALLOW_LOGS: 1
ALLOW_START: 1
ALLOW_STOP: 1
ALLOW_RESTARTS: 1
ALLOW_PAUSE: 1
ALLOW_UNPAUSE: 1
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: unless-stopped
read_only: true
tmpfs:
- /run
networks:
- tugtainer_agent
labels:
dev.quenary.tugtainer.protected: True
agent:
depends_on:
- socket-proxy
container_name: tugtainer-agent
image: ghcr.io/quenary/tugtainer-agent:1
restart: unless-stopped
read_only: true
tmpfs:
- /run
environment:
AGENT_SECRET: set-a-long-random-string
DOCKER_HOST: tcp://socket-proxy:2375
networks:
- tugtainer_agent
ports:
- '9413:8001'
labels:
dev.quenary.tugtainer.protected: TrueSetze denselben AGENT_SECRET-Wert auf der primären Instanz und dem Agent. Generiere einen mit openssl rand -hex 32 und behandle ihn wie jede andere Credential. Compose unterstützt auch echte Secrets; siehe Docker-Compose-Secrets und sichere Alternativen für die Optionen.
Agent-Secrets und private Netzwerke
Nutze ein langes, einzigartiges AGENT_SECRET pro Flotte, nicht den Beispielwert. Bedenke außerdem: Die primäre Instanz blockt standardmäßig Agent-URLs, die auf private oder reservierte Netzwerke auflösen. Nur der eingebaute 127.0.0.1:8001-Endpoint ist out of the box erlaubt – ein LAN-Agent kann sich also nicht verbinden, bis du ihn allow-listest.
Das Allow-Listing passiert auf der primären Instanz, nicht auf dem Agent. Füge eines oder beides der Umgebung des Tugtainer-Containers hinzu:
environment:
# Allow a whole subnet (LAN or Docker network)
- AGENT_ALLOW_NETWORKS=192.168.0.0/24
# Or pin exact agent endpoints (IP:port)
- AGENT_ALLOW_ENDPOINTS=10.0.0.5:9413TLS-Optionen für die Agent-Verbindung
Backend und Agent sprechen standardmäßig schlichtes HTTP:
- Öffentliche CA (Let’s Encrypt etc.): Setze einen Reverse Proxy vor den Agent und trage die Host-URL als
https://...in der UI ein. Traefik funktioniert gut; siehe unser Traefik-Reverse-Proxy-Setup für Docker - Private CA oder self-signed: Füge das CA-PEM ins „Custom CA”-Feld der Host-Einstellungen ein (unterstützt seit v1.36.0). Der Zertifikats-Hostname muss zur URL passen
- Natives TLS ohne Proxy: Mounte Cert/Key in den Agent und erweitere den Command um
--ssl-certfile/--ssl-keyfile. Caveat: Der eigene Healthcheck des Agents rufthttp://localhost:8001auf und kann unhealthy melden, wenn uvicorn nur HTTPS serviert
Nach dem Agent-Deploy gehst du in der Web-UI auf Menu → Hosts, fügst den Host mit seiner IP (oder Domain) und dem AGENT_SECRET hinzu. Verifizieren: Der Host zeigt online in der Hostliste, dann führe ein manuelles „Check all” gegen ihn aus und schau zu, wie das Live-Job-Journal die Ergebnisse streamt.
Die Tugtainer-Web-UI
Einmal deployed, zeigt das Dashboard alle Container und ihren Update-Status.

Das Dashboard zeigt alle deine Container, ihre aktuellen Versionen und ob Updates verfügbar sind. Du siehst schnell, welche Container auf Auto-Update stehen und welche geschützt sind. (Screenshots stammen von Anfang 2026; spätere Versionen sehen etwas anders aus.)

Aus dieser Ansicht kannst du:
- Detailinformationen zu jedem Container ansehen
- Zwischen „check only”- und „auto-update”-Modi umschalten
- Die Tabelle nach Status filtern (hinzugefügt in v1.33.0)
- Mehrere Container auswählen und als Batch prüfen oder aktualisieren
- Die laufende Version aus den Image-Labels sehen (v1.38.0) und einen Source-Code-Link auf der Karte (v1.36.0)

Die Einzelcontainer-Ansicht lässt dich konfigurieren:
- Update-Zeitplan und Update-Delay pro Container
- Benachrichtigungs-Präferenzen
- Dependency-Management
- Custom Labels und ein Healthcheck-Timeout-Override (v1.40.0)
Seit v1.39.0 gibt es außerdem einen Jobs-Fortschrittsdialog: Wenn du einen Check oder ein Update laufen lässt, streamt er ein Live-Journal über WebSockets – du kannst also zusehen, wie die Pull-, Stop-, Recreate- und Start-Schritte jedes Containers passieren, statt auf einen Spinner zu starren.
Erster Login
Beim ersten Besuch der Tugtainer-Web-UI richtest du einen Administrator-Account ein.
- Passwort erstellen: Setze ein sicheres Passwort beim initialen Setup
- Login: Nutze das erstellte Passwort, um ins Dashboard zu kommen
- Passwort ändern: Du kannst dein Passwort später in den Einstellungen ändern
Tugtainer generiert kein Zufallspasswort wie manche Docker-Tools. Du setzt es selbst im Setup-Wizard – wähl also etwas Langes.
Der Check- und Update-Prozess
Tugtainer verarbeitet jeden Host als eine Einheit. Es baut einen Abhängigkeitsgraphen aus Compose-Metadaten (depends_on zwischen Containern desselben Compose-Projekts) und aus dem Custom-depends_on-Label für projektübergreifende Links. Geschützte Container und gestoppte Container werden übersprungen.
Wenn ein Update läuft (per Zeitplan oder manuell):
- Digest-Check: Tugtainer vergleicht den Image-Digest jedes Containers mit der Registry und markiert Container mit einem neueren Image als „available”
- Pull: Neue Images werden für den aktualisierbaren Satz gepullt
- Stop-Reihenfolge: Alle beteiligten Container stoppen einmal, beginnend bei den am stärksten abhängigen
- Recreate und Start: Aktualisierbare Container werden mit dem neuen Image neu erstellt, und alles startet in umgekehrter Reihenfolge, Abhängigkeiten zuerst
- Healthcheck-Warte: Nach dem Start wartet Tugtainer auf Healthchecks. Wird ein aktualisierter Container unhealthy, rollt es zurück auf das vorherige Image
Jobs auf demselben Host serialisieren (ein Check von A und B kann ein Update von C und D nicht überlappen), während verschiedene Hosts parallel laufen. Jeder Host führt eine Job-History, die du in der UI einsehen kannst.
Update-Delay (ein Sicherheitspuffer)
Neue Releases werden manchmal innerhalb von Stunden nach Veröffentlichung zurückgezogen. Das Delay-Feature lässt geplante Updates warten, bis ein neuer Digest eine Weile stabil war:
DELAY_UPDATE_FORist die globale Einstellung in Sekunden, Default0(kein Delay)- Ein
delay_update_for-Override pro Container gewinnt, wenn gesetzt - Der Check läuft weiterhin und benachrichtigt dich sofort; nur das geplante Update wartet
- Manuelle Updates ignorieren das Delay komplett
Für Dienste, die wichtig, aber nicht sicherheitskritisch sind, würde ich 24–48 Stunden setzen. Für deinen Reverse Proxy oder dein VPN lieber schnell aktualisieren. Eine Footgun: Der manuelle „Update all”-Button umgeht das Delay – nutze ihn also nicht als Hotfix-Pfad für verzögerte Container, es sei denn, du hast den Changelog gelesen.
Zurückrollen auf das vorherige Image
Seit v1.34.0 zeichnet jedes erfolgreiche Update auf, was der Container vorher lief:
previous_image_digests: die Repo-Digests, wienginx@sha256:.... Das ist der einzige Wert, der das exakte Image wieder pinntprevious_image_tags: die lokalen Tags, die das alte Image hatte (weniger nützlich, wenn dulatesttrackst)previous_image_version: ein Hinweis aus den Image-Labels, kein garantierter Tag
Alle drei stehen auf der Container-Karte. Der automatische Weg: Wenn ein neu erstellter Container seinen Healthcheck nach einem Update vermasselt, rollt Tugtainer ihn von allein auf das vorherige Image zurück und markiert das Ergebnis als rolled_back. Der manuelle Weg: Kopiere den Digest von der Karte in deine Compose-Datei und erstelle neu:
services:
nginx:
image: nginx@sha256:abc123... # paste previous_image_digests herePinne den Digest, nicht das Version-Label. Werte werden nur nach erfolgreichen Updates aufgezeichnet, denn nach einem Rollback ist das vorherige Image das aktuelle.
Lifecycle-Hooks (opt-in)
Hooks lassen dich Shell-Befehle in einem Container an Punkten des Update-Lifecycle ausführen: pre_update, post_update, pre_stop, pre_rollback und post_rollback. Jeder läuft als sh -c "<command>" im Zielcontainer.
So snapshotest du eine Datenbank vor Updates – z. B. ein pre_update-Hook, der pg_dump ausführt. Tugtainer bringt keine eingebaute Backup-Logik mit; du schreibst den Befehl und verwaltest, wohin die Ausgabe geht.
Die Failure-Semantik ist vernünftig:
- Ein fehlschlagender
pre_update- oderpre_stop-Hook bricht das Update dieses Containers ab und lässt ihn wie bisher laufen post_update-,pre_rollback- undpost_rollback-Fehler werden geloggt und blockieren nie etwas
Hooks führen beliebige Befehle aus
Hooks sind by design Remote Code Execution. Sie brauchen zwei Schalter gleichzeitig: ALLOW_HOOKS=true auf dem Tugtainer-Backend und ALLOW_EXEC=true auf dem Agent für den jeweiligen Host. Lass beide aus, wenn du keinen konkreten Grund hast, und aktiviere ALLOW_EXEC niemals auf Hosts, die nicht vertrauenswürdige Workloads laufen lassen.
Deine Container überwachen
Auto-Update-Systeme scheitern leise, wenn ein neues Image beim Boot abstürzt. Das Healthcheck-Monitoring-Feature (neu in v1.41.0) adressiert das: Tugtainer inspiziert periodisch Docker-Healthchecks über alle aktivierten Hosts hinweg und verfolgt Statusübergänge über die Zeit.
So funktioniert es:
- Erkennung: Läuft auf einem Crontab-Schedule (
HEALTH_MONITOR_CRON_EXPR, Default alle 3 Minuten). Container ohne Docker-Healthcheck werden übersprungen – das deckt also nur Container ab, die einen definieren - Fehler-Tracking: Aufeinanderfolgende unhealthy Checks werden pro Container gezählt
- Automatische Restarts mit Backoff: Wenn Fehler
(restart_attempts + 1) * HEALTH_MONITOR_N_TO_RESTARTerreichen, wird der Container neu gestartet. Restarts deckeln beiHEALTH_MONITOR_RESTART_ATTEMPTS. Standardmäßig deaktiviert; setzeHEALTH_MONITOR_N_TO_RESTARTauf eine positive Zahl (z. B.3) zum Aktivieren - Benachrichtigungen: Werden nach
HEALTH_MONITOR_N_TO_NTFYaufeinanderfolgenden Fehlern geschickt (Default 3), mit einer Recovery-Notice, wenn der Container wieder healthy wird - Historie: Jedes Status-Event landet in einer Historientabelle, aufgeräumt nach
HEALTH_MONITOR_HISTORY_DAYS(Default 7)
Alle Einstellungen leben unter Menu → Settings:
| Einstellung | Default | Was sie tut |
|---|---|---|
HEALTH_MONITOR_CRON_EXPR |
*/3 * * * * |
Wie oft der Health-Job läuft |
HEALTH_MONITOR_N_TO_RESTART |
-1 (aus) |
Aufeinanderfolgende Fehler vor einem Restart |
HEALTH_MONITOR_N_TO_NTFY |
3 |
Aufeinanderfolgende Fehler vor einer Benachrichtigung |
HEALTH_MONITOR_RESTART_ATTEMPTS |
3 |
Max. Restart-Versuche pro Container |
HEALTH_MONITOR_HISTORY_DAYS |
7 |
Tage Historie behalten (unter 0 behält für immer) |
HEALTH_MONITOR_NTFY_BODY_TMPL |
eingebaut | Jinja2-Template für den Notification-Body |
Beim Warten darauf, dass ein Container nach einem Restart healthy wird, kommt der Timeout in dieser Reihenfolge: der Override pro Container (Container-Karte, seit v1.40.0), die CONTAINER_HC_TIMEOUT-Einstellung des Hosts, dann ein 60-Sekunden-Fallback.
Verifizieren, dass es funktioniert: Öffne die Healthcheck-Monitoring-Kachel auf dem Dashboard, die zu /hosts/:id/health und der Historientabelle führt. Um Events absichtlich zu erzeugen, lass einen Test-Container mit einem fehlschlagenden Healthcheck laufen:
docker run -d --name hc-test --health-cmd "false" busybox sleep 300Innerhalb weniger Zyklen zeigt der Container unhealthy in der Historie. Aufräumen mit docker rm -f hc-test.
Das ergänzt Outside-in-Monitoring statt es zu ersetzen. Tugtainer startet unhealthy Container von innen neu; Tools wie Beszel- und Uptime-Kuma-Monitoring auf Dokploy sagen dir aus Nutzersicht, wie es um Host-Ressourcen und Service-Uptime steht. Ich betreibe beide. Für CPU-, Memory- und Disk-Trends auf Host-Ebene siehe unseren Server-Monitoring-Dashboards-Guide, und für Alerting speziell auf Endpoints ist das Uptime-Kuma-Self-Hosted-Monitoring-Tool die langweilig zuverlässige Wahl.
Benachrichtigungen
Tugtainer nutzt Apprise für die Zustellung und Jinja2 für den Nachrichteninhalt – du bekommst also Discord, Telegram, Slack, E-Mail und grob 80 andere Dienste aus einer Konfiguration.
Jeder Container in einem Check- oder Update-Job bekommt eines dieser Ergebnisse:
not_available: kein neues Imageavailable: neues Image gefundenavailable(notified): neues Image, aber du wurdest schon informiert. Tugtainer merkt sich Digests, zu denen es benachrichtigt hat – wiederholte Checks spammen dich also nicht zuupdated: erfolgreich mit dem neuen Image neu erstelltrolled_back: Recreate fehlgeschlagen, vorheriges Image wiederhergestelltfailed: Recreate fehlgeschlagen, kein Rollback
Eine Feinheit: Eine Benachrichtigung wird nur geschickt, wenn der gerenderte Body nicht leer ist. Wenn jeder Container mit available(notified) zurückkommt, produziert das Default-Template nichts, und keine Nachricht geht raus. Das ist Dedupe wie beabsichtigt, kein kaputter Webhook.
Der Health-Monitor hat sein eigenes Template und Context (HEALTH_MONITOR_NTFY_BODY_TMPL), sodass Unhealthy-/Recovery-Alerts getrennt von Update-Ergebnissen rendern. Es gibt außerdem einen any_worthy-Jinja2-Filter, wenn du Templates anpasst: Er ist true, wenn mindestens ein Container available, updated, rolled_back oder failed ist.
Ein Haken für Self-Hoster: Notification-URLs, die auf private oder reservierte Netzwerke auflösen, werden durch einen Best-Effort-SSRF-Check geblockt. Wenn du ntfy oder einen anderen Webhook-Empfänger im selben privaten Netz betreibst, kann er geblockt werden. Die strengere Option ist NOTIFICATION_ALLOW_SCHEMES (z. B. tgram,discord,ntfy), die die Zustellung auf die Schemes beschränkt, die du nutzt.
Verifizieren: Konfiguriere deinen Discord-Webhook in den Notification-Einstellungen, drück manuell „Check all” und bestätige, dass die Nachricht im Channel landet.
Authentifizierung und Sicherheit
Standardmäßig nutzt Tugtainer Passwort-Authentifizierung, die in einer verschlüsselten Datei gespeichert ist. Ab v1.6.0 kannst du einen OpenID-Connect(OIDC)-Provider konfigurieren, um den Login über dein bestehendes Identity-Management-System abzuwickeln.
OIDC-Authentifizierung einrichten
Um OIDC-Authentifizierung zu aktivieren, brauchst du:
-
OIDC-Provider: Konfiguriere deinen Provider (Auth0, Keycloak, Authentik, Azure AD, Google etc.) mit:
- Client ID
- Client Secret
- Issuer URL
- Redirect-URL (deine Tugtainer-Domain +
/auth/callback)
-
Umgebungsvariablen: Füge diese deinem Tugtainer-Container hinzu:
environment:
- OIDC_ENABLED=true
- OIDC_CLIENT_ID=your_client_id
- OIDC_CLIENT_SECRET=your_client_secret
- OIDC_ISSUER=https://your-provider.com
- OIDC_REDIRECT_URI=https://tugtainer.yourdomain.com/auth/callback
- OIDC_SCOPES=openid email profile
# Optional allowlists:
# - [email protected]
# - OIDC_ALLOWED_SUBJECTS=auth0|12345- Container neu starten: Übernimm die Änderungen, indem du den Container neu erstellst
Dinge, die in 2026er-Releases verschärft wurden und wissenswert sind, bevor du einen Login debuggst, der „früher funktioniert hat”: Seit v1.31.3 werden ID-Token serverseitig verifiziert – dein Provider muss also mit einem asymmetrischen Key signieren (RS*/ES*, nicht HS256), der iss-Claim muss exakt zum Issuer des Discovery-Dokuments passen, und openid muss in den Scopes sein, damit ein id_token zurückkommt. Refresh-Token-Support kam in v1.30.3. Die optionalen OIDC_ALLOWED_EMAILS- / OIDC_ALLOWED_SUBJECTS-Listen beschränken, welche Identitäten sich einloggen können.
Den Docker-Socket und die Agents absichern
Der Socket-Proxy ist aus einem Grund das Default-Muster: Er exponiert nur die API-Calls, die Tugtainer braucht, mit einem Read-Only-Socket-Mount im Proxy-Container. Halte die ALLOW_*-Liste minimal; jede Permission, die du hinzufügst, erweitert den Explosionsradius, falls Tugtainer je kompromittiert wird.
Agent-seitige Härtung hat sich durch 2026 ebenfalls verbessert: AGENT_ALLOW_NETWORKS / AGENT_ALLOW_ENDPOINTS geben dir eine Default-Deny-Haltung für Agent-Endpoints, und v1.34.2 fügte DNS-Rebinding-Schutz hinzu, sodass validierte Agent-IPs für die Verbindung gepinnt werden.
Default-Deny-Haltung
Out of the box werden Agent-Endpoints in privaten Netzwerken geblockt, bis du sie allow-listest, und Notification-URLs, die auf private Netzwerke zeigen, werden ebenfalls geblockt. Beide öffnen sich nur, wenn du sie explizit konfigurierst – das ist der richtige Default für eine internet-facing Maschine.
Sei aber ehrlich zum Threat Model. Das ist ein Single-Operator-Tool mit einem Privilege-Level: Ein authentifizierter Admin kann über die UI eh alles mit Docker machen. Es ist für ein vertrauenswürdiges Netzwerk gebaut, das du kontrollierst, nicht für Multi-Tenant-Exposition. Halte es vom öffentlichen Internet fern, oder mindestens hinter SSO und Reverse-Proxy-Auth. Bevor du irgendeinen Docker-nahen Dienst exponierst, lohnt es sich, unserem Guide zum Absichern deines Docker-Servers anhand des BSI-Hardening-Reports zu folgen.
Meine kurze Hardening-Checkliste für eine Tugtainer-Maschine:
- HTTPS via Dokploy oder Traefik; exponiere 9412 niemals roh ins Internet
- Starkes, einzigartiges
AGENT_SECRET, bei deinen anderen Secrets gelagert - Socket-Proxy statt roher Socket-Mounts, überall
- OIDC oder ein langes zufälliges Admin-Passwort, nicht
password123 - Hooks aus, wenn kein Workload sie wirklich braucht
NOTIFICATION_ALLOW_SCHEMESverschärft, wenn du Webhook-Empfänger selbst hostest- Patche den Host selbst; Tugtainer aktualisiert Container, nicht dein OS
Tugtainer im Alltag betreiben
Backups
Was zählt, sind die Daten deiner Container, nicht Tugtainers State. Auto-Updates sind genau die Zeit, in der du frische Backups willst: Snapshote Volumes vor geplanten Update-Fenstern und nutze pre_update-Hooks für Datenbank-Dumps, wenn ein Container Daten hält, die du nicht regenerieren kannst. Tugtainers eigenes tugtainer_data-Volume hält Config und Historie. Es zu verlieren ist ärgerlich, nicht katastrophal.
Tugtainer selbst aktuell halten
Es kann sich selbst, den Agent oder den Socket-Proxy nicht aktualisieren. Ich mache einen monatlichen manuellen Durchgang:
cd /path/to/tugtainer-stack
docker compose pull && docker compose up -dDas deckt alle geschützten Container im Stack ab. Dasselbe auf den Agent-Hosts.
Pruning
Alte Images stapeln sich nach jedem Update-Zyklus. Tugtainer kann automatisch oder on demand aus den Einstellungen prunen. Für tiefere Aufräumarbeiten siehe, wie du alle Docker-Images, -Container und -Volumes aufräumst, und wenn der Disk-Verbrauch weiter steigt, geht unser Guide zum Zurückholen von Festplattenplatz aus /var/lib/docker/overlay2 an das, was Pruning verfehlt.
Es abschalten
Schalte Container zurück auf „check only”, wenn du die Sichtbarkeit ohne die Automatisierung behalten willst, oder entferne die Stacks komplett:
docker compose down # keeps the tugtainer_data volume
docker compose down -v # also wipes Tugtainer's stateSo oder so laufen deine Workloads unangetastet weiter. Tugtainer zu entfernen entfernt nur die Automatisierung, niemals die Container, die es verwaltet hat.
Häufige Probleme troubleshooten
- Agent-Host zeigt unreachable →
AGENT_SECRETpasst nicht zwischen Primary und Agent, oder die private IP des Agents ist geblockt. SetzeAGENT_ALLOW_NETWORKSoderAGENT_ALLOW_ENDPOINTSauf der primären Instanz - Updates schlagen mit Socket-Proxy-Permission-Fehlern fehl → dem Proxy fehlen erforderliche
ALLOW_*-Variablen, vor allemALLOW_START/ALLOW_STOP/ALLOW_RESTARTSundNETWORKS(Anforderungen geändert in v1.37.0) - „Cannot update”-Fehler auf tugtainer, dem Agent oder socket-proxy → Sie tragen by design das
protected-Label. Aktualisiere sie manuell - Port 9412 oder 9413 schon belegt → ändere die Host-Seite des Port-Mappings in Compose. Beachte außerdem: Der Agent-Stack erwartet seinen eigenen Host; den vollen Agent-Compose auf derselben Maschine wie die primäre Instanz laufen zu lassen, kollidiert beim
socket-proxy-Container-Namen - Agent-Container unhealthy nach Aktivieren von nativem TLS → sein Healthcheck ruft
http://localhost:8001auf, was fehlschlägt, wenn uvicorn nur HTTPS serviert. Bevorzuge Reverse-Proxy-TLS - Keine Benachrichtigungen kommen an → entweder war jedes Ergebnis
available(notified)(leerer Body, nichts gesendet) oder deine Webhook-URL wird vom Private-Network-SSRF-Check geblockt - Container hängt in einer Rollback-Schleife nach einem schlechten Image → pinne
previous_image_digestsvon der Container-Karte in deine Compose-Datei, deaktiviere Auto-Update für diesen Container und warte auf einen gefixten Release - OIDC-Login-Redirect-Fehler →
OIDC_REDIRECT_URImuss exakt deiner Domain plus/auth/callbackentsprechen, und seit v1.31.3 muss der Provider ein asymmetrisch signiertes ID-Token mit passendem Issuer zurückgeben
Häufige Fragen
Wie behandelt Tugtainer Container-Abhängigkeiten?
Tugtainer baut pro Host einen Abhängigkeitsgraphen aus Compose-depends_on-Metadaten (für Container im selben Compose-Projekt) und aus dem dev.quenary.tugtainer.depends_on-Label für projektübergreifende Links. Während Updates stoppt es alle beteiligten Container einmal, beginnend bei den am stärksten abhängigen, dann erstellt und startet es alles in umgekehrter Reihenfolge, sodass Datenbanken hochkommen, bevor die Dienste da sind, die sie brauchen. Container ohne Abhängigkeiten werden als unabhängig behandelt.
Kann ich bestimmte Container von Auto-Updates ausschließen?
Ja, auf mehrere Arten:
- Nutze das
dev.quenary.tugtainer.protected=true-Label, um zu verhindern, dass Tugtainer einen Container überhaupt stoppt oder aktualisiert - Setze einzelne Container in der Web-UI auf „check only”, sodass du benachrichtigt wirst, aber nichts automatisch aktualisiert wird
- Setze ein Update-Delay pro Container, wenn du Updates irgendwann willst, nur nicht an Tag eins
Was passiert, wenn ein Update fehlschlägt?
Zwei Schutzschichten. Wenn der neu erstellte Container seinen Healthcheck nach dem Start vermasselt, rollt Tugtainer automatisch auf das vorherige Image zurück und markiert das Ergebnis als rolled_back. Wenn das Recreate selbst fehlschlägt, ist das Ergebnis failed. So oder so bekommst du eine Benachrichtigung über deine konfigurierten Apprise-Dienste, das alte Image bleibt lokal verfügbar, und die Container-Karte zeichnet previous_image_digests auf, sodass du die letzte bekannte gute Version manuell pinnen kannst.
Ist Tugtainer sicher für Produktivumgebungen?
Die Entwickler empfehlen es nicht für kritische Produktivumgebungen ohne Tests. Wenn du es in produktionsnahem Terrain betreibst:
- Teste Updates zuerst in Staging
- Halte regelmäßige Backups und snapshotte vor Update-Fenstern
- Starte kritische Dienste im „check only”-Modus und beobachte ein paar Zyklen
- Nutze das Update-Delay, damit schlechte Releases ausreifen, bevor sie dich erreichen
- Habe den Rollback-Pfad (healthcheck-basiert oder manuelles Digest-Pinnen) bestätigt, bevor du Auto-Update aktivierst
Wie verwalte ich Docker-Festplattenplatz mit Tugtainer?
Tugtainer enthält automatisches oder manuelles Pruning alter Images, was den Großteil des Wachstums durch häufige Updates abdeckt. Für eine komplette Aufräumung folge unserem Guide, wie du alle Docker-Images, -Container und -Volumes aufräumst. Wenn der Disk-Verbrauch weiter kriecht, siehe, wie du Festplattenplatz aus /var/lib/docker/overlay2 zurückholst.
Kann Tugtainer sich selbst aktualisieren?
Nein. Tugtainer, der Tugtainer-Agent und der Socket-Proxy tragen alle das dev.quenary.tugtainer.protected=true-Label und können nicht aus der App heraus aktualisiert werden. Aktualisiere sie manuell mit docker compose pull && docker compose up -d in jedem Stack-Verzeichnis oder über Dokploys Redeploy. Dieselbe Limitation gilt für jeden Container, den du selbst schützt.
Startet Tugtainer unhealthy Container neu?
Ja, aber es ist opt-in. Healthcheck-Monitoring (v1.41.0) verfolgt aufeinanderfolgende unhealthy Checks, und Restarts greifen, wenn du HEALTH_MONITOR_N_TO_RESTART auf eine positive Zahl setzt (Default ist -1, aus). Restarts nutzen Backoff, deckeln bei HEALTH_MONITOR_RESTART_ATTEMPTS (Default 3), und jeder Fehler und jede Recovery wird in die Health-Historientabelle geloggt. Container ohne Docker-Healthcheck werden nie angefasst.
Kann ich Updates verzögern, damit schlechte Releases meinen Server nicht treffen?
Ja. Setze DELAY_UPDATE_FOR (Sekunden) global oder pro Container. Geplante Updates greifen erst, nachdem ein neuer Image-Digest für die Delay-Periode stabil war – Releases, die innerhalb von Stunden zurückgezogen oder gehotfixt werden, erreichen dich also nie. Check-Benachrichtigungen feuern trotzdem sofort, und manuelle Updates umgehen das Delay.
Wie komme ich nach einem schlechten Update zurück auf ein älteres Container-Image?
Wenn der Container einen Healthcheck hat, ist das Rollback automatisch, sobald die neue Version unhealthy wird. Andernfalls öffne die Container-Karte in der Tugtainer-UI, kopiere previous_image_digests und setze diesen Digest ins image:-Feld deiner Compose-Datei, dann erstelle den Container neu. Pinne den Digest statt dem Version-Label; das Label ist nur ein Hinweis des Publishers und existiert nicht garantiert als Registry-Tag.
Wie vergleicht sich Tugtainer mit manuellen Docker-Compose-Updates?
Du kannst immer manuell mit docker compose pull und docker compose up -d aktualisieren, wie in unserem Docker-Compose-Update-Guide gezeigt, und Dokploy-Nutzer haben ihren eigenen Flow zum Aktualisieren von Docker-Compose-Stacks in Dokploy. Tugtainer automatisiert diese Schleife:
- Prüft auf Updates nach Zeitplan und benachrichtigt dich
- Handhabt die Abhängigkeitsreihenfolge über den ganzen Host hinweg
- Fügt einen Delay-Puffer und automatisches Rollback bei fehlgeschlagenen Healthchecks hinzu
- Gibt dir eine UI über mehrere Hosts hinweg
Verwandte Artikel
- Best Self-Hosted Panels: A Comparison – Vergleiche Tugtainer mit anderen Self-Hosted-Management-Lösungen
- Top 60+ Docker Commands Every Developer MUST Know – Essenzielle Docker-Befehle für Container-Management
- Dokploy Install – Self-Host Your SaaS – Komplette Dokploy-Installationsanleitung
- How To Update Containers With Docker Compose – Manueller Container-Update-Guide
- How To Clean All Docker Things – Komplette Docker-Aufräum-Anleitung
- Monitor Server Resources – Server- und Docker-Ressourcen-Monitoring
- Arcane Docker Install: Self-Hosted Container Manager – Breiteres Container-Management, wenn Updates nicht dein einziges Problem sind
- Arcane vs. Dockhand im Vergleich – Welcher Docker-Manager zu deinem Setup passt
Hat diese Anleitung bei dir funktioniert?
Brauchst du Hilfe bei Astro, VPS oder einer Self-hosted-App? Services ansehen →


