Files
bf-infra/mcp/komodo/MIGRATION.md

8.3 KiB
Raw Permalink Blame History

Portainer → Komodo Migration

Entscheidung (2026-06-15): Portainer CE 2.40.0 wird durch Komodo ersetzt.

  • Portainer-MCP braucht 2.41/2.42 (kein Match für 2.40) → Blocker für portainer-mcp
  • Komodo hat nativen MCP-Server (Samik081/mcp-komodo, selber Autor wie pve-mcp)
  • Komodo = modernes Portainer-Äquivalent mit Git-Deploy, Prozeduren, Monitoring

Architektur-Übersicht

Claude Code (Mac)
    └── komodo-mcp (.176, SSE) ── Komodo Core (.126:9120) ──┬── Periphery auf .126 (self)
                                      └── MongoDB              ├── Periphery auf .10  (DS923)
                                                               ├── Periphery auf .7   (odroid)
                                                               ├── Periphery auf .167 (macmini)
                                                               └── Periphery auf nas-fm

Komodo besteht aus zwei Teilen:

  • Core — Web-UI + API + Orchestrierung (läuft auf .126, Port 9120)
  • Periphery — leichter Agent auf jedem verwalteten Host (managed Docker direkt lokal)
  • mcp-komodo — MCP-Adapter zwischen Claude Code und Komodo-API

Phase 0 — Vorbereitung: Portainer-Inventar exportieren

Bevor Portainer abgeschaltet wird, alle Stacks + Endpunkte dokumentieren:

# API-Token aus mcp/portainer/.env
source mcp/portainer/.env

# Endpunkte (= die 5 Hosts)
curl -sk "$PORTAINER_URL/api/endpoints" \
  -H "X-API-Key: $PORTAINER_API_KEY" | jq '.[] | {id, name, URL}'

# Alle Stacks (pro Endpoint)
curl -sk "$PORTAINER_URL/api/stacks" \
  -H "X-API-Key: $PORTAINER_API_KEY" | jq '.[] | {Id, Name, EndpointId}'

# Stack-Compose je Stack (Beispiel Stack-ID 1):
curl -sk "$PORTAINER_URL/api/stacks/1/file" \
  -H "X-API-Key: $PORTAINER_API_KEY" | jq -r '.StackFileContent'

Bekannte Portainer-Endpunkte:

endpointId Host IP
(lokal) pve-LXC 10.40.41.126
14 nas-bf (DS923+) 10.40.41.10
? odroid-m1 10.40.41.7
? macmini 10.40.41.167
? nas-fm (DS415+) (IP prüfen)

Phase 1 — Komodo Core deployen (auf pve-LXC, .126)

Komodo Core ersetzt Portainer auf demselben Host. Portainer läuft während der Migration parallel (Port 9443 ≠ Port 9120). Erst nach Abschluss von Phase 4 wird Portainer gestoppt.

1a — Secrets anlegen

# Datei: mcp/komodo/.env (gitignored via mcp/.gitignore)
KOMODO_HOST=http://10.40.41.126:9120
KOMODO_DB_PASSWORD=<generate: openssl rand -hex 24>
KOMODO_JWT_SECRET=<generate: openssl rand -hex 32>
KOMODO_PASSKEY=<generate: openssl rand -hex 16>
# Nach Core-Start befüllen:
# KOMODO_API_KEY=...
# KOMODO_API_SECRET=...

1b — Docker Compose für Core

Datei: mcp/komodo/core-compose.yml (liegt neben dieser Datei)

Deployment via Portainer endpointId=lokal (.126 selbst) oder direkt per SSH:

ssh <pve-lxc>
mkdir -p /opt/komodo && cd /opt/komodo
# compose + .env hochladen / eintragen
docker compose -f core-compose.yml up -d

UI erreichbar: http://10.40.41.126:9120

1c — Initialer Admin-User

Beim ersten Öffnen des UI → Admin-Account anlegen → danach: Settings → API Keys → neues Key-Paar generieren → in .env eintragen.


Phase 2 — Periphery-Agent auf den 5 Hosts

Komodo Core managt seinen eigenen Docker-Host (pve-LXC) nativ über localhost. Für alle weiteren Hosts muss ein Periphery-Agent installiert werden.

Methode A — Docker Container (bevorzugt, wo Docker schon läuft)

# periphery.compose.yml (auf dem jeweiligen Host ablegen, z.B. /opt/komodo/)
services:
  periphery:
    image: ghcr.io/moghtech/komodo-periphery:latest
    restart: unless-stopped
    network_mode: host          # muss direkt erreichbar sein
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/komodo:/etc/komodo # periphery root (compose-Dateien landen hier)
    environment:
      PERIPHERY_ALLOWED_IPS: 10.40.41.126   # nur Core darf reden
      PERIPHERY_PORT: 8120

