Bis hierher hast du alles im Terminal gemacht: SSH-Login, docker compose up -d, Logs mit docker logs, Container neu starten von Hand. Das funktioniert – aber sobald drei oder vier Stacks laufen, wird es mühsam. Welcher Container nutzt gerade viel RAM? Ist der Vaultwarden-Stack noch healthy? Hat das Update von gestern Nacht durchgezogen?

Genau dafür installieren wir jetzt Komodo: eine Web-Oberfläche für Docker, mit der du Stacks anlegst, bearbeitest, deployst und überwachst – alles im Browser, ohne SSH-Session. Komodo läuft ausschließlich über das Tailscale-Netz aus dem letzten Artikel. Es gibt keinen offenen Port, kein öffentliches Login-Formular, keine Domain. Sichtbar ist die Oberfläche nur für deine eigenen Geräte.

Am Ende hast du

  • Komodo Core + Periphery installiert (mit Postgres + FerretDB)
  • Web-Oberfläche erreichbar über die Tailscale-IP deines Servers
  • Admin-Account angelegt, Registrierung wieder geschlossen
  • Periphery per Onboarding-Key verbunden – PKI-basiert, ohne manuell verwaltete Secrets
  • Einen Test-Stack über die Komodo-UI deployed (Workflow erfolgreich demonstriert)
  • Verstanden, wann du Stacks künftig per UI pflegst – und wann nicht (Bootstrap-Ausnahme)

Voraussetzungen

  • Artikel 02–05 abgeschlossen
  • Tailscale läuft auf Server und lokalem Rechner
  • docker compose funktioniert als Benutzer martin ohne sudo
  • homelab_net existiert (aus Artikel 03)
  • Du kennst die Tailscale-IP deines Servers (oder ermittelst sie gleich nochmal mit tailscale ip -4)

1. Was Komodo dir gibt

Komodo ist ein Web-Frontend für Docker. Konkret heißt das:

  • Alle Container auf einen Blick mit CPU-, RAM- und Status-Anzeige
  • Logs in Echtzeit im Browser, ohne docker logs -f im Terminal
  • Compose-Dateien direkt in der UI editieren, mit Syntax-Highlighting
  • Stacks deployen, restarten, stoppen per Mausklick
  • Update-Erkennung für Container-Images – inkl. optionalem Auto-Update
  • Mehrere Server verwalten aus einem Dashboard (über Periphery-Agents auf jedem Host)
  • Alerts bei Problemen oder Updates – z. B. per E-Mail oder ntfy

Core und Periphery

Komodo besteht aus zwei Bausteinen:

Komponente Wofür?
Komodo Core Die Web-UI, die du im Browser aufrufst. Speichert Stack-Definitionen, Logins, History.
Komodo Periphery Ein Agent, der auf jedem verwalteten Server läuft und dort tatsächlich die docker-Befehle ausführt.

Bei Single-Host-Setups (egal ob VPS oder NAS) laufen beide auf demselben Gerät, getrennt nur durch das interne Docker-Netz. Wenn du später einen zweiten Server hast, installierst du dort nur Periphery – Core bleibt einmal zentral.

Im fertigen Stack laufen am Ende vier Container: Komodo Core, Komodo Periphery, Postgres (mit DocumentDB-Extension) und FerretDB als MongoDB-Adapter dazwischen.

Authentifizierung zwischen Core und Periphery

Core und Periphery authentifizieren sich über automatisch erzeugte Schlüsselpaare (Ed25519). Du musst kein Geheimnis selbst generieren und in Config-Dateien synchron halten:

  1. Beim ersten Start erzeugen Core und Periphery jeweils ihr eigenes Schlüsselpaar in einem geteilten Docker-Volume.
  2. In der .env weisen wir beide an, den Public Key des jeweils anderen direkt aus diesem Volume zu lesen.
  3. Ab da läuft die gegenseitige Authentifizierung kryptografisch über die ausgetauschten Public Keys – manueller Eingriff: keiner.

Bei mehreren Servern (z. B. später ein NAS dazu) kommt zusätzlich ein Onboarding-Key ins Spiel: ein einmalig in der UI generierter Schlüssel, der einen neuen Periphery-Agenten dem bestehenden Core vorstellt. Das brauchen wir in dieser Single-Host-Installation aber nicht – ist erst in Reihe 2 relevant.

