4.1 KiB
Hébergement de sites statiques produits par Hermes
Date : 2026-06-20
Origine : Incident panda-dashboard — site hors ligne après redémarrage Container Manager
Applicable : hermes-tt, hermes-nyora, hermes-perso
LE PROBLÈME À NE JAMAIS REPRODUIRE
Hermes-nyora avait servi panda-dashboard via python3 -m http.server lancé depuis son
propre workspace. Quand Container Manager redémarre, le container Hermes redémarre et
le process Python meurt — sans aucune relance automatique.
Un agent Hermes NE DOIT PAS héberger un site en production.
Le workspace d'un agent est éphémère du point de vue de la disponibilité service.
LA RÈGLE
Tout site statique produit par Hermes doit être déployé dans son propre container Docker dédié avec
restart: always, via un docker-compose dans/volume1/docker/.
PROCÉDURE — Déployer un site statique
1. Identifier un port libre
Lire /volume1/docker/ports-registry.md (accessible depuis l'agent : /opt/data/workspace/../../../ports-registry.md — non, passer par l'outil NAS ou demander à Claude).
Plages recommandées : 3040-3099, 8800-8899.
2. Créer le docker-compose dans /volume1/docker/
L'agent écrit le fichier dans son workspace, puis demande au MCP NAS de le déplacer. Ou bien Claude le crée directement via mcp-nas.
Template à copier :
# <nom-du-site> — description courte
# Port : <PORT> — <domaine.bolbol.tn>
services:
<nom-du-site>:
image: nginx:alpine
container_name: <nom-du-site>
restart: always
ports:
- "<PORT>:80"
volumes:
- /volume1/docker/hermes-platform/hermes-<instance>/data/workspace/<dossier-site>:/usr/share/nginx/html:ro
networks:
- n8n_default
networks:
n8n_default:
external: true
3. Déployer via API Portainer
Portainer est accessible sur http://172.17.0.1:9000 depuis les containers Docker.
# Obtenir JWT
JWT=$(curl -s -X POST http://172.17.0.1:9000/api/auth \
-H "Content-Type: application/json" \
-d '{"username":"bestof","password":"2L2u519wportainer"}' \
| grep -o '"jwt":"[^"]*"' | cut -d'"' -f4)
# Créer le stack (endpointId=2 = local)
curl -s -X POST "http://172.17.0.1:9000/api/stacks/create/standalone/string?endpointId=2" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d "{
\"name\": \"<nom-du-site>\",
\"stackFileContent\": $(cat /chemin/vers/docker-compose.yml | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))'),
\"env\": []
}"
Vérification :
JWT=<JWT_OBTENU>
curl -s "http://172.17.0.1:9000/api/endpoints/2/docker/containers/json?filters=%7B%22label%22%3A%5B%22com.docker.compose.project%3D<nom-du-site>%22%5D%7D" \
-H "Authorization: Bearer $JWT" | python3 -c "
import json,sys
for c in json.load(sys.stdin):
print(c['Names'], c['State'], c['Status'])
"
4. Configurer le Reverse Proxy DSM
DSM → Panneau de configuration → Portail d'applications → Proxy inversé :
- Source : HTTPS,
<nom>.bolbol.tn, port 443 - Destination : HTTP,
192.168.100.33, port<PORT>
5. Mettre à jour ports-registry.md
# Ajouter la ligne dans le tableau Services Actifs
# Marquer le port comme OCCUPE dans Plages libres
# Ajouter une ligne dans Historique des modifications
6. Commit Gitea
cd /volume1/docker/<nom-du-site>
git init
git add .
git commit -m "deploy: <nom-du-site> nginx statique port <PORT>"
git push http://bolbol:2L2u519wgitea@192.168.100.33:3232/bolbol/nas-runbooks.git
EXEMPLE CONCRET — panda-dashboard (2026-06-20)
- Dossier source :
/volume1/docker/hermes-platform/hermes-nyora/data/workspace/panda-dashboard/ - Port : 3021
- Domaine : panda.bolbol.tn
- Stack Portainer : ID 314
- Compose :
/volume1/docker/panda-dashboard/docker-compose.yml
RAPPEL SÉCURITÉ
- Ne jamais stocker de données sensibles dans le workspace monté en lecture publique
- Le volume est monté
:ro(read-only) — le container nginx ne peut pas modifier les fichiers - Le mot de passe Portainer est dans
/volume1/docker/hermes-platform/.env