Methode B — systemd-Binary (für Hosts ohne Docker oder wenn Methode A nicht passt)

# Einzeiler vom Komodo-Onboarding-Wizard (im UI generiert):
curl -sSL https://raw.githubusercontent.com/moghtech/komodo/main/scripts/setup-periphery.sh \
  | bash -s -- --core-addr http://10.40.41.126:9120 \
               --name <hostname> \
               --passkey <KOMODO_PASSKEY>

Host-Matrix

Host IP Periphery-Methode Besonderheit
pve-LXC 10.40.41.126 lokal (Core selbst) kein Agent nötig — Core = erster Server
DS923 10.40.41.10 Docker Container Portainer endpointId=14 → Bootstrap via Portainer API
odroid-m1 10.40.41.7 Docker Container IP prüfen; Docker vorhanden
macmini 10.40.41.167 Docker Container o. systemd ssh macmini → compose up
nas-fm (IP prüfen) Docker Container IP + SSH-Zugang vorher klären

DS923-Bootstrap (einmalig, vor Phase 3):

source mcp/portainer/.env
# periphery.compose.yml via Portainer API auf DS923 deployen:
curl -sk -X POST "$PORTAINER_URL/api/stacks/create/standalone/string?endpointId=14" \
  -H "X-API-Key: $PORTAINER_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"name\":\"komodo-periphery\",\"stackFileContent\":\"$(cat mcp/komodo/periphery.compose.yml | jq -Rs .)\"}"

Phase 3 — Stacks in Komodo eintragen

Nach Phase 1+2: alle vorhandenen Stacks aus Phase 0 in Komodo nachpflegen.

Komodo Stack-Konzept:

  • UI → Stacks → + New Stack
  • Compose-Inhalt: direkt im UI editieren oder aus Git-Repo (Webhook-Auto-Deploy)
  • Komodo schreibt die Compose-Datei zur Deploy-Zeit auf den Host ins Periphery-Root

Bestehende Stacks (nach Portainer-Export bekannt):

  • omada-controller (DS923, .175)
  • omada-mcp (DS923, .174) — noch nicht deployed, wird direkt über Komodo erstdeployed
  • pve-mcp (DS923, .173) — laufend, nahtlos umziehen

Empfehlung: Stacks zunächst in Komodo anlegen (disabled), dann umschalten, Portainer-Stack deaktivieren (nicht löschen) → erst nach Verifikation aus Portainer entfernen.


Phase 4 — Portainer abschalten

Wenn alle Stacks auf Komodo laufen und verifiziert:

# Auf pve-LXC:
docker stop portainer && docker rm portainer
# docker volume portainer_data → optional behalten als Backup

mcp/INVENTORY.md aktualisieren: portainer-mcp-Zeile auf retired setzen.


Phase 5 — komodo-mcp deployen + Claude Code eintragen

Image: ghcr.io/samik081/mcp-komodo:latest (selber Autor wie pve-mcp ✓) Macvlan-IP: 10.40.41.176 (folgt .173/.174/.175)

5a — Komodo API-Key erzeugen

Komodo UI → Settings → API Keys → New Key → Key + Secret in mcp/komodo/.env als KOMODO_API_KEY + KOMODO_API_SECRET

5b — compose.yml

Datei: mcp/komodo/komodo-mcp-compose.yml (liegt neben dieser Datei)

Stack via Komodo selbst deployen (Stack auf DS923, macvlan .176):

  • Komodo UI → Stacks → New Stack → Ziel: DS923 (Periphery da)

5c — Claude Code eintragen

# ~/.claude/settings.json ergänzen (neben pve-mcp/.173):
# "komodo-mcp": {
#   "type": "sse",
#   "url": "http://10.40.41.176:3000/sse"
# }

Oder via CLI:

claude mcp add --transport sse komodo-mcp http://10.40.41.176:3000/sse -s user

Verfügbar nach Claude Code Neustart. Tools prüfen:

/mcp → komodo-mcp → 40 Tools sichtbar

Abhängigkeiten & Reihenfolge

Phase 0 (Export)
    ↓
Phase 1 (Core auf .126)
    ↓
Phase 2 (Periphery auf .10, .7, .167, nas-fm)
    ↓
Phase 3 (Stacks umziehen)
    ↓
Phase 4 (Portainer stop)
    ↓
Phase 5 (komodo-mcp .176 + Claude Code)

Phasen 0–2 sind unabhängig von laufenden Stacks und können ohne Downtime vorbereitet werden. Phasen 3–5 erfordern kurze Downtime je Stack beim Umschalten (Sekunden).


Referenzen