2. Zugriff: ausschließlich über Tailscale

Komodo darf alle Container auf deinem Server starten, stoppen, löschen. Das bedeutet: kein öffentliches Login-Formular, kein offener Port im Internet, keine Domain. Die Oberfläche ist nur über das Tailscale-VPN erreichbar – genau dafür haben wir es im letzten Artikel eingerichtet.

Wir binden Komodos Port 9120 deshalb gezielt an die Tailscale-IP deines Servers. Docker veröffentlicht den Port dann nur auf diesem Interface, nicht auf 0.0.0.0. Damit umgehen wir auch das aus Artikel 03 bekannte Problem, dass Docker die UFW-Regeln umgeht: Wenn der Port erst gar nicht auf der öffentlichen IP gebunden wird, kommt da auch nichts an.

Tailscale-IP ermitteln und merken:

tailscale ip -4

Erwartung: Eine Adresse aus dem Bereich 100.x.x.x. Schreib sie auf – du trägst sie gleich in die .env-Datei ein.

3. Stack-Verzeichnis anlegen

Wir folgen dem Pattern aus Artikel 03: Jeder Stack bekommt einen eigenen Ordner unter /srv/docker/stacks/.

mkdir -p /srv/docker/stacks/komodo
cd /srv/docker/stacks/komodo

Die einzelnen Daten-Verzeichnisse (für Postgres, FerretDB) legt Docker beim ersten Start selbst als benannte Volumes an.

4. Secrets generieren

Komodo nutzt PKI für die Core-Periphery-Authentifizierung (siehe Sektion 1) – das spart einige Geheimnisse, die du sonst selbst pflegen müsstest. Was bleibt, sind drei Werte:

echo "DB Passwort:      $(openssl rand -hex 24)"
echo "JWT Secret:       $(openssl rand -base64 48)"
echo "Webhook Secret:   $(openssl rand -base64 32)"

Das Ergebnis sind drei Zeichenketten. Kopiere sie an einen sicheren Ort – auf deinem lokalen Rechner in einen Passwort-Manager oder zumindest in eine verschlüsselte Notiz. Du brauchst sie gleich in der .env-Datei und solltest sie sichern, falls du den Stack neu aufsetzt.

Warum -hex beim DB-Passwort, aber -base64 beim Rest?

Komodo baut intern eine Datenbank-Verbindung in der Form mongodb://user:PASSWORT@host. Sonderzeichen wie +, / oder = – die openssl rand -base64 regelmäßig erzeugt – haben in einer URI eine eigene Bedeutung und brechen das Parsing („password must be URL encoded"). openssl rand -hex erzeugt nur 0-9a-f und ist damit URL-sicher. Beim JWT- und Webhook-Secret taucht dieses Problem nicht auf – die landen nie in einer URI.

⚠️ Niemals Sample-Werte aus Tutorials oder dieser Anleitung übernehmen

Jeder Generator-Aufruf erzeugt frische Zufallswerte. Wenn du Secrets aus Beispielen oder einer öffentlichen Doku übernimmst, sind sie aus Sicherheits­sicht wertlos – sie sind ja öffentlich. Generiere immer eigene.

5. .env-Datei erstellen

Komodo nutzt eine .env-Datei zur Konfiguration. Lege sie an:

nano /srv/docker/stacks/komodo/.env

Inhalt (Platzhalter <...> durch deine echten Werte ersetzen – inklusive der eben generierten Secrets und deiner Tailscale-IP):

####################################
# 🦎 KOMODO - HOMELAB CONFIG       #
####################################

# Image-Version
COMPOSE_KOMODO_IMAGE_TAG=2

# Wo Komodo später erreichbar ist (für Webhook-URLs, Anzeige)
KOMODO_HOST=http://<TAILSCALE-IP>:9120
KOMODO_TITLE=Komodo

# Port-Bindung: Komodo nur über Tailscale erreichbar
TAILSCALE_IP=<TAILSCALE-IP>

