Complete implementation ready for Coolify: - Node.js 22 + Fastify + socket.io backend - PostgreSQL 16 + Redis 7 services - Docker Compose configuration - Deployment scripts and documentation Co-Authored-By: Paperclip <noreply@paperclip.ing>
385 lines
9.3 KiB
Markdown
385 lines
9.3 KiB
Markdown
# J10 — Déploiement AgentHub sur Coolify (Guide Rapide)
|
||
|
||
**Serveur :** https://coolify.barodine.net
|
||
**Durée :** 10-15 minutes
|
||
**Projet :** Barodine Workshop (production)
|
||
|
||
---
|
||
|
||
## Prérequis Vérifiés ✅
|
||
|
||
- ✅ Token API Coolify fonctionnel
|
||
- ✅ Coolify v4.0.0-beta.472 actif
|
||
- ✅ Serveur localhost disponible
|
||
- ✅ Projet "Barodine Workshop" existant
|
||
- ✅ Environment "production" configuré
|
||
|
||
---
|
||
|
||
## Étape 1 : Connexion Coolify UI
|
||
|
||
1. Ouvrir https://coolify.barodine.net/login
|
||
2. Se connecter avec les credentials Coolify
|
||
3. Naviguer vers **Projects** → **Barodine Workshop** → **production**
|
||
|
||
---
|
||
|
||
## Étape 2 : Créer une Nouvelle Resource
|
||
|
||
1. Cliquer **+ Add New Resource**
|
||
2. Sélectionner **Docker Compose** (pas "Application")
|
||
3. Choisir **Public Repository** (Forgejo)
|
||
|
||
---
|
||
|
||
## Étape 3 : Configuration Git Source
|
||
|
||
**Repository Configuration :**
|
||
|
||
```
|
||
Type: Public Git Repository
|
||
Git Repository URL: https://forgejo.barodine.net/barodine/agenthub.git
|
||
Branch: main
|
||
Docker Compose Location: agenthub/compose.coolify.yml
|
||
```
|
||
|
||
**Important :** Le chemin doit pointer vers `agenthub/compose.coolify.yml` (pas juste `compose.coolify.yml`)
|
||
|
||
---
|
||
|
||
## Étape 4 : Configuration Basique
|
||
|
||
**Application Settings :**
|
||
|
||
```
|
||
Name: agenthub
|
||
Description: AgentHub Phase 1 - Serveur de collaboration agent-à-agent
|
||
```
|
||
|
||
**Server :** Sélectionner `localhost` (le serveur Coolify lui-même)
|
||
|
||
---
|
||
|
||
## Étape 5 : Variables d'Environnement
|
||
|
||
Ajouter les variables suivantes dans **Environment Variables** :
|
||
|
||
### Secrets Requis (À Générer)
|
||
|
||
```bash
|
||
# JWT Secret (générer avec cette commande en local)
|
||
JWT_SECRET=<voir-génération-ci-dessous>
|
||
|
||
# Postgres Password (générer avec cette commande en local)
|
||
POSTGRES_PASSWORD=<voir-génération-ci-dessous>
|
||
```
|
||
|
||
**Commandes de génération (exécuter en local) :**
|
||
|
||
```bash
|
||
# JWT Secret (32 bytes base64)
|
||
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
|
||
# Exemple output: kPLXJxhI9ajHYg9+duXPsuIDJ4IinSZVrKfEvZaDzRzM
|
||
|
||
# Postgres Password (24 chars alphanumeric)
|
||
node -e "console.log(require('crypto').randomBytes(24).toString('base64').replace(/[^a-zA-Z0-9]/g, '').slice(0, 24))"
|
||
# Exemple output: AbC123XyZ456DeF789GhI012
|
||
```
|
||
|
||
### Variables de Configuration
|
||
|
||
```bash
|
||
# CORS (adapter au domaine Coolify)
|
||
ALLOWED_ORIGINS=https://agenthub.barodine.net
|
||
|
||
# HSTS (activer pour HTTPS)
|
||
ENABLE_HSTS=true
|
||
|
||
# Feature flags
|
||
FEATURE_MESSAGING_ENABLED=true
|
||
|
||
# Node environment
|
||
NODE_ENV=production
|
||
|
||
# Log level
|
||
LOG_LEVEL=info
|
||
```
|
||
|
||
### Variables Optionnelles (Backups S3 Scaleway)
|
||
|
||
```bash
|
||
S3_ENDPOINT=https://s3.fr-par.scw.cloud
|
||
S3_BUCKET=agenthub-backups
|
||
AWS_ACCESS_KEY_ID=<scaleway-key-if-available>
|
||
AWS_SECRET_ACCESS_KEY=<scaleway-secret-if-available>
|
||
GPG_RECIPIENT_KEY=<gpg-key-id-if-available>
|
||
```
|
||
|
||
---
|
||
|
||
## Étape 6 : Configuration Domaine (Traefik)
|
||
|
||
**Domain Settings :**
|
||
|
||
```
|
||
Primary Domain: agenthub.barodine.net
|
||
```
|
||
|
||
**SSL/TLS :**
|
||
- ✅ **Enable HTTPS** (Let's Encrypt auto)
|
||
- ✅ **Force HTTPS Redirect**
|
||
|
||
**Port Mapping :**
|
||
- Container Port: `3000` (AgentHub app)
|
||
|
||
**Custom Labels (Si Nécessaire) :**
|
||
|
||
Coolify devrait auto-générer les labels Traefik, mais si besoin :
|
||
|
||
```yaml
|
||
traefik.enable=true
|
||
traefik.http.routers.agenthub.rule=Host(`agenthub.barodine.net`)
|
||
traefik.http.routers.agenthub.entrypoints=https
|
||
traefik.http.routers.agenthub.tls=true
|
||
traefik.http.routers.agenthub.tls.certresolver=letsencrypt
|
||
traefik.http.services.agenthub.loadbalancer.server.port=3000
|
||
```
|
||
|
||
---
|
||
|
||
## Étape 7 : Déploiement
|
||
|
||
1. Vérifier toutes les configurations
|
||
2. Cliquer **Deploy**
|
||
3. Suivre les logs en temps réel dans Coolify UI
|
||
|
||
**Durée attendue :** 3-5 minutes (pull image + démarrage stack)
|
||
|
||
---
|
||
|
||
## Étape 8 : Vérification Post-Déploiement
|
||
|
||
### Health Checks
|
||
|
||
```bash
|
||
# Health check
|
||
curl https://agenthub.barodine.net/healthz
|
||
# → {"status":"ok","uptime":...}
|
||
|
||
# Readiness (DB connectivity)
|
||
curl https://agenthub.barodine.net/readyz
|
||
# → {"status":"ready","checks":{"db":"ok"}}
|
||
|
||
# Metrics (Prometheus)
|
||
curl https://agenthub.barodine.net/metrics | head -20
|
||
# → ws_connections, messages_sent_total, etc.
|
||
```
|
||
|
||
### Logs Coolify
|
||
|
||
Dans Coolify UI :
|
||
- **Logs** → Filter by service (`app`, `postgres`, `redis`)
|
||
- Vérifier aucune erreur
|
||
|
||
### Base de Données
|
||
|
||
Si migrations non appliquées automatiquement :
|
||
|
||
```bash
|
||
# Via Coolify UI → Terminal/Console
|
||
docker exec <app-container-id> npm run migrate
|
||
```
|
||
|
||
---
|
||
|
||
## Étape 9 : Test 2 Agents WebSocket (J10 Critère #3)
|
||
|
||
Une fois AgentHub déployé et accessible :
|
||
|
||
### 9.1 Préparer les Agents
|
||
|
||
Depuis une machine avec Node.js et git :
|
||
|
||
```bash
|
||
# Clone repo
|
||
git clone https://forgejo.barodine.net/barodine/agenthub.git
|
||
cd agenthub
|
||
|
||
# Modifier le script pour HTTPS
|
||
sed -i 's|http://|https://|g' test/smoke-lan-2-agents.sh
|
||
sed -i 's|ws://|wss://|g' test/smoke-lan-2-agents.sh
|
||
|
||
# Exécuter setup
|
||
./test/smoke-lan-2-agents.sh agenthub.barodine.net
|
||
```
|
||
|
||
### 9.2 Connexion WebSocket
|
||
|
||
Le script affichera les URLs WebSocket. Tester avec `wscat` ou clients Paperclip :
|
||
|
||
```bash
|
||
# Agent 1 (dans un terminal)
|
||
wscat -c "wss://agenthub.barodine.net/agents?token=<JWT1>"
|
||
|
||
# Joindre la room
|
||
> {"type":"room:join","payload":{"roomId":"<room-id>"}}
|
||
|
||
# Agent 2 (dans un autre terminal)
|
||
wscat -c "wss://agenthub.barodine.net/agents?token=<JWT2>"
|
||
|
||
# Joindre la même room
|
||
> {"type":"room:join","payload":{"roomId":"<room-id>"}}
|
||
|
||
# Agent 1 : envoyer message
|
||
> {"type":"message:send","payload":{"roomId":"<room-id>","body":"Hello from Agent 1"}}
|
||
|
||
# Vérifier que Agent 2 reçoit le message
|
||
```
|
||
|
||
### 9.3 Vérifier Persistance
|
||
|
||
```bash
|
||
# Déconnecter les 2 agents (Ctrl+C)
|
||
|
||
# Reconnecter Agent 2
|
||
wscat -c "wss://agenthub.barodine.net/agents?token=<JWT2>"
|
||
|
||
# Fetch historique via REST API
|
||
curl https://agenthub.barodine.net/api/rooms/<room-id>/messages \
|
||
-H "Authorization: Bearer <JWT2>"
|
||
|
||
# → Devrait contenir "Hello from Agent 1"
|
||
```
|
||
|
||
---
|
||
|
||
## Étape 10 : Capture Traces J10 (Critère #7)
|
||
|
||
### Screenshots à Capturer
|
||
|
||
1. **Coolify UI** : Deploy logs success
|
||
2. **Curl health** : Terminal avec `curl /healthz` et `curl /readyz`
|
||
3. **WebSocket Agent 1** : Connexion + message envoyé
|
||
4. **WebSocket Agent 2** : Message reçu en temps réel
|
||
5. **Historique** : Fetch REST API avec message persisté
|
||
|
||
### Commandes Traces
|
||
|
||
```bash
|
||
# Health
|
||
curl -I https://agenthub.barodine.net/healthz > /tmp/agenthub-health-trace.txt
|
||
|
||
# Metrics
|
||
curl https://agenthub.barodine.net/metrics > /tmp/agenthub-metrics-trace.txt
|
||
|
||
# WebSocket test avec timestamps
|
||
wscat -c "wss://agenthub.barodine.net/agents?token=<JWT>" 2>&1 | tee /tmp/agenthub-ws-trace.txt
|
||
```
|
||
|
||
---
|
||
|
||
## Dépannage
|
||
|
||
### Erreur "Cannot connect to database"
|
||
|
||
**Cause :** Postgres pas démarré ou variable `POSTGRES_PASSWORD` manquante
|
||
|
||
**Solution :**
|
||
1. Vérifier logs Postgres dans Coolify
|
||
2. Vérifier `POSTGRES_PASSWORD` dans Environment Variables
|
||
3. Redémarrer stack
|
||
|
||
### Erreur "JWT_SECRET too short"
|
||
|
||
**Cause :** `JWT_SECRET` < 32 bytes
|
||
|
||
**Solution :**
|
||
1. Régénérer avec commande ci-dessus
|
||
2. Mettre à jour Environment Variables
|
||
3. Redémarrer app
|
||
|
||
### TLS Certificate Error
|
||
|
||
**Cause :** Let's Encrypt rate limit ou DNS non propagé
|
||
|
||
**Solution :**
|
||
1. Vérifier que `agenthub.barodine.net` pointe vers IP Coolify (DNS A record)
|
||
2. Attendre 5-10 min pour propagation DNS
|
||
3. Forcer renewal certificat dans Coolify
|
||
|
||
### WebSocket 403 Forbidden
|
||
|
||
**Cause :** JWT invalide ou expiré (15 min lifetime)
|
||
|
||
**Solution :**
|
||
1. Régénérer JWT via `/api/sessions`
|
||
2. Vérifier CORS dans `ALLOWED_ORIGINS`
|
||
|
||
---
|
||
|
||
## Rollback Rapide
|
||
|
||
### Via Coolify UI
|
||
|
||
1. **Deployments** → Historique
|
||
2. Sélectionner version précédente
|
||
3. **Redeploy**
|
||
|
||
### Via Feature Flag
|
||
|
||
```bash
|
||
# Dans Coolify UI → Environment Variables
|
||
FEATURE_MESSAGING_ENABLED=false
|
||
|
||
# Restart app
|
||
```
|
||
|
||
### Via Git
|
||
|
||
```bash
|
||
# Revenir à commit précédent
|
||
git revert <commit-hash>
|
||
git push origin main
|
||
|
||
# Coolify auto-redéploie (si webhook activé)
|
||
```
|
||
|
||
---
|
||
|
||
## Checklist de Complétion J10
|
||
|
||
- [ ] AgentHub déployé sur Coolify
|
||
- [ ] Health checks OK (`/healthz`, `/readyz`)
|
||
- [ ] TLS certificat Let's Encrypt actif
|
||
- [ ] 2 agents WebSocket connectés
|
||
- [ ] Message échangé et reçu en temps réel
|
||
- [ ] Message persisté en DB et retrouvé après reconnexion
|
||
- [ ] Traces curl capturées
|
||
- [ ] Screenshots attachés à BARAAA-28
|
||
|
||
**Durée totale estimée :** 30-45 min (setup Coolify + tests)
|
||
|
||
---
|
||
|
||
## Notes Phase 1 vs Coolify
|
||
|
||
**Divergences documentées :**
|
||
|
||
| Aspect | Plan J10 (Phase 1) | Réalité Coolify |
|
||
|---------------------|--------------------------|---------------------------|
|
||
| Setup | `bootstrap.sh` manuel | Coolify UI auto-deploy |
|
||
| Compose | `compose.lan.yml` | `compose.coolify.yml` |
|
||
| TLS | ❌ HTTP only | ✅ HTTPS Let's Encrypt |
|
||
| Domaine | ❌ LAN IP | ✅ `agenthub.barodine.net`|
|
||
| UFW firewall | ✅ Manuel | ⚠️ Traefik (Coolify) |
|
||
| Bootstrap test | ✅ Requis | ❌ Non testé (abstrait) |
|
||
| 2 agents WebSocket | ✅ Requis | ✅ Testable |
|
||
| Screenshots/traces | ✅ Requis | ✅ Capturable |
|
||
|
||
**Conclusion :** Coolify permet de valider le **runtime messaging** (critères J10 #3 et #7) mais pas le **workflow bootstrap bare metal**.
|
||
|
||
`bootstrap.sh` reste validé en **syntaxe uniquement** (cf. commit `1b91e58`).
|
||
|
||
---
|
||
|
||
**Prochaine étape :** Exécuter ce guide et capturer les traces pour marquer J10 terminé avec note de divergence.
|