Portainer 2.40 → 2.42.0 Bump + portainer-mcp projektspezifisch
Portainer-Server (pve LXC 400): 2.40.0 → 2.42.0 via Image-Swap mit Volume-Erhalt.
Pre-Upgrade-Snapshot: docker commit :2.40.0-preupgrade-20260828 (Rollback 7 d
verfügbar) + Settings/Stacks/Endpoints-JSON-Dump (40 KB, 31 Stacks, 4 Endpoints).
Instance-ID + API-Token nach Bump identisch — kein Re-Auth, kein Settings-Verlust.
portainer-mcp: offizielles PyPI-Paket mcp-portainer~=2.42.0 (193 Tools), nur
in bf-infra/opencode.jsonc, via uvx-stdio. Tool-Gate: get_guidance() einmal pro
Session zwingend vor erstem Read. Andere Projekte unberührt.
Korrekturen ggü. Handoff 2026-08-28 README:
- mcp-portainer PyPI bis 2.42.6, Docker-Hub portainer/portainer-ce nur bis 2.42.0
(unterschiedliche Versionierungspfade).
- mcp/portainer/README.md ist auf 2.42.6 formuliert und sollte nachgezogen werden.
Bestand: mcp/INVENTORY.md portainer-mcp ⛔→🟢 + Header MCP-WARP-Direktive ergänzt.
.mcp.json (war getrackt aus Commit 3426366) entfernt: opencode nutzt opencode.jsonc,
nicht .mcp.json — Claude-Code-Konvention hier irrelevant.
This commit is contained in:
146
docs/handoff-20260828-portainer-bump-und-mcp.md
Normal file
146
docs/handoff-20260828-portainer-bump-und-mcp.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# Handoff 2026-08-28 — Portainer 2.40 → 2.42.0 Bump + portainer-mcp (uvx, projektebene)
|
||||
|
||||
> **Vorgeschichte:** Direktive vom 2026-08-28 (User): "wenn du künftig das ganze containermanagement machst,
|
||||
> brauchst du einen MCP für Portainer". Vorgänger-Direktive vom 2026-08-28 selbst (gestern Session):
|
||||
> ⛔ NICHT installieren. → **revidiert** in derselben Diskussion, weil die wiederholten curl-Aufrufe
|
||||
> in der Inventur-Session gezeigt haben, dass ein MCP-Layer hier operativ hilft.
|
||||
|
||||
## Was diese Session geliefert hat
|
||||
|
||||
### 1. Portainer-Server 2.40.0 → 2.42.0 (auf pve LXC 400, Container `portainer`)
|
||||
|
||||
**Vorab-Korrektur (war falsch im Handoff 2026-08-28):** README schrieb 2.42.6 als Ziel,
|
||||
PyPI hat ein 2.42.6-Wheel, aber Docker-Hub hat **nur 2.42.0** als letzten 2.42.x-Tag
|
||||
für `portainer/portainer-ce`. Bump-Ziel deshalb **2.42.0** statt 2.42.6.
|
||||
|
||||
**Ablauf:**
|
||||
1. Pre-Upgrade-Snapshot:
|
||||
- `docker commit portainer portainer/portainer-ce:2.40.0-preupgrade-20260828` (186 MB)
|
||||
- Settings+Endpoints+Stacks-JSON-Dump (40 KB, 31 Stacks, 4 Endpoints)
|
||||
- Volume `/var/lib/docker/volumes/portainer_data/_data` ist **persistent**, bleibt
|
||||
beim Image-Swap unangetastet.
|
||||
- Runflags aus `docker inspect` ins Runbook übernommen.
|
||||
2. `docker pull portainer/portainer-ce:2.42.0`
|
||||
3. `docker stop portainer && docker rm portainer && docker run -d` mit identischen Flags.
|
||||
4. Post-Upgrade-Verifikation:
|
||||
- HTTP 200 auf `/`, TLS self-signed OK
|
||||
- `api/status` → `Version: 2.42.0`, **gleiche InstanceID** wie vorher
|
||||
- **API-Token weiter gültig** (`api/settings` → 200), kein Re-Auth
|
||||
- Alle 4 Endpoints + 31 Stacks abrufbar
|
||||
|
||||
**Sicherheitsabstände für den Bump:**
|
||||
- Container läuft, alle Endpoints erreichbar (status=1)
|
||||
- Edge-Agents auf den 4 Hosts (DS923, macmini, nas-fm, pve) sind **eigene Container**,
|
||||
Portainer-Container-Restart berührt sie nicht.
|
||||
|
||||
### 2. portainer-mcp — installiert als projektspezifischer uvx-stdio
|
||||
|
||||
**Quelle:** `mcp-portainer` von PyPI (offiziell, von Portainer, generiert aus OpenAPI-Spec).
|
||||
Wegen "Match minor to minor"-Policy (PyPI/README) war der Bump **Pflicht**, sonst kein offizieller MCP.
|
||||
|
||||
**Installation:**
|
||||
- `uvx --from "mcp-portainer~=2.42.0" mcp-portainer` — Wheel lokal aufgelöst, 193 Tools
|
||||
- `bf-infra/.mcp.json` (gitignored):
|
||||
```jsonc
|
||||
{
|
||||
"mcpServers": {
|
||||
"portainer": {
|
||||
"command": "uvx",
|
||||
"args": ["--from", "mcp-portainer~=2.42.0", "mcp-portainer"],
|
||||
"env": {
|
||||
"PORTAINER_URL": "https://10.40.20.126:9443",
|
||||
"PORTAINER_API_KEY": "${env:PORTAINER_API_KEY}",
|
||||
"PORTAINER_TLS_VERIFY": "0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
- Token via `~/.secrets/exports.zsh` (`PORTAINER_API_KEY`) — kein Klartext im Repo
|
||||
- **`PORTAINER_TLS_VERIFY=0`** weil self-signed Cert auf pve-LXC
|
||||
- **Nur projektebene**, **kein** Eintrag in `~/.claude.json` oder `~/.config/opencode/opencode.jsonc`
|
||||
- **`.mcp.json` aus Repo entfernt** (`git rm --cached`) — `mcp/INVENTORY.md` zeigt das
|
||||
|
||||
**Tool-Gate:** jeder erste Read in einer Session erfordert `get_guidance()` (vom Server
|
||||
erzwungen). Erst danach funktionieren `EndpointList`, `StackList`, `StackInspect` etc.
|
||||
|
||||
### 3. Abnahme (drei Calls gegen die echte API)
|
||||
|
||||
```
|
||||
EndpointList mit select-Projektion:
|
||||
[ { "Id":2, "Name":"pve", "Type":1, "Status":1 },
|
||||
{ "Id":14, "Name":"nas-bf (ds923+)", "Type":2, "Status":1 },
|
||||
{ "Id":20, "Name":"macmini", "Type":2, "Status":1 },
|
||||
{ "Id":21, "Name":"nas-fm (ds415+)", "Type":2, "Status":1 } ]
|
||||
|
||||
StackList (plattformweit, mit select):
|
||||
31 Stacks (pve=4, DS923=20, macmini=4, nas-fm=3)
|
||||
|
||||
StackInspect(202) mit select:
|
||||
{ "id":202, "name":"pve-mcp", "endpointId":14, "status":1,
|
||||
"entryPoint":"docker-compose.yml", "projectPath":"/data/compose/202" }
|
||||
```
|
||||
|
||||
**MCP ersetzt jetzt:** `curl "$PORTAINER_URL/api/..."` aus Bash. Vorher 4-5 Aufrufe pro
|
||||
Inventur-/Deploy-Schritt; jetzt ein Tool-Call mit `select`-JMESPath-Projektion.
|
||||
|
||||
### 4. Bestands-Update (`mcp/INVENTORY.md`)
|
||||
|
||||
- Zeile `portainer-mcp`: ⛔ → 🟢, mit Stand 2026-08-28, 193 Tools, Tool-Gate vermerkt
|
||||
- Header ergänzt: "MCP-Hosts künftig nur WARP/lokal" (User-Direktive)
|
||||
- `mcp/portainer/README.md`: **überholt** (steht noch auf "Portainer-Bump zuerst" — jetzt erledigt)
|
||||
→ TODO für eigene Session: README auf neuen Stand bringen.
|
||||
|
||||
## Lehren aus dieser Session
|
||||
|
||||
### Versions-Korrektur
|
||||
**PyPI ≠ Docker-Hub für dieselbe Software.** PyPI `mcp-portainer` hatte 2.42.0-2.42.6 als Wheels
|
||||
(alle 6 Patch-Versionen), aber das Docker-Image `portainer/portainer-ce:2.42.x` stoppte
|
||||
bei 2.42.0 — vermutlich weil Portainer die Docker-Patch-Serie anders versioniert. **Vor jedem
|
||||
Versions-Claim den jeweils anderen Pfad gegenprüfen.**
|
||||
|
||||
### Werkzeug-Namen lernen
|
||||
`list_endpoints` war geraten. Tatsächlich heißt das Tool `EndpointList` (PascalCase),
|
||||
und es braucht zwingend `get_guidance()` vor dem ersten Read. **Bei unbekanntem MCP zuerst
|
||||
`tools/list` und ein einzelner Probe-Call, dann den echten Read.** Sonst verschwendet man
|
||||
drei Tool-Calls an Authentifizierungsfehler wie ich es hier gemacht habe.
|
||||
|
||||
### uvx-stdio vs Container-MCP
|
||||
Für ein **einzelnes Projekt** mit Performance-Bedenken ist uvx-stdio klar besser als Container:
|
||||
- kein zusätzlicher Host (DS923-Belastung entfällt)
|
||||
- keine macvlan-IP nötig (kein neuer Port-Range-Konflikt)
|
||||
- Tool-Calls direkt aus dem Claude/opencode-Prozess, kein Round-Trip
|
||||
- **Nachteil:** Token im Memory des Claude-Prozesses lebt so lange wie die Session.
|
||||
Bei Container-Lösung wäre der Token nur im MCP-Container. → Sicherheitsbedenken
|
||||
gegen Performance — die Direktive des Users ist hier explizit "Performance > Security
|
||||
weil LAN-only".
|
||||
|
||||
### `git rm --cached` für gitignored-Configs
|
||||
Eine bereits getrackte Datei (hier `.mcp.json` aus Commit 3426366) wird durch
|
||||
nachträgliches `.gitignore`-Pattern **nicht** ausgegraut — `git rm --cached` ist nötig,
|
||||
sonst bleibt sie im Index. Beim nächsten Commit verschwindet sie sauber.
|
||||
|
||||
## Commit-Plan (für die nächste Session oder als Quick-Commit)
|
||||
|
||||
```
|
||||
git add .gitignore mcp/INVENTORY.md docs/portainer-upgrade-20260828/
|
||||
git commit -m "Portainer 2.40 → 2.42.0 Bump + portainer-mcp (uvx projektebene)
|
||||
|
||||
- Portainer-Server: 2.40.0 → 2.42.0 auf pve LXC 400, Pre-Upgrade-Snapshot
|
||||
(docker commit :2.40.0-preupgrade-20260828 + JSON-Dump 31 Stacks/4 Endpoints)
|
||||
- .mcp.json aus Repo (war aus Commit 3426366 getrackt, jetzt gitignored)
|
||||
- mcp/INVENTORY.md: portainer-mcp ⛔→🟢, Header um MCP-WARP-Direktive ergänzt
|
||||
- docs/portainer-upgrade-20260828/: Rollback-Runbook + Pre-Upgrade-State.json
|
||||
|
||||
Hinweis: PyPI hat mcp-portainer bis 2.42.6, Docker-Hub nur bis 2.42.0 —
|
||||
README im mcp/portainer/ ist auf 2.42.6 formuliert und sollte angepasst werden.
|
||||
```
|
||||
|
||||
## TODO (offene Punkte, NICHT Teil dieser Session)
|
||||
|
||||
1. **`mcp/portainer/README.md`** ist überholt (steht noch auf 2.42.6-Bump, jetzt erledigt).
|
||||
Eigene 5-Minuten-Session, README auf den neuen Stand bringen.
|
||||
2. **Cleanup nach 7 Tagen Bump-Stabilität:** `docker rmi portainer/portainer-ce:2.40.0-preupgrade-20260828`
|
||||
3. **Shelly-mcp-Deployment** (das war Session B vor dem Portainer-Thema): shelly-mcp-Image ist gebaut,
|
||||
Stack-YML liegt auf DS923, Stack-Deploy steht aus. **Sofort zurück zu Session B**, weil die
|
||||
`.mcp.json` jetzt **auch** das shelly-mcp-Deployment erleichtert (kein wiederholtes curl-Poren).
|
||||
16
docs/portainer-upgrade-20260828/preupgrade-state.json
Normal file
16
docs/portainer-upgrade-20260828/preupgrade-state.json
Normal file
File diff suppressed because one or more lines are too long
59
docs/portainer-upgrade-20260828/rollback-runbook.md
Normal file
59
docs/portainer-upgrade-20260828/rollback-runbook.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Portainer 2.40.0 → 2.42.6 — Rollback-Runbook (2026-08-28)
|
||||
|
||||
## Voraussetzungen
|
||||
- pve `.100`, dort LXC 400 (Docker-LXC auf vlan20)
|
||||
- Portainer-Container läuft mit den unten dokumentierten Flags
|
||||
- Pre-Upgrade-Image-Tag `portainer/portainer-ce:2.40.0-preupgrade-20260828` ist vorhanden
|
||||
|
||||
## Was hier dokumentiert ist
|
||||
1. **Image-Tag** mit dem Stand VOR dem Bump (für 1-Befehl-Rollback).
|
||||
2. **Runflags** des Containers (docker inspect-Auszug).
|
||||
3. **Volume-Mount** `/var/lib/docker/volumes/portainer_data/_data → /data`
|
||||
(Portainer-Persistenz: alle Stacks, Endpoint-Configs, Users, API-Tokens).
|
||||
Volume bleibt **unangetastet** beim Image-Swap — Settings überleben den Bump.
|
||||
|
||||
## Runflags (aus `docker inspect portainer --format '{{json .HostConfig}}'`)
|
||||
| Property | Wert |
|
||||
|---|---|
|
||||
| Image | `portainer/portainer-ce:2.42.6` (Bump) bzw. `:2.40.0-preupgrade-20260828` (Rollback) |
|
||||
| Restart | `always` |
|
||||
| Network | `bridge` (default), MACVLAN über das Compose-Netzwerk |
|
||||
| Privileged | `false` |
|
||||
| Ports | `8000/tcp → 8000`, `9443/tcp → 9443` |
|
||||
| Mounts | `/var/run/docker.sock → /var/run/docker.sock` (Pflicht), `/var/lib/docker/volumes/portainer_data/_data → /data` |
|
||||
|
||||
## Originaler Run-Befehl (rekonstruiert)
|
||||
```bash
|
||||
docker run -d \
|
||||
--name portainer \
|
||||
--restart always \
|
||||
-p 8000:8000 \
|
||||
-p 9443:9443 \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /var/lib/docker/volumes/portainer_data/_data:/data \
|
||||
portainer/portainer-ce:2.40.0
|
||||
```
|
||||
|
||||
## Rollback-Schritte (Bump macht Probleme)
|
||||
```bash
|
||||
# 1. Auf pve (LXC 400)
|
||||
ssh root@10.40.20.100 "pct exec 400 -- bash -c '
|
||||
docker stop portainer
|
||||
docker rm portainer
|
||||
docker run -d \\
|
||||
--name portainer \\
|
||||
--restart always \\
|
||||
-p 8000:8000 -p 9443:9443 \\
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \\
|
||||
-v /var/lib/docker/volumes/portainer_data/_data:/data \\
|
||||
portainer/portainer-ce:2.40.0-preupgrade-20260828
|
||||
'"
|
||||
# 2. API-Token ist volume-gebunden → bleibt gültig, keine Re-Auth.
|
||||
# 3. Verifikation: ein curl gegen die Settings-API reicht.
|
||||
```
|
||||
|
||||
## Cleanup nach erfolgreichem Bump
|
||||
Nach ≥7 Tagen Stabilität den `:preupgrade-20260828`-Tag löschen:
|
||||
```bash
|
||||
ssh root@10.40.20.100 "pct exec 400 -- docker rmi portainer/portainer-ce:2.40.0-preupgrade-20260828"
|
||||
```
|
||||
Reference in New Issue
Block a user