# Postgres / FerretDB Zugangsdaten
KOMODO_DATABASE_USERNAME=komodo
KOMODO_DATABASE_PASSWORD=<DB-PASSWORT-AUS-OPENSSL-HEX>

# Krypto-Secrets
KOMODO_JWT_SECRET=<JWT-SECRET-AUS-OPENSSL>
KOMODO_WEBHOOK_SECRET=<WEBHOOK-SECRET-AUS-OPENSSL>

# Auth-Verhalten
KOMODO_LOCAL_AUTH=true
KOMODO_DISABLE_USER_REGISTRATION=false
KOMODO_DISABLE_NON_ADMIN_CREATE=false
KOMODO_TRANSPARENT_MODE=false
KOMODO_JWT_TTL="1-day"

# Monitoring-Intervalle
KOMODO_MONITORING_INTERVAL="15-sec"
KOMODO_RESOURCE_POLL_INTERVAL="5-min"

# OAuth/OIDC aus (kommt frühestens mit Authentik im Bonus-Artikel)
KOMODO_OIDC_ENABLED=false
KOMODO_GITHUB_OAUTH_ENABLED=false
KOMODO_GOOGLE_OAUTH_ENABLED=false

# Lokalen Server automatisch beim ersten Start anlegen
KOMODO_FIRST_SERVER_NAME=homelab

# PKI-Schlüsselaustausch: Core und Periphery lesen sich gegenseitig
# automatisch aus dem geteilten keys-Volume
KOMODO_PERIPHERY_PUBLIC_KEY=file:/config/keys/periphery.pub

# Periphery
PERIPHERY_CORE_ADDRESS=ws://core:9120
PERIPHERY_CONNECT_AS=${KOMODO_FIRST_SERVER_NAME}
PERIPHERY_CORE_PUBLIC_KEYS=file:/config/keys/core.pub
PERIPHERY_ROOT_DIRECTORY=/etc/komodo
PERIPHERY_STACK_DIR=/srv/docker/stacks

# Zeitzone
TZ=Europe/Berlin

Wichtig: KOMODO_DISABLE_USER_REGISTRATION steht jetzt auf false, damit du gleich den Admin-Account anlegen kannst. Sobald das erledigt ist, setzen wir die Variable auf true und deployen neu – damit niemand sonst einen Account anlegen kann.

Wie die Authentifizierung zwischen Core und Periphery funktioniert: Beide Container teilen sich ein gemeinsames Docker-Volume namens keys. Beim ersten Start erzeugt Core dort sein Schlüsselpaar (core.key + core.pub), Periphery seins (periphery.key + periphery.pub). Die beiden Public-Key-Pfade tragen wir oben in der .env ein. Damit weiß Core, welchem Periphery er vertrauen darf, und umgekehrt. Kein manueller Schlüsseltausch, kein Onboarding-Key. Der KOMODO_FIRST_SERVER_NAME legt beim ersten Start automatisch einen Server-Eintrag in der UI an, und Periphery verbindet sich über PERIPHERY_CONNECT_AS genau mit diesem.

Speichern mit Ctrl+X, Y, Enter.

Zugriffsrechte einschränken (die Datei enthält jetzt Klartext-Passwörter):

chmod 600 /srv/docker/stacks/komodo/.env

6. compose.yaml erstellen

nano /srv/docker/stacks/komodo/compose.yaml

Inhalt:

name: komodo

