fix(mcp): intégration réelle passerelle MCP Portainer (image+auth) (v0.34.0)
Image portainer-mcp 0.6.0 (inexistant) -> 2.42.6. Passerelle HTTP :17717/mcp attend Bearer (secret passerelle) + X-Portainer-API-Key (clé API restreinte chlova) : ajout config.portainerApiKey + McpServerConfig.extraHeaders, backend envoie les deux. socket-proxy supprimé (plus de socket monté). Compose prod, .env.example, deploy.md à jour. Typecheck + 78 tests verts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016w5jRe87MGdd6AMvXQcHNi
This commit is contained in:
@@ -32,44 +32,20 @@ services:
|
||||
- chlova-egress
|
||||
# AUCUN port publié : Ollama n'a pas d'auth native, jamais exposé.
|
||||
|
||||
# ── socket-proxy : accès Docker filtré, LECTURE SEULE (Phase 1) ─────────
|
||||
socket-proxy:
|
||||
image: tecnativa/docker-socket-proxy:0.3.0
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
CONTAINERS: 1
|
||||
IMAGES: 1
|
||||
NETWORKS: 1
|
||||
VOLUMES: 1
|
||||
SERVICES: 1
|
||||
TASKS: 1
|
||||
NODES: 1
|
||||
INFO: 1
|
||||
VERSION: 1
|
||||
POST: 0
|
||||
EXEC: 0
|
||||
AUTH: 0
|
||||
SECRETS: 0
|
||||
CONFIGS: 0
|
||||
BUILD: 0
|
||||
COMMIT: 0
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
networks:
|
||||
- chlova-internal
|
||||
# AUCUN port publié.
|
||||
|
||||
# ── MCP Portainer (portainer/portainer-mcp) — read-only en Phase 1 ──────
|
||||
# ── MCP Portainer (passerelle HTTP portainer/portainer-mcp) — read-only P1 ─
|
||||
# Parle à l'API Portainer (pas au socket Docker). Le backend s'y connecte en
|
||||
# HTTP sur :17717/mcp avec le secret de passerelle (Bearer) + la clé API
|
||||
# restreinte de chlova (X-Portainer-API-Key).
|
||||
mcp-portainer:
|
||||
image: portainer/portainer-mcp:0.6.0
|
||||
image: portainer/portainer-mcp:2.42.6
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
PORTAINER_URL: ${PORTAINER_URL:-http://portainer:9000} # interne : Portainer sur le même hôte (local), réseau proxy
|
||||
PORTAINER_MCP_AUTH_TOKEN: ${PORTAINER_MCP_AUTH_TOKEN:?requis} # token user chlova restreint
|
||||
PORTAINER_READ_ONLY: ${PORTAINER_READ_ONLY:-true} # P1 : NE PAS passer à false
|
||||
DOCKER_HOST: tcp://socket-proxy:2375
|
||||
depends_on:
|
||||
- socket-proxy
|
||||
PORTAINER_MCP_AUTH_TOKEN: ${PORTAINER_MCP_AUTH_TOKEN:?requis} # secret de passerelle (partagé avec le backend)
|
||||
PORTAINER_MCP_ALLOWED_HOSTS: mcp-portainer:17717 # hôte par lequel le backend appelle
|
||||
PORTAINER_MCP_DANGEROUSLY_ALLOW_PLAINTEXT_HTTP: "1" # HTTP interne (réseau Docker privé)
|
||||
PORTAINER_TLS_VERIFY: "0" # Portainer interne en HTTP : pas de TLS
|
||||
PORTAINER_READ_ONLY: ${PORTAINER_READ_ONLY:-true} # P1 : GET/HEAD seulement (défense en profondeur)
|
||||
networks:
|
||||
- chlova-internal # joignable par le backend
|
||||
- proxy # joint le serveur Portainer (http://portainer:9000)
|
||||
@@ -95,9 +71,10 @@ services:
|
||||
# — MCP n8n (natif, interne via réseau proxy) —
|
||||
MCP_N8N_URL: ${MCP_N8N_URL:-http://n8n-chlova:5678/mcp-server/http}
|
||||
MCP_N8N_AUTH_TOKEN: ${MCP_N8N_AUTH_TOKEN:?requis}
|
||||
# — MCP Portainer (sidecar) —
|
||||
MCP_PORTAINER_URL: ${MCP_PORTAINER_URL:-http://mcp-portainer:3000}
|
||||
PORTAINER_MCP_AUTH_TOKEN: ${PORTAINER_MCP_AUTH_TOKEN:?requis}
|
||||
# — MCP Portainer (passerelle) —
|
||||
MCP_PORTAINER_URL: ${MCP_PORTAINER_URL:-http://mcp-portainer:17717/mcp}
|
||||
PORTAINER_MCP_AUTH_TOKEN: ${PORTAINER_MCP_AUTH_TOKEN:?requis} # secret de passerelle (= côté sidecar)
|
||||
PORTAINER_API_KEY: ${PORTAINER_API_KEY:?requis} # clé API Portainer restreinte de chlova
|
||||
PORTAINER_READ_ONLY: ${PORTAINER_READ_ONLY:-true}
|
||||
# — Alertes (Phase 3) : vide = log-only —
|
||||
ALERT_WEBHOOK_URL: ${ALERT_WEBHOOK_URL:-}
|
||||
|
||||
Reference in New Issue
Block a user