Plan de migration par phases¶
La migration vers Docker se fait de manière incrémentale, service par service, pour minimiser les risques et permettre un retour arrière à chaque étape.
Vue d'ensemble des phases¶
gantt
title Migration Essensys vers Docker
dateFormat YYYY-MM-DD
axisFormat %b %Y
section Phase 0
Installer Docker sur le Pi :p0a, 2026-03-01, 3d
Dockeriser Redis + Mosquitto :p0b, after p0a, 4d
section Phase 1
Créer repo essensys-mcp :p1a, after p0b, 5d
Dockerfile MCP + CI/CD :p1b, after p1a, 3d
Déployer MCP en container :p1c, after p1b, 3d
section Phase 2
Dockerfile Backend + CI/CD :p2a, after p1c, 5d
Dockerfile Frontend + CI/CD :p2b, after p1c, 5d
Nginx en container :p2c, after p2b, 3d
section Phase 3
Traefik en container :p3a, after p2c, 3d
AdGuard en container :p3b, after p3a, 2d
Monitor en container :p3c, after p3a, 2d
section Phase 4
Développer le Control Plane :p4a, after p3b, 15d
Interface UI Control Plane :p4b, after p4a, 10d
Intégration MCP + Control Plane :p4c, after p4b, 5d
section Phase 5 - Observabilité
Déployer Prometheus + node-exporter :p5a, after p4c, 5d
Ajouter /metrics sur MCP + Backend :p5b, after p5a, 5d
Configurer alertes + Alertmanager :p5c, after p5b, 3d
section Phase 6 - IA et Automatisation
Déployer OpenClaw :p6a, after p5c, 7d
Déployer N8N :p6b, after p5c, 5d
Workflows N8N essentiels :p6c, after p6b, 7d
Intégration Prometheus-N8N-OpenClaw :p6d, after p6c, 5d
section Phase 7 - Nettoyage
Supprimer les services systemd :p7a, after p6d, 3d
Supprimer les rôles Ansible legacy :p7b, after p7a, 2d
Documentation finale :p7c, after p7b, 3d Phase 0 : Prérequis (semaine 1)¶
Objectif : Installer Docker et migrer les services d'infrastructure simples.
Étapes¶
-
Installer Docker Engine sur Raspberry Pi OS
-
Installer Docker Compose v2 (plugin)
-
Migrer Redis en container
-
Migrer Mosquitto en container
-
Tester : vérifier que le backend et le MCP (encore en systemd) se connectent correctement à Redis et Mosquitto dockerisés
Critère de validation¶
redis-cli ping→PONGdepuis le backend systemd- Le backend écrit et lit dans Redis normalement
- MQTT debug monitor fonctionne
Rollback¶
Arrêter les containers, redémarrer redis-server et mosquitto en systemd.
Phase 1 : MCP standalone (semaines 2-3)¶
Objectif : Extraire le MCP du backend, le dockeriser, valider l'indépendance.
Phase critique
Le MCP est le service le plus stratégique. C'est le premier à migrer car :
- Il sera la base du Control Plane
- Son cycle de release doit devenir indépendant
- Il valide toute la chaîne CI/CD (build image → registry → pull sur Pi)
Étapes¶
-
Créer le repo
essensys-mcpsur GitHub -
Extraire le code de
essensys-server-backend/cmd/mcp-server/vers le nouveau repo -
Écrire le Dockerfile multi-stage (voir MCP Standalone)
-
Configurer GitHub Actions pour le build arm64 + push vers ghcr.io
-
Déployer le container MCP à côté du backend systemd
-
Arrêter le service systemd
essensys-mcp -
Tester avec un agent IA (OpenClaw) : vérifier que tous les outils MCP fonctionnent
Critère de validation¶
curl -N -H "Authorization: Bearer $TOKEN" http://localhost:8083/sse→ stream SSE OKfind_device_index+send_orderfonctionnent depuis un agentlist_service_statusvoit les containers Docker + les services systemd restants
Rollback¶
Arrêter le container MCP, redémarrer le service systemd.
Phase 2 : Backend + Frontend (semaines 3-4)¶
Objectif : Dockeriser les services Essensys principaux.
Backend¶
-
Écrire le Dockerfile dans
essensys-server-backend/ -
CI/CD : même workflow que le MCP
-
Déployer, arrêter le systemd
essensys-backend
Frontend¶
-
Dockerfile avec build Node + Nginx pour servir
-
L'image frontend n'expose pas de port : elle fournit les fichiers statiques dans un volume partagé avec Nginx
Nginx¶
Nginx passe en container avec la config Essensys montée en volume.
Client legacy
Tester impérativement la communication avec le client BP_MQX_ETH. Si le NAT Docker pose problème, utiliser network_mode: host pour Nginx.
Critère de validation¶
- Frontend accessible sur
http://mon.essensys.fr/ - API backend accessible sur
http://mon.essensys.fr/api/serverinfos - Client legacy fonctionne normalement (single-packet TCP)
Phase 3 : Services réseau (semaine 5)¶
Objectif : Migrer Traefik et AdGuard en containers.
Traefik¶
Traefik a une image Docker officielle et supporte nativement le Docker provider :
traefik:
image: traefik:v2.11
ports:
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- acme:/etc/traefik/acme
Avantage : Traefik peut auto-détecter les containers Docker via les labels, simplifiant la configuration des routes.
AdGuard Home¶
adguard:
image: adguard/adguardhome
ports:
- "53:53/tcp"
- "53:53/udp"
- "3000:3000"
volumes:
- adguard-conf:/opt/adguardhome/conf
- adguard-work:/opt/adguardhome/work
Monitor¶
monitor:
image: ghcr.io/essensys-hub/monitor:${ESSENSYS_VERSION}
ports:
- "5000:5000"
environment:
- MQTT_BROKER=mosquitto
Critère de validation¶
- HTTPS fonctionne sur
https://essensys.acme.com/ - DNS local résout
mon.essensys.fr docker compose ps: tous les services running- Plus aucun service systemd Essensys (sauf Docker lui-même)
Phase 4 : Control Plane (semaines 6-9)¶
Objectif : Développer et déployer le Control Plane.
Étapes¶
-
Créer le repo
essensys-control-plane -
Développer l'API (Go) :
- Endpoints
/api/services,/api/versions,/api/logs,/api/system - Accès Docker socket pour la gestion des containers
- Check registry ghcr.io pour les nouvelles versions
- Base SQLite pour l'historique
- Endpoints
-
Développer l'UI (React) :
- Dashboard avec statut de tous les services
- Page versions avec boutons Update / Rollback
- Viewer de logs avec filtre et live tail
- Page système (CPU, RAM, disque, température)
-
Intégrer avec le MCP :
- Le MCP appelle le Control Plane pour les opérations d'infrastructure
- Le Control Plane appelle le MCP pour les diagnostics
- Nouveaux outils MCP :
check_updates,update_service,rollback_service
-
Dockeriser et déployer
Critère de validation¶
- Dashboard accessible sur
http://cp.essensys.local:9100/ - Mise à jour d'un service depuis l'UI
- Rollback fonctionnel
- Logs visibles en temps réel
- Agent IA peut demander un diagnostic complet via MCP
Phase 5 : Observabilité - Prometheus (semaines 10-11)¶
Objectif : Mettre en place la collecte de métriques et les alertes.
Étapes¶
-
Déployer Prometheus + node-exporter (métriques système Pi)
prometheus: image: prom/prometheus:latest ports: - "9090:9090" volumes: - ./config/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro - ./config/prometheus/alert-rules.yml:/etc/prometheus/alert-rules.yml:ro - prometheus-data:/prometheus node-exporter: image: prom/node-exporter:latest pid: host volumes: - /proc:/host/proc:ro - /sys:/host/sys:ro command: - '--path.procfs=/host/proc' - '--path.sysfs=/host/sys' -
Ajouter
/metricssur le MCP et le Backend (endpoint Prometheus natif en Go avecpromhttp) -
Configurer les règles d'alerte : service down, CPU élevé, température, disque plein, erreurs MCP
-
Déployer Alertmanager : routage vers webhooks (préparation pour N8N et OpenClaw)
-
Intégrer au Control Plane : le dashboard query Prometheus au lieu de faire son propre polling
Critère de validation¶
http://pi:9090/targets→ tous les targets UP- Alerte
ServiceDownse déclenche quand on stoppe un container - Le dashboard Control Plane affiche des graphes depuis Prometheus
/metricsaccessible sur le MCP et le Backend
Rollback¶
Supprimer les containers Prometheus et node-exporter. Le Control Plane repasse en mode polling direct.
Phase 6 : IA et Automatisation (semaines 12-15)¶
Objectif : Déployer OpenClaw, N8N et connecter le triangle d'intelligence.
Prérequis
Prometheus doit être opérationnel (Phase 5) pour que les alertes puissent être routées vers N8N et OpenClaw.
Étapes¶
-
Déployer OpenClaw comme container Docker
-
Déployer N8N (image officielle)
-
Créer les workflows N8N essentiels :
- Notification d'alerte Prometheus (email/WhatsApp/Signal/Telegram)
- Mise à jour semi-automatique (check registry → notification → approbation → deploy)
- Forward message utilisateur → OpenClaw → réponse
- Rapport quotidien (métriques + events)
-
Configurer Alertmanager pour router :
- Alertes
critical→ OpenClaw (auto-diagnostic) + N8N (notification) - Alertes
warning→ N8N (notification admin)
- Alertes
-
Tester le flux complet : envoyer un message (WhatsApp/Signal/Telegram) → N8N → OpenClaw → MCP → action exécutée → réponse
Critère de validation¶
- OpenClaw pilote les équipements via MCP depuis une commande texte
- N8N reçoit les alertes Prometheus et envoie des notifications
- Le flux utilisateur → (WhatsApp/Signal/Telegram) → N8N → OpenClaw → MCP → action fonctionne end-to-end
- OpenClaw auto-diagnostique quand un service est down
Rollback¶
Supprimer les containers OpenClaw et N8N. Le système fonctionne normalement sans eux (pas de dépendance critique).
Phase 7 : Nettoyage (semaine 16)¶
Objectif : Supprimer tout le legacy systemd.
-
Supprimer les services systemd :
-
Supprimer les dépendances système inutiles :
-
Simplifier
install.sh: le script ne fait plus que :- Installer Docker
- Configurer le réseau
docker compose pull && docker compose up -d
-
Mettre à jour les rôles Ansible : optionnel, pour les Pi distants. Les rôles deviennent des wrappers autour de Docker Compose.
-
Mettre à jour la documentation
Résumé des risques¶
| Risque | Impact | Mitigation |
|---|---|---|
| Client legacy incompatible avec NAT Docker | Élevé | Tester tôt (Phase 2). Fallback: network_mode: host pour Nginx |
| RAM insuffisante (Pi 4 Go) | Élevé | Pi 8 Go recommandé avec N8N + OpenClaw + Prometheus (~900 Mo ajoutés) |
| Performance Docker sur Pi | Moyen | Overhead ~5%. Acceptable sur Pi 4/8 Go |
| Espace disque (images Docker) | Moyen | Images Alpine minimales. Rotation automatique (docker system prune) |
| Temps de build CI arm64 via QEMU | Faible | Cache GitHub Actions. Build ~5-10 min par image |
| Perte de données Redis au restart | Faible | Volume persistant + appendonly yes |
| Coût API LLM (OpenClaw) | Moyen | Usage via API externe (Anthropic/OpenAI). Monitorer la consommation via N8N |
| Prometheus rétention disque | Moyen | Limiter --storage.tsdb.retention.time=30d. ~500 Mo pour 30 jours |
| N8N workflows complexes | Faible | Commencer simple (4 workflows essentiels), itérer |