services:
  postgres:
    image: ghcr.io/ferretdb/postgres-documentdb
    container_name: komodo-postgres
    restart: unless-stopped
    labels:
      komodo.skip: ""
    environment:
      POSTGRES_USER: ${KOMODO_DATABASE_USERNAME}
      POSTGRES_PASSWORD: ${KOMODO_DATABASE_PASSWORD}
      POSTGRES_DB: postgres
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - komodo_internal

  ferretdb:
    image: ghcr.io/ferretdb/ferretdb
    container_name: komodo-ferretdb
    restart: unless-stopped
    labels:
      komodo.skip: ""
    environment:
      FERRETDB_POSTGRESQL_URL: postgres://${KOMODO_DATABASE_USERNAME}:${KOMODO_DATABASE_PASSWORD}@postgres:5432/postgres
    depends_on:
      - postgres
    volumes:
      - ferretdb-state:/state
    networks:
      - komodo_internal

  core:
    image: ghcr.io/moghtech/komodo-core:${COMPOSE_KOMODO_IMAGE_TAG}
    container_name: komodo-core
    init: true
    restart: unless-stopped
    labels:
      komodo.skip: ""
    env_file: .env
    environment:
      KOMODO_DATABASE_ADDRESS: ferretdb:27017
    ports:
      - "${TAILSCALE_IP}:9120:9120"
    volumes:
      - keys:/config/keys
    depends_on:
      - ferretdb
    networks:
      - komodo_internal
      - homelab_net

  periphery:
    image: ghcr.io/moghtech/komodo-periphery:${COMPOSE_KOMODO_IMAGE_TAG}
    container_name: komodo-periphery
    init: true
    restart: unless-stopped
    labels:
      komodo.skip: ""
    env_file: .env
    volumes:
      - keys:/config/keys
      - /var/run/docker.sock:/var/run/docker.sock
      - /proc:/proc
      - /etc/komodo:/etc/komodo
      - /srv/docker/stacks:/srv/docker/stacks
    depends_on:
      - core
    networks:
      - komodo_internal

volumes:
  postgres-data:
  ferretdb-state:
  keys:

networks:
  komodo_internal:
  homelab_net:
    external: true

Speichern und schließen.

Was passiert hier?

Block Erklärung
name: komodo Expliziter Projektname (wie in Artikel 03 etabliert).
komodo.skip: "" Markiert alle Container, damit Komodo seinen eigenen Stack nicht stoppt oder neu deployt.
init: true Aktiviert PID 1 als Init-Prozess, sonst sammeln sich Zombie-Prozesse an.
postgres mit DocumentDB-Image Postgres + DocumentDB-Extension (von Microsoft), Basis für FerretDB.
keys-Volume Speichert die automatisch generierten Ed25519-Schlüsselpaare von Core und Periphery. Persistenz ist wichtig – sonst muss bei jedem Restart neu onboarded werden.
core mit ports: "${TAILSCALE_IP}:9120:9120" Port 9120 wird ausschließlich auf das Tailscale-Interface gebunden. Über die öffentliche IP des VPS ist nichts erreichbar.
core an beiden Netzen An komodo_internal für DB-Zugriff, an homelab_net für Container in anderen Stacks.
periphery ohne ports: Periphery ist nur intern erreichbar – Core spricht es über den Container-Namen an.
Docker-Socket-Mount bei Periphery Damit Periphery docker-Befehle auf dem Host ausführen kann.
/etc/komodo als Bind-Mount Periphery-Root-Verzeichnis. Wichtig: Pfad innen und außen identisch – sonst übergibt Periphery dem Host-Docker beim Stack-Deploy Pfade, die der Host nicht versteht.
/srv/docker/stacks als Bind-Mount + PERIPHERY_STACK_DIR Damit Komodo die UI-Defined Stacks unter /srv/docker/stacks/<name>/ ablegt – konsistent mit dem Muster aus Artikel 03.

7. Stack starten

Bevor wir starten, einmalig das Periphery-Datenverzeichnis vorbereiten – sonst wird es von Docker als root-owned angelegt:

sudo mkdir -p /etc/komodo

Dann der eigentliche Start:

cd /srv/docker/stacks/komodo
docker compose up -d

Beim ersten Start:

  • Postgres initialisiert die DocumentDB-Extension (kann 30–60 Sekunden dauern)
  • FerretDB verbindet sich mit Postgres
  • Core kommt online und generiert sein Schlüsselpaar im keys-Volume
  • Periphery startet – wartet aber auf einen Onboarding-Key, bevor es sich mit Core verbindet

Status prüfen:

docker compose ps

Erwartung: Vier Container, alle Up:

NAME               STATUS                   PORTS
komodo-core        Up 30 seconds            100.x.x.x:9120->9120/tcp
komodo-ferretdb    Up 35 seconds
komodo-periphery   Up 30 seconds
komodo-postgres    Up 1 minute

Wichtig: Bei komodo-core steht die Tailscale-IP vor :9120 – nicht 0.0.0.0:9120. Genau so soll es sein.

