8.3 KiB
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
- Komodo Docs
- Core Setup
- Connect Servers (Periphery)
- Docker Compose Stacks
- Samik081/mcp-komodo — MCP-Adapter
- MP-Tool/komodo-mcp-server — Alternative (70 Tools, aber kein GHCR-Image)
- moghtech/komodo (GitHub) — Upstream