Falls etwas nicht startet:

docker compose logs postgres
docker compose logs ferretdb
docker compose logs core
docker compose logs periphery

Häufigste Ursache: Tippfehler in der .env-Datei oder ein leeres Feld wo ein Secret stehen sollte.

Wenn komodo-core in einer Restart-Schleife hängt (Restarting in docker compose ps) und das Log password must be URL encoded zeigt: Dein DB-Passwort enthält Sonderzeichen. Du hast es vermutlich mit -base64 statt -hex generiert. Lösung: ein neues Passwort mit openssl rand -hex 24 erzeugen, in der .env eintragen – und weil Postgres das alte Passwort bereits im Volume gespeichert hat, das Volume neu aufsetzen:

docker compose down -v
docker compose up -d

Das ist verlustfrei, solange Komodo noch nie vollständig lief – es sind ja noch keine Daten drin. Achtung: down -v löscht alle Volumes des Stacks, auch das keys-Volume. Das ist hier okay, weil Komodo die Schlüssel beim nächsten Start neu generiert.

8. Erstaufruf der Web-UI

Öffne im Browser:

http://<TAILSCALE-IP-DES-SERVERS>:9120

Falls du in Artikel 05 MagicDNS aktiviert hast, geht auch:

http://homelab:9120

(oder wie du dein Server-Gerät in Tailscale benannt hast).

Hinweis zur Browser-Warnung „Nicht sicher": Du sprichst Komodo über http:// an, nicht über https:// – deshalb meldet dein Browser „keine Zertifikatsabsicherung". Das ist hier kein Problem: Die Verbindung läuft durch den Tailscale-Tunnel und ist auf WireGuard-Ebene Ende-zu-Ende verschlüsselt. Caddy + HTTPS brauchen wir in den nächsten Artikeln nur für Dienste, die übers offene Internet erreichbar sein sollen.

Falls die Seite nicht lädt, prüfe in dieser Reihenfolge:

  1. Bist du im Tailscale-Netz aktiv? tailscale status auf dem lokalen Rechner sollte den Server zeigen.
  2. docker compose ps auf dem Server – läuft komodo-core?
  3. Stimmt die Tailscale-IP in der .env? tailscale ip -4 auf dem Server gibt die korrekte Adresse aus.

Admin-Account anlegen

Beim ersten Aufruf erscheint ein Login-/Sign-Up-Formular. Ein bisschen verwirrend, weil es keinen klar getrennten „Registrieren"-Button gibt:

  1. Username eintragen (z. B. martin)
  2. Passwort vergeben (mindestens 12 Zeichen, idealerweise aus deinem Passwort-Manager)
  3. Auf Sign Up klicken

Der erste Account wird automatisch zum „Super Admin" mit allen Rechten. Du bist sofort eingeloggt.

Wenn nach dem Sign-Up nur „Komodo Log in" ohne Felder erscheint: Die UI cacht Assets aggressiv, und nach dem allerersten Sign-Up landet man manchmal auf einer halb-gerenderten Login-Seite. Strg + Shift + R (Hard Reload, leert den Cache für diese Seite) löst das in den allermeisten Fällen. Alternativ: Inkognito-Tab öffnen und mit den gerade angelegten Daten einloggen.

Registrierung schließen

Jetzt – sofort nach dem ersten Login – die Registrierung wieder zumachen. In der .env-Datei:

nano /srv/docker/stacks/komodo/.env

Diese Zeile ändern:

KOMODO_DISABLE_USER_REGISTRATION=true

Speichern. Stack neu starten:

cd /srv/docker/stacks/komodo
docker compose up -d

(Nur die geänderten Container werden neu erstellt – Postgres und FerretDB bleiben unverändert laufen.)

Danach kurz testen: Im Browser einen Inkognito-Tab öffnen, Komodo aufrufen – jetzt sollte nur noch das Login-Formular angezeigt werden, keine Sign-Up-Möglichkeit mehr.

9. Server in der UI prüfen

Anders als du es vielleicht aus älterer Komodo-Doku im Netz liest, musst du in diesem Setup nichts tun, um Periphery mit Core zu verbinden: Core und Periphery haben sich beim ersten Start ihre Schlüsselpaare ins gemeinsame keys-Volume gelegt, und über die .env-Variablen wissen beide, wem sie vertrauen. Zusätzlich hat KOMODO_FIRST_SERVER_NAME=homelab Core dazu veranlasst, beim ersten Start einen Server mit genau diesem Namen anzulegen.

In der UI links auf das Resources-Icon und dann auf Servers. Du solltest einen Eintrag sehen:

  • Name: homelab (oder wie du KOMODO_FIRST_SERVER_NAME gesetzt hast)
  • Status: grün, OK

Klick den Server an – im Hauptbereich siehst du Live-Daten: CPU, RAM, Disk, laufende Container. Wenn das angezeigt wird, ist die Core-Periphery-Verbindung sauber.

Falls der Server rot ist („ServerUnreachable") oder gar nicht erscheint:

docker compose logs core | grep -iE "periphery|key"
docker compose logs periphery | grep -iE "core|key"

Häufigste Ursachen:

  • Das keys-Volume fehlt im Compose oder ist nicht in beide Container gemountet → die Schlüssel werden nicht geteilt.
  • PERIPHERY_CORE_PUBLIC_KEYS oder KOMODO_PERIPHERY_PUBLIC_KEY zeigen auf einen falschen Pfad → mit dem Pfad /config/keys/... aus Sektion 5 abgleichen.
  • PERIPHERY_CONNECT_AS weicht von KOMODO_FIRST_SERVER_NAME ab → beide müssen identisch sein, damit Periphery sich am angelegten Server-Eintrag andockt.

Optional: Server umbenennen

Wenn dir der Default-Name nicht gefällt, klick rechts oben auf den Server in der Detail-Ansicht auf das Edit-Symbol → Name ändern → Speichern. Beachte: Wenn du den Namen änderst, musst du in der .env auch PERIPHERY_CONNECT_AS anpassen und Periphery neu starten – sonst sucht Periphery beim nächsten Connect den alten Namen.

10. Workflow ab jetzt: Stacks über die UI

Ab diesem Punkt installierst du neue Docker-Stacks nicht mehr per SSH und docker compose up -d. Du legst sie über die Komodo-UI an, pflegst die compose.yaml direkt im Browser-Editor und deployst per Mausklick.

Eine wichtige Ausnahme: der Komodo-Stack selbst. Dieser bleibt manuell – aus offensichtlichem Grund: Komodo kann sich nicht über sich selbst deployen. Wenn du jemals die Komodo-Konfiguration änderst, machst du das per SSH, mit nano und docker compose up -d. Dafür ist das komodo.skip-Label gesetzt – Komodo lässt seinen eigenen Stack in Ruhe.

Wie das in der UI konkret aussieht, machen wir gleich an einem Test-Stack durch. Welche Möglichkeiten du danach noch hast (Stacks aus Git-Repos, Auto-Updates, Alerts), folgt im Anschluss.

11. Test-Deployment: whoami über die Komodo-UI

Bevor du mit Caddy im nächsten Artikel den ersten echten produktiven Stack baust, fahren wir einmal trocken: ein winziger Test-Stack, der Komodos UI-Workflow zeigt.

In der UI:

  1. Links auf Stacks → oben rechts + New Stack
  2. Name: test-whoami
  3. Server: Den gerade verbundenen homelab auswählen
  4. Stack Type: „UI Defined"
  5. Im Compose-Editor folgendes einfügen:
name: test-whoami

services:
  whoami:
    image: traefik/whoami
    container_name: test-whoami
    restart: unless-stopped
    networks:
      - homelab_net

networks:
  homelab_net:
    external: true
  1. Save klicken – Komodo legt damit die Stack-Definition an (noch nicht deployt).
  2. Anschließend Deploy und im Bestätigungsdialog Confirm.

Was du jetzt siehst:

  • Komodo schreibt die compose.yaml auf den Host (unter /srv/docker/stacks/test-whoami/)
  • Periphery führt docker compose up -d im Hintergrund aus
  • Der Container test-whoami erscheint in der Container-Liste mit Status „Running"
  • Logs des Containers sind ein Klick entfernt

Aufräumen – wir brauchen den Stack jetzt nicht:

  1. Im Stack-Overview auf Destroy klicken (stoppt und entfernt die Container)
  2. Anschließend auf Delete Stack (entfernt den Stack-Eintrag aus Komodo und das Verzeichnis vom Host)

Du hast den vollen Komodo-Workflow gerade einmal end-to-end gesehen: Stack anlegen → editieren → deployen → kontrollieren → wegräumen. Genau so läuft das ab dem nächsten Artikel mit jedem neuen Stack.

12. Komodo im Alltag

Den Installations-Teil hast du jetzt durch. Bevor du ab Artikel 07 die ersten echten Stacks baust, lohnt sich ein Überblick über die Funktionen, die du danach nutzen wirst. Komodo ist nicht nur ein Klick-Ersatz für docker compose up – es bringt ein paar Konzepte mit, die im Alltag den Unterschied machen.

Stack-Typen: drei Wege zum Compose-File

In Komodo gibt es drei Wege, eine compose.yaml zu pflegen. Welcher Weg sich wann lohnt:

UI Defined (unsere Standard-Wahl)

Du tippst compose.yaml und .env direkt im Komodo-Editor. Komodo schreibt die Dateien beim Deploy auf den Host (unter /srv/docker/stacks/<name>/compose.yaml). Vorteil: Compose und Environment liegen zentral in Komodo, kein SSH zum Editieren nötig. Nachteil: keine native Versionierung – wenn du ein älteres Compose-File brauchst, gibt es in Komodo eine begrenzte Edit-History, aber keinen vollwertigen Diff.

Files on Host

Komodo liest eine compose.yaml, die schon manuell auf dem Server liegt – die Datei selbst bleibt unter deiner Kontrolle. Sinnvoll, wenn du einen bestehenden Stack in Komodo „übernehmen" willst, ohne ihn neu anzulegen.

Git Repo

Komodo klont ein Git-Repository auf den Host und nutzt die compose.yaml daraus. Änderungen läufst du per Commit – nach git push zieht Komodo die neue Version. Damit hast du echte Versionierung, Rollbacks per Checkout, optional automatische Deploys via Webhook. Das ist die Endausbaustufe – im späteren Bonus-Artikel zur GitOps-Pipeline gehen wir das durch.

Empfehlung für diese Serie: UI Defined für alle Stacks. Du gewinnst alle Komodo-Vorteile und kannst später jederzeit auf Git Repo umstellen.

Datei-Namens-Hinweis: Komodo schreibt UI-Defined Stacks als compose.yaml (Compose-Spec-Standard). Den Bootstrap-Stack für Komodo selbst legst du manuell an – dort nutzen wir compose.yml, weil Docker beide Schreibweisen akzeptiert und du die Datei selbst kontrollierst.

Environment-Variablen: zentral pro Stack

Jeder Stack in Komodo hat zwei separate Editoren: einen für die compose.yaml, einen für die .env. Du pflegst Secrets, Domain-Namen, Versions-Tags also nicht in der Compose-Datei selbst, sondern in der zugehörigen .env. Das ist exakt dasselbe Pattern, das wir in Artikel 03 für manuelle Stacks etabliert haben – nur dass du beide Dateien jetzt im Browser editierst statt per SSH.

Praktischer Nebeneffekt: Wenn du einen Stack klonst (in Komodo verfügbar als „Copy Stack"), übernimmt Komodo die compose.yaml, aber nicht automatisch die .env. So vermeidest du, dass Secrets ungewollt in mehreren Stacks landen.

Updates erkennen und einspielen

Komodo prüft im Hintergrund regelmäßig (Default: alle 5 Minuten, in der .env als KOMODO_RESOURCE_POLL_INTERVAL einstellbar), ob für die in deinen Stacks verwendeten Images eine neuere Version verfügbar ist. Sobald ein Update gefunden wird, erscheint in der Stack-Übersicht ein farbiger Hinweis.

Pro Stack hast du zwei Schalter unter Auto Update:

  • Notify on Update: Komodo meldet dir nur, dass ein Update da ist. Du entscheidest manuell, wann du deployst.
  • Auto Update: Komodo zieht das neue Image und deployt den Stack automatisch.

Ehrliche Einschätzung: Auto-Update ist verlockend, aber für die meisten Self-Hosting-Apps die schlechtere Wahl. Major-Updates (z. B. Postgres 17 → 18, oder Immich von einer Breaking-Release zur nächsten) können Datenbanken migrieren, Konfigurationen ändern oder schlicht inkompatibel werden. Wenn das mitten in der Nacht passiert und am Morgen geht der Stack nicht mehr hoch, hast du keine Vorwarnung.

Empfehlung: Notify on Update aktivieren, Auto-Update meiden. Bei kritischen Apps (Vaultwarden, Immich) sowieso. Bei wirklich kleinen, unkritischen Stacks (z. B. ein simpler Tool-Container) kannst du Auto-Update einschalten, wenn du das Risiko kennst.

Alerts

Komodo kann dich aktiv benachrichtigen – nicht nur passiv in der UI anzeigen. Konfiguriert wird das unter Alerters im Settings-Bereich. Typische Auslöser:

  • Container down (z. B. nach OOM-Kill)
  • Server unreachable (Periphery antwortet nicht mehr)
  • Stack-Update verfügbar
  • Ressourcen-Schwellwerte überschritten (CPU, RAM, Disk)

Als Empfänger eignen sich für diese Serie zwei Endpunkte besonders:

  • E-Mail – sobald du in Artikel 08 (Mail-Versand) den SMTP-Versand eingerichtet hast, kannst du Komodo dort als Sender konfigurieren. Praktisch für ruhige, weniger zeitkritische Meldungen.
  • ntfy – ein leichtgewichtiger Push-Service, der selbst self-hostbar ist und Push-Nachrichten direkt aufs Handy schickt. Gute Wahl, wenn du sofort wissen willst, dass etwas down ist.

Welcher Alerter wann sinnvoll ist, vertiefen wir in einem späteren Artikel zum Monitoring (Phase 4). Für jetzt: Du weißt, dass Komodo das kann – und musst es nicht sofort einrichten.

2FA für den Admin-Account

Komodo bringt eingebautes TOTP-2FA für den Username/Passwort-Login mit. Du findest es in deinem User-Profil oben rechts → AccountEnable 2FA. App auf dem Handy (Aegis, 2FAS, Authy), QR-Code scannen, Code eingeben, fertig. Bei einem reinen VPN-only-Tool wie Komodo ist das Komfort gegen geringes Restrisiko – aber kostenlos zu haben, also sinnvoll mitzunehmen.

Was Komodo nicht ist

Damit du dir keine falschen Erwartungen aufbaust: Komodo ist eine Verwaltungs-Oberfläche, kein Reverse Proxy, kein Backup-Tool und kein Identity Provider. Domains, HTTPS, Authentifizierung und Backups bleiben jeweils eigene Bausteine – die kommen in den nächsten Artikeln (Caddy, Authelia) und in Phase 4 (Backup).

Und jetzt?

Du hast eine Web-Oberfläche für Docker, die nur über dein VPN erreichbar ist. Neue Stacks legst du ab jetzt direkt im Browser an. SSH brauchst du fast nur noch für drei Dinge: System-Updates, Komodo-Konfigurationsänderungen, und gelegentliches Debugging.

Bisher ist allerdings noch keiner deiner Dienste öffentlich erreichbar – und das ist auch richtig so. Komodo hat im öffentlichen Internet nichts verloren. Für die Apps, die später öffentlich sein sollen (Vaultwarden, Immich, Ghost), brauchen wir einen Reverse Proxy mit automatischem HTTPS. Genau das macht der nächste Artikel.

Vorausschauend gedacht: Reihe 2 (NAS Edition)

Wenn du später ein NAS oder einen zusätzlichen ThinClient/Raspi dazunimmst, kannst du Komodo Core auf einem Gerät zentral lassen und auf dem zweiten Gerät nur Periphery installieren. Wie das aufgesetzt wird, zeigt die NAS Edition.

👉 Nächster Artikel: 07. Caddy – Reverse Proxy mit automatischem HTTPS (und vorbereitet für CrowdSec)