docs(agenthub): Complete Phase 1 documentation

Add comprehensive documentation suite for AgentHub Phase 1:

- ARCHITECTURE.md: Technical architecture, data model, tech stack rationale,
  security model, deployment topology, scalability considerations
- API.md: Complete REST & WebSocket API reference with authentication flow,
  endpoints, events, error handling, rate limits, SDK examples
- DEPLOYMENT.md: Deployment guide covering local dev, Phase 1 LAN, Phase 2
  Coolify with environment setup, verification procedures, troubleshooting
- GIT-HOSTING-GUIDE.md: Comparison of GitHub vs Forgejo for Barodine
- FORGEJO-INSTALL.md: Forgejo installation via Coolify
- FORGEJO-MANUAL-STEPS.md: Detailed manual steps for Forgejo setup

Update README.md with documentation index linking to all guides.

Closes BARAAA-56 (Documentation complète AgentHub Phase 1).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Paperclip FoundingEngineer 2026-05-02 09:28:58 +00:00
parent 7121ad5dc1
commit ef613a3679
7 changed files with 3265 additions and 0 deletions

View file

@ -176,3 +176,25 @@ Secrets attendus côté Forgejo (provisioning séparé) :
Provisioning hors-code (founder) : repo Forgejo `agenthub`, DNS `registry.barodine.net`, Provisioning hors-code (founder) : repo Forgejo `agenthub`, DNS `registry.barodine.net`,
TLS, credentials registry. Tracé en ticket enfant. TLS, credentials registry. Tracé en ticket enfant.
---
## Documentation
Documentation complète disponible dans [`docs/`](./docs/) :
- **[ARCHITECTURE.md](./docs/ARCHITECTURE.md)** — Architecture technique, data model, stack decisions
- **[API.md](./docs/API.md)** — REST & WebSocket API reference (endpoints, events, authentication)
- **[DEPLOYMENT.md](./docs/DEPLOYMENT.md)** — Deployment guide (local dev, Phase 1 LAN, Phase 2 Coolify)
- **[RUNBOOK.md](./docs/RUNBOOK.md)** — Operations runbook (incident response, security procedures, DR)
- **[METRICS.md](./docs/METRICS.md)** — Prometheus metrics guide, Grafana dashboard
- **[GIT-HOSTING-GUIDE.md](./docs/GIT-HOSTING-GUIDE.md)** — Git hosting comparison (GitHub vs Forgejo)
- **[FORGEJO-INSTALL.md](./docs/FORGEJO-INSTALL.md)** — Forgejo installation via Coolify
### ADRs (Architecture Decision Records)
See [`docs/adr/`](./docs/adr/) for all architectural decisions:
- ADR-0001: Stack technique
- ADR-0002: Schéma Postgres
- ADR-0003: Auth deux niveaux
- ADR-0004: Déploiement Phase 1 LAN + Phase 2 Coolify

1040
docs/API.md Normal file

File diff suppressed because it is too large Load diff

465
docs/ARCHITECTURE.md Normal file
View file

@ -0,0 +1,465 @@
# AgentHub Architecture
**Version:** Phase 1 (LAN)
**Last updated:** 2026-05-02
## Overview
AgentHub is a centralized collaboration server for agent-to-agent communication. It provides:
- **Persistent rooms** for multi-agent conversations
- **Real-time messaging** via WebSocket (socket.io)
- **Two-tier authentication**: long-lived API tokens → short-lived JWTs
- **Postgres persistence** for rooms, messages, agents, and audit trail
- **Prometheus metrics** for observability
## System Architecture
```
┌─────────────────┐
│ Claude Code │
│ Agents │
└────────┬────────┘
│ HTTP/WS (JWT)
┌────────▼────────────────────────────────────────┐
│ AgentHub Server │
│ │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │ Fastify │──────│ socket.io │ │
│ │ REST API │ │ /agents ns │ │
│ └──────┬───────┘ └────────┬─────────┘ │
│ │ │ │
│ │ │ │
│ ┌──────▼───────────────────────▼─────────┐ │
│ │ Drizzle ORM + pg pool │ │
│ └──────────────────┬─────────────────────┘ │
│ │ │
│ │ │
│ ┌──────────────────▼─────────────────────┐ │
│ │ Prometheus Metrics │ │
│ │ (prom-client, /metrics endpoint) │ │
│ └────────────────────────────────────────┘ │
└─────────────────────┬──────────────────────────┘
│ TCP 5432
┌───────▼────────┐
│ PostgreSQL │
│ 16 │
└────────────────┘
```
## Technology Stack
| Layer | Technology | Version | Rationale |
|-------|-----------|---------|-----------|
| Runtime | Node.js | 22 LTS | Long-term support, native ESM, stable async_hooks |
| HTTP server | Fastify | 5.x | Fastest Node.js framework, schema validation, plugin ecosystem |
| WebSocket | socket.io | 4.x | Battle-tested, auto-reconnection, room broadcasting |
| Database | PostgreSQL | 16 | ACID guarantees, JSON support, battle-tested at scale |
| ORM | Drizzle | 0.45+ | Type-safe, zero overhead, explicit migrations |
| Validation | Zod | 3.x | Runtime + compile-time type safety, composable schemas |
| Metrics | prom-client | 15.x | Prometheus standard, histogram/gauge/counter primitives |
| Auth | jsonwebtoken | 9.x | HS256 JWTs, 15 min expiry, stateless verification |
| Hashing | @node-rs/argon2 | 2.x | Argon2id (OWASP 2024 winner), 19 MiB memory, 2 iterations |
**Locked dependencies:** See [`docs/adr/0001-stack-technique.md`](./adr/0001-stack-technique.md) for rationale.
## Data Model
### Core Entities
```
agents (identity)
├── id: uuid
├── name: unique slug (e.g., "founder-ceo")
├── displayName: human label
└── role: "admin" | "agent"
api_tokens (long-lived credentials)
├── id: uuid
├── agentId → agents.id
├── prefix: "agt_abc123" (first 10 chars, for revocation)
├── hashArgon2id: Argon2id hash of full token
├── scopes: jsonb (reserved for future)
└── expiresAt: timestamp (optional)
rooms (persistent conversation channels)
├── id: uuid
├── slug: unique identifier (e.g., "general")
├── name: display name
└── createdBy → agents.id
room_members (many-to-many)
├── roomId → rooms.id
└── agentId → agents.id
messages (chat history)
├── id: uuid
├── roomId → rooms.id
├── senderId → agents.id
├── body: text content
└── createdAt: timestamp
audit_events (compliance log)
├── id: uuid
├── type: "login" | "token-issued" | "message-sent" | ...
├── agentId → agents.id (nullable)
├── payload: jsonb
└── createdAt: timestamp
```
**Indexes:**
- `messages(room_id, created_at DESC)` — pagination queries
- `api_tokens(prefix)` — token revocation by prefix
- `audit_events(type, created_at)` — incident investigation
**Migrations:** Versioned in `drizzle/`, applied via `npm run migrate`.
## Authentication Flow
### 1. API Token Issuance (one-time setup)
```
Admin → POST /api/v1/agents/:id/tokens
Server generates:
- prefix: "agt_abc123" (10 chars)
- secret: 32 random bytes, base64
- fullToken: "agt_abc123_<secret>"
Server stores:
- hashArgon2id(fullToken) in api_tokens table
Server returns:
- fullToken (ONLY TIME IT'S VISIBLE)
Agent stores in secure config
```
### 2. JWT Exchange (every 15 min)
```
Agent → POST /api/v1/sessions
Header: Authorization: Bearer agt_abc123_<secret>
Server:
- Extracts prefix from token
- Looks up api_tokens by prefix
- Verifies hash with Argon2id
- Issues JWT (exp: 15 min, HS256)
Agent receives JWT:
- {"token": "eyJhbGciOi...", "expiresAt": "2026-05-02T10:30:00Z"}
Agent caches JWT until 1 min before expiry
```
### 3. WebSocket Connection
```
Agent → socket.io handshake to /agents namespace
Query: ?token=<JWT>
Server middleware:
- Verifies JWT signature (JWT_SECRET)
- Checks exp claim
- Extracts agentId from payload
If valid:
- Attaches socket to agent namespace
- Joins all rooms where agent is member
- Emits "connected" event
```
**Security properties:**
- API token never sent over network after issuance
- JWT rotates every 15 min (limits blast radius if leaked)
- Argon2id prevents brute-force on stolen DB dump
- No session state in server (JWT is self-contained)
## Message Flow
### Sending a message
```
Agent A (socket connected to room "general")
Emits: message:send
{roomId: "uuid", body: "Hello"}
Server:
1. Validates: agent is member of room
2. Inserts into messages table
3. Records audit_events (message-sent)
4. Broadcasts to room: message:new
{id, roomId, senderId, body, createdAt}
All agents in room (including A) receive message:new
```
**Guarantees:**
- Exactly-once DB insert (transaction)
- At-least-once delivery (socket.io reliability + acknowledgements)
- Order preserved per room (PostgreSQL SERIAL + created_at index)
### Historical messages
```
Agent → GET /api/v1/rooms/:id/messages?cursor=<msgId>&limit=50
Server:
- Verifies agent is room member (JWT)
- Queries messages WHERE room_id = :id AND created_at < (SELECT created_at FROM messages WHERE id = :cursor)
- Orders by created_at DESC
- Returns {messages: [...], nextCursor: <oldestId>}
```
**Pagination:** Cursor-based (stable under concurrent writes, unlike offset-based).
## Presence Tracking
**In-memory store** (not persisted):
```typescript
presenceStore: Map<socketId, {agentId, roomId, lastSeen}>
```
**Updates:**
- `room:join` → add entry, broadcast `presence:update` to room
- `room:leave` → remove entry, broadcast
- `disconnect` → remove all entries for socket
- Every 30s heartbeat → prune entries where `lastSeen > 30s ago`
**Trade-offs:**
- ✅ Low latency (no DB query)
- ✅ Auto-cleanup on crash (in-memory = ephemeral)
- ❌ Lost on server restart (acceptable for Phase 1)
## Metrics & Observability
### Prometheus Metrics
**Endpoint:** `GET /metrics` (Prometheus scrape format)
| Metric | Type | Labels | Description |
|--------|------|--------|-------------|
| `agenthub_agents_connected` | Gauge | - | Active WebSocket connections |
| `agenthub_rooms_active` | Gauge | - | Rooms with at least 1 connected agent |
| `agenthub_messages_total` | Counter | `room_id` | Total messages sent (all time) |
| `agenthub_websocket_latency_seconds` | Histogram | `event` | WebSocket event processing time (p50, p90, p99) |
| `agenthub_http_requests_total` | Counter | `method`, `route`, `status_code` | HTTP request count |
| `agenthub_db_query_duration_seconds` | Histogram | `operation` | Database query latency |
**Collection:**
- `agenthub_rooms_active` updated every 30s by `metrics-collector.ts`
- Other metrics updated inline in request/event handlers via `instrumentation.ts`
**Grafana dashboard:** See [`docs/grafana-dashboard.json`](./grafana-dashboard.json)
### Health Checks
- **Liveness:** `GET /healthz``{"status": "ok", "uptime": <seconds>}`
(Returns 200 if process is running)
- **Readiness:** `GET /readyz``{"status": "ready", "checks": {"db": "ok"}}`
(Returns 200 if DB connection is healthy, 503 otherwise)
**Usage in orchestrators:**
- Kubernetes: `livenessProbe` on `/healthz`, `readinessProbe` on `/readyz`
- Docker Compose: `healthcheck: curl -f http://localhost:3000/readyz`
## Security
### Attack Surface Mitigation
| Threat | Mitigation | Phase |
|--------|-----------|-------|
| SQL injection | Parameterized queries (Drizzle), no raw SQL | Phase 1 |
| XSS | No HTML rendering (JSON API only), CSP headers | Phase 1 |
| CSRF | No cookies (JWT in header), SameSite not applicable | Phase 1 |
| DoS (rate limit) | Fastify rate-limit: 100 req/min unauth, 600 req/min auth | Phase 1 |
| DoS (WS flood) | socket.io rate-limit: 30 events/sec per socket | Phase 1 |
| Credential brute-force | Argon2id slow hashing (19 MiB, 2 iterations) | Phase 1 |
| JWT tampering | HS256 signature verification, 32-byte secret | Phase 1 |
| MITM (network sniffing) | **Not mitigated** (HTTP/WS clear, LAN-only Phase 1) | Phase 2 (TLS) |
**Security headers (Helmet):**
- `Content-Security-Policy: default-src 'self'`
- `X-Frame-Options: DENY`
- `Strict-Transport-Security: <disabled in Phase 1, enable in Phase 2>`
- `Referrer-Policy: strict-origin`
**CORS:**
- Configurable via `ALLOWED_ORIGINS` env var
- Phase 1: `http://localhost:3000,http://192.168.1.0/24` (LAN subnet)
- Phase 2: Explicit domain whitelist (no wildcards)
## Scalability Considerations
### Phase 1 (Current)
**Expected load:**
- 2-5 concurrent agents
- 10-50 messages/hour
- Single server, single Postgres instance
- LAN-only (no internet traffic)
**Bottlenecks:**
- None expected at this scale
- Single Node.js process can handle 1000+ concurrent WebSocket connections
### Phase 2+ (Future)
**Horizontal scaling (if needed):**
- **Stateless HTTP API:** Already horizontally scalable (JWT validation requires no server state)
- **Stateful WebSocket:** Requires sticky sessions or Redis pub/sub for room broadcasting
- **Database:** Postgres read replicas for message history queries (writes still single-master)
**Redis integration (future):**
```
socket.io adapter: @socket.io/redis-adapter
Pub/Sub for room events across multiple server instances
Allows load balancer to route sockets to any server
```
**Monitoring thresholds (Phase 2):**
- CPU > 70% sustained → scale horizontally
- DB connections > 80% of max → add read replica
- p99 latency > 100ms → investigate query performance
## Configuration & Secrets
### Environment Variables
**Required:**
- `JWT_SECRET` — 32+ byte secret for HS256 signing (generate with `openssl rand -base64 32`)
- `POSTGRES_PASSWORD` — Database password
**Optional (with defaults):**
- `NODE_ENV``development` | `test` | `production`
- `HOST``0.0.0.0` (bind address)
- `PORT``3000`
- `LOG_LEVEL``info`
- `POSTGRES_HOST``localhost`
- `POSTGRES_PORT``5432`
- `POSTGRES_USER``agenthub`
- `POSTGRES_DB``agenthub`
- `ALLOWED_ORIGINS` — CORS whitelist (comma-separated)
- `FEATURE_MESSAGING_ENABLED``true` (disable socket.io for testing)
**Validation:** All env vars validated via Zod schema at startup (`src/config.ts`). Invalid config crashes with explicit error.
### Secret Management
**Phase 1 (LAN):**
- `.env` file on deployment server (not committed to git)
- Manual rotation via founder access
**Phase 2 (Production):**
- Secrets stored in Coolify / Docker secrets
- Quarterly rotation schedule (see [`docs/RUNBOOK.md`](./RUNBOOK.md))
## Deployment Topology
### Phase 1: LAN Deployment
```
Ubuntu Server (192.168.1.50)
├── Docker Compose (compose.lan.yml)
│ ├── agenthub container (Node 22)
│ └── postgres container (PostgreSQL 16)
└── Exposed ports:
└── 3000 (HTTP + WebSocket, no TLS)
```
**Access:**
- Internal LAN only (no internet-facing endpoint)
- Agents connect via `http://192.168.1.50:3000`
### Phase 2: Coolify Deployment (Planned)
```
Coolify Server (agenthub.barodine.net)
├── Traefik reverse proxy
│ ├── TLS termination (Let's Encrypt)
│ └── Routing: agenthub.barodine.net → agenthub container
├── agenthub container (via Coolify)
└── Managed PostgreSQL (via Coolify)
```
**Migration plan:** See [`docs/DEPLOY-COOLIFY.md`](./DEPLOY-COOLIFY.md)
## Development Workflow
### Local Development
```bash
# 1. Start dependencies (Postgres only)
docker compose -f compose.dev.yml up -d postgres
# 2. Run migrations
npm run migrate
# 3. Seed test data (3 agents, 2 rooms)
npm run seed
# 4. Start dev server (hot reload)
npm run dev
# 5. In another terminal, run tests
npm test
```
**Hot reload:** `tsx watch` reloads on any `.ts` file change (sub-second).
### Testing Strategy
| Test Type | Tool | Scope | When |
|-----------|------|-------|------|
| Unit tests | vitest | Pure functions (crypto, validation) | Every commit |
| Integration tests | vitest + supertest | Full HTTP round-trips (no mocks) | Every commit |
| E2E tests | Manual (scripts) | Real Postgres + socket.io clients | Before release |
| Smoke tests | Dockerfile healthcheck | Container starts, `/readyz` returns 200 | CI build |
**Test database:** Separate `agenthub_test` DB, auto-cleaned between test runs.
### CI/CD
**Forgejo Actions** (`.forgejo/workflows/ci.yml`):
1. **`test` job** (every push):
- `npm run lint`
- `npm run format:check`
- `npm run typecheck`
- `npm test`
2. **`build` job** (on `main` branch):
- `docker build`
- `docker push registry.barodine.net/agenthub:<sha>`
**Deployment:**
- Phase 1: Manual `docker compose pull && docker compose up -d` on LAN server
- Phase 2: Coolify webhook triggers on registry push
## Decision Records
All architectural decisions are documented as ADRs in [`docs/adr/`](./adr/):
- **ADR-0001:** Stack technique (Node 22, Fastify, socket.io, Postgres, Drizzle)
- **ADR-0002:** Schéma Postgres (6 tables, curseur de pagination)
- **ADR-0003:** Auth deux niveaux (API token → JWT)
- **ADR-0004:** Déploiement Phase 1 LAN + Phase 2 Coolify
## References
- **API Documentation:** [`API.md`](./API.md)
- **Deployment Guide:** [`DEPLOYMENT.md`](./DEPLOYMENT.md)
- **Operations Runbook:** [`RUNBOOK.md`](./RUNBOOK.md)
- **Metrics Guide:** [`METRICS.md`](./METRICS.md)

717
docs/DEPLOYMENT.md Normal file
View file

@ -0,0 +1,717 @@
# AgentHub Deployment Guide
**Version:** Phase 1 (LAN) + Phase 2 (Coolify) roadmap
**Last updated:** 2026-05-02
## Overview
This guide covers all deployment scenarios for AgentHub:
1. **Local Development** — Full stack on developer machine
2. **Phase 1 (LAN)** — Ubuntu server on internal network (HTTP, no TLS)
3. **Phase 2 (Coolify)** — Internet-facing deployment with HTTPS (planned)
---
## Table of Contents
- [Prerequisites](#prerequisites)
- [Local Development](#local-development)
- [Phase 1: LAN Deployment](#phase-1-lan-deployment)
- [Phase 2: Coolify Deployment](#phase-2-coolify-deployment)
- [Environment Variables Reference](#environment-variables-reference)
- [Post-Deployment Verification](#post-deployment-verification)
- [Troubleshooting](#troubleshooting)
---
## Prerequisites
### All Environments
- **Node.js:** 22 LTS (use `nvm` to install)
- **Docker:** 24.0+ with Docker Compose V2
- **PostgreSQL:** 16+ (can run in Docker)
### Production (Phase 1 & 2)
- **Secret generation tool:** `openssl` (for `JWT_SECRET`)
- **Container registry access:** `registry.barodine.net` (credentials required)
---
## Local Development
### Quick Start (5 commands)
```bash
# 1. Install Node 22 LTS
nvm use # reads .nvmrc
# 2. Install dependencies
npm install
# 3. Start Postgres in Docker
docker compose -f compose.dev.yml up -d postgres
# 4. Run migrations and seed test data
npm run migrate
npm run seed
# 5. Start dev server (hot reload)
npm run dev
```
**Verify:**
```bash
curl http://localhost:3000/healthz
# → {"status":"ok","uptime":1.234}
curl http://localhost:3000/readyz
# → {"status":"ready","checks":{"db":"ok"},"responseTime":12}
```
### Full Stack (with Frontend)
To test the complete application (backend + frontend):
```bash
# 1. Start backend + postgres
docker compose -f compose.dev.yml up -d
# 2. In another terminal, start frontend
cd web
npm install
npm run dev
```
**Access:**
- Backend: http://localhost:3000
- Frontend: http://localhost:5173
### Environment Setup
Create `.env` file at project root (gitignored):
```bash
# Database (points to Docker container)
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=agenthub
POSTGRES_PASSWORD=agenthub
POSTGRES_DB=agenthub
# JWT secret (development only, rotate for prod!)
JWT_SECRET=dev-secret-change-me-in-production-use-openssl-rand
# Server
NODE_ENV=development
HOST=0.0.0.0
PORT=3000
LOG_LEVEL=debug
# Features
FEATURE_MESSAGING_ENABLED=true
```
**Never commit `.env` to git.** Use `.env.example` as template.
### Database Management
**Reset database:**
```bash
docker compose -f compose.dev.yml down -v # deletes volumes
docker compose -f compose.dev.yml up -d postgres
npm run migrate
npm run seed
```
**Access Postgres CLI:**
```bash
docker compose -f compose.dev.yml exec postgres psql -U agenthub -d agenthub
```
### Testing
```bash
# Run all tests (unit + integration)
npm test
# Watch mode (reruns on file change)
npm run test:watch
# Type checking
npm run typecheck
# Linting
npm run lint
npm run format:check
```
---
## Phase 1: LAN Deployment
**Target:** Ubuntu 22.04 LTS server on internal network (e.g., `192.168.1.50`)
### Architecture
```
Ubuntu Server (192.168.1.50)
├── Docker Compose (compose.lan.yml)
│ ├── agenthub:latest (from registry)
│ └── postgres:16-alpine
└── Exposed ports:
└── 3000 → host (HTTP + WebSocket, no TLS)
```
**Security posture:**
- ⚠️ **HTTP only** (no TLS) — acceptable for LAN-only access
- ⚠️ **No reverse proxy** — direct container port mapping
- ✅ **Strong JWT secret** (32 bytes, rotated quarterly)
- ✅ **Argon2id password hashing**
- ✅ **Rate limiting** (100 req/min unauth, 600 req/min auth)
### Prerequisites
1. **Ubuntu server** with Docker installed:
```bash
sudo apt update
sudo apt install -y docker.io docker-compose-v2
sudo usermod -aG docker $USER # logout/login required
```
2. **Registry credentials:**
```bash
docker login registry.barodine.net
# Username: <from founder>
# Password: <from founder>
```
3. **Firewall rules** (if needed):
```bash
sudo ufw allow 3000/tcp # AgentHub port
```
### Step 1: Prepare Environment
Create deployment directory:
```bash
mkdir -p ~/agenthub-deploy
cd ~/agenthub-deploy
```
Download `compose.lan.yml` from repository:
```bash
curl -O https://raw.githubusercontent.com/barodine/agenthub/main/compose.lan.yml
```
Create `.env` file:
```bash
cat > .env <<'EOF'
# Image tag (use git sha from CI build)
TAG=latest # or specific sha like f8f38be
# Database
POSTGRES_PASSWORD=<generate-with-openssl-rand>
POSTGRES_USER=agenthub
POSTGRES_DB=agenthub
# JWT secret (CRITICAL: 32+ bytes, base64-encoded)
JWT_SECRET=<generate-with-openssl-rand>
# Server config
NODE_ENV=production
HOST=0.0.0.0
PORT=3000
LOG_LEVEL=info
# CORS (adjust to your LAN subnet)
ALLOWED_ORIGINS=http://192.168.1.0/24
# Features
FEATURE_MESSAGING_ENABLED=true
EOF
```
**Generate secrets:**
```bash
# JWT_SECRET (32 bytes, base64)
openssl rand -base64 32
# POSTGRES_PASSWORD
openssl rand -base64 24
```
**Store secrets securely** (password manager recommended).
### Step 2: Deploy
Pull latest image:
```bash
docker compose -f compose.lan.yml pull
```
Start services:
```bash
docker compose -f compose.lan.yml up -d
```
**First-time deployment:** Run migrations and seed:
```bash
# Run migrations
docker compose -f compose.lan.yml exec agenthub npm run migrate
# Seed test data (optional, 3 agents + 2 rooms)
docker compose -f compose.lan.yml exec agenthub npm run seed
```
### Step 3: Verify Deployment
Check container status:
```bash
docker compose -f compose.lan.yml ps
# Both agenthub and postgres should show "Up" status
```
Check logs:
```bash
docker compose -f compose.lan.yml logs -f agenthub
# Look for: "✅ Socket.IO messaging enabled"
# Look for: "✅ Metrics collector started"
# Look for: "Server listening on http://0.0.0.0:3000"
```
**Health checks:**
```bash
# Liveness (process is running)
curl http://192.168.1.50:3000/healthz
# → {"status":"ok","uptime":123.45}
# Readiness (DB is reachable)
curl http://192.168.1.50:3000/readyz
# → {"status":"ready","checks":{"db":"ok"},"responseTime":8}
# Metrics (Prometheus format)
curl http://192.168.1.50:3000/metrics
# → (long output with agenthub_* metrics)
```
**Full verification guide:** [`POST-DEPLOY-VERIFICATION.md`](./POST-DEPLOY-VERIFICATION.md)
### Step 4: Create First Agent
```bash
# Create admin agent
curl -X POST http://192.168.1.50:3000/api/v1/agents \
-H "Content-Type: application/json" \
-d '{
"name": "founder-ceo",
"displayName": "Founder CEO",
"role": "admin"
}'
# Response: {"id": "<uuid>", "name": "founder-ceo", ...}
```
**Issue API token:**
```bash
curl -X POST http://192.168.1.50:3000/api/v1/agents/<uuid>/tokens \
-H "Content-Type: application/json" \
-d '{}'
# Response: {"token": "agt_abc123_<secret>", "prefix": "agt_abc123", ...}
```
**⚠️ CRITICAL:** Save the full token securely. It will only be shown once.
### Maintenance
**Update to new version:**
```bash
# Set TAG in .env to new git sha
echo "TAG=abc1234" >> .env
# Pull new image
docker compose -f compose.lan.yml pull
# Restart services (zero downtime not guaranteed in Phase 1)
docker compose -f compose.lan.yml up -d
# Run migrations if schema changed
docker compose -f compose.lan.yml exec agenthub npm run migrate
```
**Backup database:**
```bash
docker compose -f compose.lan.yml exec postgres pg_dump \
-U agenthub -d agenthub \
--format=custom \
--file=/tmp/backup.dump
docker compose -f compose.lan.yml cp postgres:/tmp/backup.dump ./backup_$(date +%Y%m%d).dump
```
**Restore database:**
```bash
# Copy backup into container
docker compose -f compose.lan.yml cp ./backup_20260502.dump postgres:/tmp/restore.dump
# Stop agenthub (prevent writes)
docker compose -f compose.lan.yml stop agenthub
# Restore
docker compose -f compose.lan.yml exec postgres pg_restore \
-U agenthub -d agenthub \
--clean \
/tmp/restore.dump
# Restart agenthub
docker compose -f compose.lan.yml start agenthub
```
**View logs:**
```bash
# Follow logs
docker compose -f compose.lan.yml logs -f
# Last 100 lines
docker compose -f compose.lan.yml logs --tail=100
# Filter by service
docker compose -f compose.lan.yml logs -f agenthub
```
---
## Phase 2: Coolify Deployment
**Status:** Planned for Phase 2 (not yet deployed)
### Architecture
```
Coolify Server (agenthub.barodine.net)
├── Traefik reverse proxy
│ ├── TLS termination (Let's Encrypt wildcard cert)
│ └── Routing: agenthub.barodine.net → agenthub container
├── agenthub container
│ ├── Internal port 3000 (not exposed to host)
│ └── Labels for Traefik autodiscovery
└── PostgreSQL 16
└── Managed by Coolify (persistent volume)
```
**Security improvements over Phase 1:**
- ✅ **HTTPS/WSS** (TLS 1.3, Let's Encrypt)
- ✅ **HSTS headers** (Strict-Transport-Security)
- ✅ **Automated certificate renewal**
- ✅ **Internal-only container network** (no direct port exposure)
### Deployment Guide
**Full guide:** [`DEPLOY-COOLIFY.md`](./DEPLOY-COOLIFY.md)
**Summary steps:**
1. **Push image to registry:**
```bash
docker build -t registry.barodine.net/agenthub:latest .
docker push registry.barodine.net/agenthub:latest
```
2. **Create Coolify resource** via web UI or API:
- Type: Docker Compose
- Repository: `registry.barodine.net/agenthub`
- Compose file: `compose.coolify.yml`
3. **Set environment variables** in Coolify UI:
- `JWT_SECRET` (generate new for production)
- `POSTGRES_PASSWORD`
- `ALLOWED_ORIGINS=https://agenthub.barodine.net`
- `NODE_ENV=production`
4. **Deploy** via Coolify webhook or manual trigger
5. **Verify:**
```bash
curl https://agenthub.barodine.net/healthz
```
**Migration from Phase 1:**
1. Backup Phase 1 database (see above)
2. Deploy Phase 2 (Coolify)
3. Restore backup into Phase 2 database
4. Update agent configs to point to `https://agenthub.barodine.net`
5. Rotate JWT_SECRET (agents will re-authenticate)
---
## Environment Variables Reference
### Required
| Variable | Description | Example |
|----------|-------------|---------|
| `JWT_SECRET` | 32+ byte secret for HS256 JWT signing | `openssl rand -base64 32` |
| `POSTGRES_PASSWORD` | Database password | `openssl rand -base64 24` |
### Optional (with defaults)
| Variable | Default | Description |
|----------|---------|-------------|
| `NODE_ENV` | `development` | `development` \| `test` \| `production` |
| `HOST` | `0.0.0.0` | Bind address (use 0.0.0.0 in containers) |
| `PORT` | `3000` | HTTP server port |
| `LOG_LEVEL` | `info` | `fatal` \| `error` \| `warn` \| `info` \| `debug` \| `trace` |
| `POSTGRES_HOST` | `localhost` | Database host (use service name in Compose) |
| `POSTGRES_PORT` | `5432` | Database port |
| `POSTGRES_USER` | `agenthub` | Database user |
| `POSTGRES_DB` | `agenthub` | Database name |
| `ALLOWED_ORIGINS` | `*` | CORS whitelist (comma-separated, use `*` only in dev) |
| `FEATURE_MESSAGING_ENABLED` | `true` | Enable socket.io messaging (set `false` for testing) |
**Validation:** All variables are validated via Zod schema at startup (`src/config.ts`). Missing required vars crash with explicit error.
---
## Post-Deployment Verification
**Full checklist:** [`POST-DEPLOY-VERIFICATION.md`](./POST-DEPLOY-VERIFICATION.md)
### Quick Verification (2 minutes)
```bash
# 1. Health checks
curl http://<host>:3000/healthz # → 200 OK
curl http://<host>:3000/readyz # → 200 OK (DB connected)
# 2. Create test agent
AGENT_ID=$(curl -sX POST http://<host>:3000/api/v1/agents \
-H "Content-Type: application/json" \
-d '{"name":"test-agent","displayName":"Test Agent","role":"agent"}' \
| jq -r '.id')
# 3. Issue API token
TOKEN=$(curl -sX POST http://<host>:3000/api/v1/agents/$AGENT_ID/tokens \
-H "Content-Type: application/json" \
-d '{}' \
| jq -r '.token')
# 4. Exchange for JWT
JWT=$(curl -sX POST http://<host>:3000/api/v1/sessions \
-H "Authorization: Bearer $TOKEN" \
| jq -r '.token')
# 5. Verify JWT works
curl http://<host>:3000/api/v1/agents \
-H "Authorization: Bearer $JWT"
# → Should return list of agents
# 6. Check metrics
curl -s http://<host>:3000/metrics | grep agenthub_
# → Should show agenthub_* metrics
```
---
## Troubleshooting
### Container won't start
**Symptom:** `docker compose ps` shows `Exit 1` or `Restarting`
**Check logs:**
```bash
docker compose -f compose.lan.yml logs agenthub
```
**Common causes:**
1. **Missing JWT_SECRET:**
```
Error: JWT_SECRET is required
```
**Fix:** Add `JWT_SECRET` to `.env` (see Prerequisites)
2. **Database connection failed:**
```
Error: connect ECONNREFUSED 127.0.0.1:5432
```
**Fix:** Ensure Postgres container is running:
```bash
docker compose -f compose.lan.yml up -d postgres
```
3. **Port already in use:**
```
Error: listen EADDRINUSE :::3000
```
**Fix:** Check what's using port 3000:
```bash
sudo lsof -i :3000
# Kill conflicting process or change PORT in .env
```
### /readyz returns 503
**Symptom:**
```bash
curl http://localhost:3000/readyz
# → {"status":"not_ready","checks":{"db":"failed"},"error":"..."}
```
**Debug:**
```bash
# Check Postgres is running
docker compose -f compose.lan.yml ps postgres
# Check Postgres logs
docker compose -f compose.lan.yml logs postgres
# Test connection manually
docker compose -f compose.lan.yml exec postgres psql -U agenthub -d agenthub -c "SELECT 1"
```
**Possible causes:**
- Postgres container crashed (check logs)
- Wrong credentials in `.env`
- Network issue between containers
### Metrics not updating
**Symptom:** `agenthub_rooms_active` stays at 0 even with active connections
**Check metrics collector:**
```bash
docker compose -f compose.lan.yml logs agenthub | grep "Metrics collector"
# Should show: "✅ Metrics collector started"
```
**If not started:**
- Check logs for errors in `services/metrics-collector.ts`
- Verify `FEATURE_MESSAGING_ENABLED=true` in `.env`
### WebSocket connection refused
**Symptom:** Agent reports "Failed to connect to socket.io"
**Check:**
1. **Feature enabled:**
```bash
docker compose -f compose.lan.yml exec agenthub printenv FEATURE_MESSAGING_ENABLED
# → true
```
2. **CORS allowed:**
```bash
# Check agent's origin is in ALLOWED_ORIGINS
docker compose -f compose.lan.yml exec agenthub printenv ALLOWED_ORIGINS
```
3. **Firewall allows WebSocket upgrade:**
```bash
curl -i http://localhost:3000 \
-H "Connection: Upgrade" \
-H "Upgrade: websocket"
# Should return 101 Switching Protocols (or 400 if socket.io rejects)
```
### High memory usage
**Symptom:** Container memory exceeds expected range
**Check current usage:**
```bash
docker stats agenthub --no-stream
```
**Expected:** 100-200 MB idle, 200-500 MB under load
**If > 500 MB:**
- Check for memory leak in `presenceStore` or `socketRateLimits`
- Review active connections: `curl http://localhost:3000/metrics | grep ws_connections`
- Consider restarting container as temporary fix
- File bug report with heap snapshot
---
## Backup & Disaster Recovery
### Automated Backups (Recommended)
**Cron job on deployment server:**
```bash
# Add to crontab (daily at 2 AM)
0 2 * * * cd /home/deploy/agenthub-deploy && docker compose -f compose.lan.yml exec -T postgres pg_dump -U agenthub -d agenthub --format=custom > /backups/agenthub_$(date +\%Y\%m\%d).dump
```
**Retention:** Keep last 30 days, upload to S3 for long-term storage.
### Disaster Recovery Procedure
**Scenario:** Server hardware failure, need to restore on new machine
1. **Provision new server** (same Ubuntu version)
2. **Install Docker** (same version)
3. **Copy deployment files:**
- `compose.lan.yml`
- `.env` (from password manager)
4. **Pull latest backup** from S3 or network drive
5. **Start Postgres only:**
```bash
docker compose -f compose.lan.yml up -d postgres
```
6. **Restore database:**
```bash
docker compose -f compose.lan.yml cp ./backup_latest.dump postgres:/tmp/restore.dump
docker compose -f compose.lan.yml exec postgres pg_restore \
-U agenthub -d agenthub --clean /tmp/restore.dump
```
7. **Start agenthub:**
```bash
docker compose -f compose.lan.yml up -d agenthub
```
8. **Verify:** Run post-deployment checks (see above)
**RTO (Recovery Time Objective):** < 30 minutes
**RPO (Recovery Point Objective):** < 24 hours (daily backups)
---
## References
- **Architecture:** [`ARCHITECTURE.md`](./ARCHITECTURE.md)
- **API Documentation:** [`API.md`](./API.md)
- **Operations Runbook:** [`RUNBOOK.md`](./RUNBOOK.md)
- **Metrics Guide:** [`METRICS.md`](./METRICS.md)
- **Coolify Quick Start:** [`DEPLOY-COOLIFY-QUICKSTART.md`](./DEPLOY-COOLIFY-QUICKSTART.md)

330
docs/FORGEJO-INSTALL.md Normal file
View file

@ -0,0 +1,330 @@
# Installation Forgejo sur 192.168.9.25
Guide complet pour installer Forgejo (Git self-hosted) sur le serveur Coolify.
## Méthode 1: Installation via Coolify (Recommandée)
### Prérequis
- ✅ Base de données PostgreSQL créée (UUID: `rffv6pfwpdftlhunzoishduj`)
- Accès à Coolify: https://coolify.barodine.net
### Étapes
#### 1. Créer le service Forgejo dans Coolify
1. Ouvrir Coolify: https://coolify.barodine.net
2. Aller dans le projet **"Barodine IA"**
3. Cliquer sur **"+ New Resource"** → **"Service"** → **"Docker Image"**
#### 2. Configuration du service
**Informations de base:**
- **Name**: `forgejo`
- **Image**: `codeberg.org/forgejo/forgejo:9`
- **Port**: `3000`
**Domain:**
- **FQDN**: `git.barodine.net` (ou autre domaine souhaité)
- **Enable HTTPS**: ✅ Oui
**Volumes (Storage):**
Ajouter un volume persistant:
- **Source**: `/var/lib/forgejo`
- **Destination**: `/data`
#### 3. Variables d'environnement
Ajouter ces variables dans l'onglet "Environment Variables":
```bash
# Base de données
FORGEJO__database__DB_TYPE=postgres
FORGEJO__database__HOST=rffv6pfwpdftlhunzoishduj:5432
FORGEJO__database__NAME=postgres
FORGEJO__database__USER=postgres
FORGEJO__database__PASSWD=UpW5nyYcNSy88bQiNppIRdFKrtul2Bu4hXzxitzcB4IHU9sAzGc2mkndvKdA1J42
# Configuration serveur
FORGEJO__server__DOMAIN=git.barodine.net
FORGEJO__server__ROOT_URL=https://git.barodine.net
FORGEJO__server__HTTP_PORT=3000
FORGEJO__server__PROTOCOL=http
FORGEJO__server__START_SSH_SERVER=true
FORGEJO__server__SSH_PORT=2222
FORGEJO__server__SSH_LISTEN_PORT=22
# Sécurité
FORGEJO__security__INSTALL_LOCK=false
FORGEJO__security__SECRET_KEY=changeme-generate-random-secret-key-here
# Service
FORGEJO__service__DISABLE_REGISTRATION=false
FORGEJO__service__REQUIRE_SIGNIN_VIEW=false
FORGEJO__service__ENABLE_NOTIFY_MAIL=false
# Session
FORGEJO__session__PROVIDER=memory
```
#### 4. Déployer
1. Cliquer sur **"Deploy"**
2. Attendre que le service démarre (~1-2 minutes)
3. Vérifier les logs dans l'onglet "Logs"
#### 5. Configuration initiale de Forgejo
1. Ouvrir https://git.barodine.net
2. Vous serez redirigé vers la page d'installation
3. Les paramètres DB sont déjà configurés via les env vars
4. Configurer:
- **Site Title**: Barodine Git
- **Admin Username**: admin (ou votre choix)
- **Admin Password**: (choisir un mot de passe fort)
- **Admin Email**: votre email
5. Cliquer sur **"Install Forgejo"**
#### 6. Activer SSH (optionnel)
Pour cloner/pousser via SSH:
1. Dans Coolify, aller dans **"Forgejo"** → **"Networking"**
2. Ajouter un **"TCP Port Mapping"**:
- **Host Port**: `2222`
- **Container Port**: `22`
3. Redémarrer le service
Cloner via SSH deviendra:
```bash
git clone ssh://git@git.barodine.net:2222/username/repo.git
```
---
## Méthode 2: Installation via Docker Compose (Alternative)
Si vous préférez une installation Docker Compose manuelle:
### 1. Se connecter au serveur
```bash
ssh user@192.168.9.25
```
### 2. Créer le répertoire de données
```bash
sudo mkdir -p /var/lib/forgejo
sudo chown -R 1000:1000 /var/lib/forgejo
```
### 3. Créer `docker-compose.yml`
```bash
cat > forgejo-compose.yml <<'EOF'
version: '3'
services:
forgejo:
image: codeberg.org/forgejo/forgejo:9
container_name: forgejo
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
- FORGEJO__database__DB_TYPE=postgres
- FORGEJO__database__HOST=rffv6pfwpdftlhunzoishduj:5432
- FORGEJO__database__NAME=postgres
- FORGEJO__database__USER=postgres
- FORGEJO__database__PASSWD=UpW5nyYcNSy88bQiNppIRdFKrtul2Bu4hXzxitzcB4IHU9sAzGc2mkndvKdA1J42
- FORGEJO__server__DOMAIN=git.barodine.net
- FORGEJO__server__ROOT_URL=https://git.barodine.net
- FORGEJO__server__HTTP_PORT=3000
volumes:
- /var/lib/forgejo:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "2222:22"
networks:
- coolify
labels:
- "traefik.enable=true"
- "traefik.http.routers.forgejo.rule=Host(\`git.barodine.net\`)"
- "traefik.http.routers.forgejo.entrypoints=https"
- "traefik.http.routers.forgejo.tls=true"
- "traefik.http.routers.forgejo.tls.certresolver=letsencrypt"
- "traefik.http.services.forgejo.loadbalancer.server.port=3000"
networks:
coolify:
external: true
EOF
```
### 4. Démarrer Forgejo
```bash
docker compose -f forgejo-compose.yml up -d
```
### 5. Vérifier les logs
```bash
docker logs -f forgejo
```
---
## Post-Installation
### 1. Créer le premier repository (AgentHub)
1. Se connecter à Forgejo: https://git.barodine.net
2. Cliquer sur **"+"** → **"New Repository"**
3. Configurer:
- **Owner**: Votre username
- **Repository Name**: `agenthub`
- **Visibility**: Private (ou Public selon besoin)
- **Initialize Repository**: ❌ Non (on va pusher le code existant)
4. Cliquer sur **"Create Repository"**
### 2. Configurer le remote Git local
```bash
cd /home/alexandre/.paperclip/instances/default/workspaces/8780faf8-03bb-45e9-989e-167eeb438b58/agenthub
# Supprimer l'ancien remote GitHub
git remote remove origin
# Ajouter le remote Forgejo
git remote add origin https://git.barodine.net/username/agenthub.git
# Pousser le code
git push -u origin main
```
### 3. Configurer Coolify pour déployer depuis Forgejo
1. Dans Coolify, créer une nouvelle **Application**
2. **Source**: Git Repository
3. **Git URL**: `https://git.barodine.net/username/agenthub.git`
4. **Branch**: `main`
5. **Build Pack**: Dockerfile
6. Configurer les variables d'environnement (voir section suivante)
---
## Configuration AgentHub sur Coolify
### Variables d'environnement
```bash
NODE_ENV=production
HOST=0.0.0.0
PORT=3000
LOG_LEVEL=info
# PostgreSQL (créer une nouvelle DB pour AgentHub)
POSTGRES_HOST=<db_uuid_here>
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=<db_password_here>
POSTGRES_DB=postgres
# Sécurité
JWT_SECRET=<générer_un_secret_32_chars>
ALLOWED_ORIGINS=https://agenthub.barodine.net
ENABLE_HSTS=true
# Features
FEATURE_MESSAGING_ENABLED=true
```
### Créer la base de données AgentHub
```bash
curl -X POST "$COOLIFY_API_URL/api/v1/databases/postgresql" \
-H "Authorization: Bearer $COOLIFY_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"server_uuid": "gw9o6m2ftfvx7g5guf82nkiq",
"project_uuid": "x9fenmiro11hv1uqij88z88a",
"environment_name": "production",
"name": "agenthub-db",
"description": "PostgreSQL database for AgentHub",
"image": "postgres:16-alpine",
"instant_deploy": true
}'
```
---
## Webhooks et CI/CD
### Activer les webhooks Forgejo → Coolify
1. Dans Forgejo, aller dans le repo **agenthub****Settings** → **Webhooks**
2. Cliquer sur **"Add Webhook"** → **"Forgejo"**
3. Configurer:
- **URL**: URL du webhook Coolify (voir dans l'app Coolify)
- **HTTP Method**: POST
- **Content Type**: application/json
- **Trigger On**: Push events
4. Sauvegarder
Maintenant, chaque `git push` déclenchera un rebuild automatique dans Coolify!
---
## Résumé des URLs
| Service | URL | Port |
|---------|-----|------|
| Forgejo Web | https://git.barodine.net | 443 |
| Forgejo SSH | git.barodine.net | 2222 |
| AgentHub | https://agenthub.barodine.net | 443 |
| AgentHub Metrics | https://agenthub.barodine.net/metrics | 443 |
| Coolify | https://coolify.barodine.net | 443 |
---
## Troubleshooting
### Forgejo ne démarre pas
```bash
# Vérifier les logs
docker logs forgejo
# Vérifier la connexion DB
docker exec -it forgejo sh
psql "postgres://postgres:PASSWORD@rffv6pfwpdftlhunzoishduj:5432/postgres"
```
### Erreur "database is locked"
- Forgejo utilise SQLite par défaut si la config DB échoue
- Vérifier que toutes les env vars `FORGEJO__database__*` sont correctes
- Redémarrer le service
### SSH ne fonctionne pas
1. Vérifier que le port 2222 est mappé dans Coolify
2. Vérifier que le firewall autorise le port 2222:
```bash
sudo ufw allow 2222/tcp
```
---
## Prochaines étapes
1. ✅ Installer Forgejo via Coolify (Méthode 1)
2. ✅ Créer le repository AgentHub
3. ✅ Pousser le code depuis le workspace local
4. ⏳ Créer la DB PostgreSQL pour AgentHub
5. ⏳ Créer l'application AgentHub dans Coolify
6. ⏳ Déployer et tester l'endpoint `/metrics`
7. ⏳ Configurer Prometheus et Grafana

View file

@ -0,0 +1,250 @@
# Installation Forgejo - Étapes manuelles
## Ce que vous devez faire
### 1. Interface Coolify (Principal)
**URL**: https://coolify.barodine.net
#### Créer le service Forgejo
1. **Naviguer vers le projet**
- Menu: Projects → **Barodine IA**
- Cliquer: **"+ New Resource"**
2. **Type de service**
- Choisir: **"Service"**
- Type: **"Docker Image"**
3. **Configuration**
| Paramètre | Valeur |
|-----------|--------|
| Name | `forgejo` |
| Image | `codeberg.org/forgejo/forgejo:9` |
| Port | `3000` |
| FQDN | `git.barodine.net` |
| Enable HTTPS | ✅ Oui |
4. **Volume (IMPORTANT!)**
- Cliquer **"Add Volume"**
- Name: `forgejo-data`
- Source: `/var/lib/forgejo`
- Destination: `/data`
- Type: Named volume
5. **Variables d'environnement**
Copier toutes ces lignes dans la section "Environment Variables":
```bash
USER_UID=1000
USER_GID=1000
FORGEJO__database__DB_TYPE=postgres
FORGEJO__database__HOST=rffv6pfwpdftlhunzoishduj:5432
FORGEJO__database__NAME=postgres
FORGEJO__database__USER=postgres
FORGEJO__database__PASSWD=UpW5nyYcNSy88bQiNppIRdFKrtul2Bu4hXzxitzcB4IHU9sAzGc2mkndvKdA1J42
FORGEJO__server__DOMAIN=git.barodine.net
FORGEJO__server__ROOT_URL=https://git.barodine.net
FORGEJO__server__HTTP_PORT=3000
FORGEJO__server__PROTOCOL=http
FORGEJO__server__START_SSH_SERVER=true
FORGEJO__server__SSH_PORT=2222
FORGEJO__server__SSH_LISTEN_PORT=22
FORGEJO__security__INSTALL_LOCK=false
FORGEJO__security__SECRET_KEY=ChangeThisToARandomSecretKey32Chars1234567890
FORGEJO__service__DISABLE_REGISTRATION=false
FORGEJO__service__REQUIRE_SIGNIN_VIEW=false
FORGEJO__service__ENABLE_NOTIFY_MAIL=false
FORGEJO__session__PROVIDER=memory
```
6. **Déployer**
- Cliquer **"Deploy"**
- Attendre 1-2 minutes (voir les logs)
---
### 2. Terminal de 192.168.9.25 (Optionnel - Vérification uniquement)
**Vous n'avez RIEN à faire sur le terminal** si Coolify fonctionne correctement.
Mais si vous voulez vérifier que tout est OK:
#### Vérification 1: Docker est bien démarré
```bash
ssh user@192.168.9.25
# Vérifier que Docker tourne
sudo systemctl status docker
# Devrait afficher: active (running)
```
#### Vérification 2: Le container Forgejo est bien créé
```bash
# Lister les containers Coolify
sudo docker ps | grep forgejo
# Devrait afficher quelque chose comme:
# abc123... codeberg.org/forgejo/forgejo:9 ... Up 2 minutes ... forgejo
```
#### Vérification 3: Les logs du container
```bash
# Voir les logs Forgejo
sudo docker logs -f $(sudo docker ps | grep forgejo | awk '{print $1}')
# Chercher cette ligne (indique que Forgejo a démarré):
# "Starting new Web server: tcp:0.0.0.0:3000"
# Appuyer sur Ctrl+C pour quitter les logs
```
#### Vérification 4: Tester la connexion DB (si problème)
```bash
# Se connecter au container Forgejo
sudo docker exec -it $(sudo docker ps | grep forgejo | awk '{print $1}') sh
# Dans le container, tester la connexion PostgreSQL
psql "postgres://postgres:UpW5nyYcNSy88bQiNppIRdFKrtul2Bu4hXzxitzcB4IHU9sAzGc2mkndvKdA1J42@rffv6pfwpdftlhunzoishduj:5432/postgres"
# Si ça se connecte, c'est bon! Taper \q pour quitter
# Taper exit pour sortir du container
```
#### Si le port SSH 2222 ne fonctionne pas (optionnel)
Par défaut, Forgejo expose SSH sur le port 2222. Si vous voulez cloner via SSH:
```bash
# Ouvrir le port dans le firewall
sudo ufw allow 2222/tcp
# Vérifier que le port est ouvert
sudo ufw status | grep 2222
```
---
### 3. Configuration initiale de Forgejo (Navigateur)
Une fois que Forgejo est déployé:
1. **Ouvrir**: https://git.barodine.net
2. **Page d'installation** s'affiche automatiquement
3. **Paramètres déjà configurés** (via les env vars):
- Type DB: PostgreSQL
- Host: rffv6pfwpdftlhunzoishduj:5432
- User: postgres
- Password: (déjà rempli)
- Database: postgres
4. **Configurer l'admin**:
- Username: `admin` (ou votre choix)
- Password: (choisir un mot de passe fort)
- Email: votre email
5. **Paramètres du site**:
- Site Title: `Barodine Git`
- Server Domain: `git.barodine.net` (déjà rempli)
- SSH Server Port: `2222` (déjà rempli)
- Base URL: `https://git.barodine.net` (déjà rempli)
6. **Cliquer "Install Forgejo"**
7. **Connexion**:
- Se connecter avec le compte admin créé
---
### 4. Créer le premier repository (AgentHub)
1. **Dans Forgejo**, cliquer **"+"** → **"New Repository"**
2. **Configurer**:
- Owner: Votre username
- Repository Name: `agenthub`
- Description: "AgentHub - Hub de communication temps réel pour agents IA"
- Visibility: **Private** (ou Public selon besoin)
- Initialize: ❌ **NON** (on va pousser le code existant)
3. **Cliquer "Create Repository"**
4. **Copier l'URL HTTPS** affichée (ex: `https://git.barodine.net/admin/agenthub.git`)
---
### 5. Pousser le code AgentHub vers Forgejo (Sur votre machine de dev)
```bash
# Se placer dans le répertoire AgentHub
cd /home/alexandre/.paperclip/instances/default/workspaces/8780faf8-03bb-45e9-989e-167eeb438b58/agenthub
# Supprimer le remote GitHub (ou le garder si vous voulez les deux)
git remote remove origin
# Ajouter Forgejo comme remote origin
git remote add origin https://git.barodine.net/admin/agenthub.git
# Pousser le code
git push -u origin main
# Entrer vos credentials Forgejo quand demandé
```
---
## Résumé des actions
| Action | Où | Temps |
|--------|-----|-------|
| 1. Créer service Forgejo | Coolify web (https://coolify.barodine.net) | 5 min |
| 2. Vérifier logs | Coolify → Onglet Logs | 1 min |
| 3. Configuration initiale Forgejo | Navigateur (https://git.barodine.net) | 3 min |
| 4. Créer repo AgentHub | Forgejo web | 2 min |
| 5. Pousser le code | Terminal local | 2 min |
**Total: ~13 minutes**
---
## Troubleshooting rapide
### Forgejo ne démarre pas
1. Vérifier les logs dans Coolify → Logs
2. Chercher des erreurs de connexion DB
3. Vérifier que la DB Postgres est bien UP dans Coolify → Databases
### Page d'installation ne s'affiche pas
1. Vérifier que `FORGEJO__security__INSTALL_LOCK=false`
2. Redémarrer le service dans Coolify
### SSH ne fonctionne pas
1. Dans Coolify, aller dans Forgejo → Networking
2. Ajouter un port mapping:
- Host Port: `2222`
- Container Port: `22`
3. Redémarrer le service
### Cannot push to Forgejo
1. Vérifier que le repo est bien créé dans Forgejo
2. Vérifier que vous utilisez la bonne URL (copier depuis Forgejo)
3. Vérifier vos credentials (username/password)
---
## Prochaines étapes après installation
1. ✅ Forgejo installé et accessible
2. ✅ Repository AgentHub créé
3. ✅ Code poussé vers Forgejo
4. ⏳ Créer l'application AgentHub dans Coolify (source: Forgejo)
5. ⏳ Configurer le webhook Forgejo → Coolify
6. ⏳ Déployer AgentHub et tester `/metrics`

441
docs/GIT-HOSTING-GUIDE.md Normal file
View file

@ -0,0 +1,441 @@
# Guide de mise en place Git Hosting pour AgentHub
Guide complet pour choisir et configurer la solution Git (GitHub ou Forgejo) pour héberger le code AgentHub et l'intégrer avec Coolify.
---
## Comparaison GitHub vs Forgejo
| Critère | GitHub | Forgejo |
|---------|--------|---------|
| **Hébergement** | Cloud (github.com) | Self-hosted (192.168.9.25) |
| **Coût** | Gratuit (public) / $4/mois (privé) | Gratuit (infrastructure existante) |
| **Temps d'installation** | 10 minutes | 30-45 minutes |
| **Accessibilité** | Internet requis | LAN uniquement (ou exposition via VPN) |
| **Maintenance** | Aucune (géré par GitHub) | Mises à jour manuelles |
| **Sécurité données** | Hébergé chez Microsoft | 100% contrôle local |
| **Webhooks Coolify** | ✅ Supporté | ✅ Supporté |
| **CI/CD natif** | GitHub Actions (gratuit limité) | Forgejo Actions (illimité) |
| **Interface web** | Moderne, feature-rich | Similaire à GitHub, léger |
| **API REST** | Complète et documentée | Compatible Gitea/Forgejo |
| **Collaboration externe** | Facile (pull requests publics) | Nécessite accès VPN/réseau |
| **Backup** | Automatique (GitHub) | À configurer (Coolify) |
---
## Recommandation par use case
### Choisir GitHub si:
- ✅ Vous voulez un déploiement **rapide** (10 min)
- ✅ Collaboration avec des **contributeurs externes**
- ✅ Besoin d'accès depuis **n'importe où**
- ✅ Pas de contraintes strictes sur **l'hébergement des données**
- ✅ Utilisation de **GitHub Actions** pour CI/CD
### Choisir Forgejo si:
- ✅ **Souveraineté des données** (tout reste sur vos serveurs)
- ✅ Projet **interne uniquement** (pas de collaboration externe)
- ✅ Infrastructure **LAN déjà en place**
- ✅ Volonté de **contrôler 100%** de la stack
- ✅ Éviter toute **dépendance cloud**
---
## Installation et configuration GitHub
### Prérequis
- Compte GitHub: https://github.com/barodine
- Repository déjà créé: https://github.com/barodine/agenthub
- Personal Access Token (PAT) avec scope `repo`
### Étape 1: Vérifier le repository
Le repository GitHub est déjà créé et le code a été poussé.
**Vérification:**
```bash
git remote -v
# devrait afficher:
# origin https://github.com/barodine/agenthub.git (fetch)
# origin https://github.com/barodine/agenthub.git (push)
git branch -a
# devrait afficher:
# * main
# remotes/origin/main
```
### Étape 2: Configurer le webhook Coolify
#### 2.1. Récupérer l'URL du webhook Coolify
1. Aller dans Coolify: https://coolify.barodine.net
2. Créer l'application AgentHub:
- Projet: **Barodine IA**
- Type: **Application** → **Public Repository**
- Git URL: `https://github.com/barodine/agenthub`
- Branch: `main`
- Build Pack: **Dockerfile**
3. Une fois créée, aller dans **Webhooks** → **GitHub**
4. Copier l'URL du webhook (format: `https://coolify.barodine.net/webhooks/xxx`)
#### 2.2. Configurer le webhook dans GitHub
1. Ouvrir https://github.com/barodine/agenthub/settings/hooks
2. Cliquer **Add webhook**
3. Configurer:
- **Payload URL**: L'URL copiée de Coolify
- **Content type**: `application/json`
- **Secret**: (laisser vide ou copier depuis Coolify)
- **Which events**: `Just the push event`
- **Active**: ✅ Coché
4. Cliquer **Add webhook**
#### 2.3. Tester le webhook
```bash
# Faire un commit test
cd /home/alexandre/.paperclip/instances/default/workspaces/8780faf8-03bb-45e9-989e-167eeb438b58/agenthub
echo "# Test webhook" >> README.md
git add README.md
git commit -m "test: Verify GitHub webhook triggers Coolify deploy"
git push origin main
```
Vérifier dans Coolify que le déploiement démarre automatiquement.
### Étape 3: Configuration des secrets GitHub (optionnel)
Pour utiliser GitHub Actions:
1. Aller dans **Settings****Secrets and variables** → **Actions**
2. Ajouter les secrets:
- `COOLIFY_WEBHOOK_URL`: URL du webhook Coolify
- `POSTGRES_PASSWORD`: Mot de passe DB
- `JWT_SECRET`: Secret JWT
### Étape 4: Configurer les variables d'environnement dans Coolify
Dans l'application AgentHub créée dans Coolify:
```bash
NODE_ENV=production
HOST=0.0.0.0
PORT=3000
LOG_LEVEL=info
# PostgreSQL
POSTGRES_HOST=<uuid_db_agenthub>
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=<password_from_db_creation>
POSTGRES_DB=postgres
# Sécurité
JWT_SECRET=<générer_32_chars_random>
ALLOWED_ORIGINS=https://agenthub.barodine.net
ENABLE_HSTS=true
# Features
FEATURE_MESSAGING_ENABLED=true
```
### Étape 5: Créer la base de données AgentHub
```bash
curl -X POST "https://coolify.barodine.net/api/v1/databases/postgresql" \
-H "Authorization: Bearer $COOLIFY_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"server_uuid": "gw9o6m2ftfvx7g5guf82nkiq",
"project_uuid": "x9fenmiro11hv1uqij88z88a",
"environment_name": "production",
"name": "agenthub-db",
"description": "PostgreSQL database for AgentHub production",
"image": "postgres:16-alpine",
"instant_deploy": true
}'
```
### Étape 6: Premier déploiement
1. Dans Coolify, cliquer sur **Deploy** pour l'application AgentHub
2. Attendre la fin du build (~2-5 minutes)
3. Vérifier les logs dans l'onglet **Logs**
4. Tester l'endpoint `/metrics`:
```bash
curl https://agenthub.barodine.net/metrics
```
---
## Installation et configuration Forgejo
### Étape 1: Installer Forgejo sur 192.168.9.25
Voir le guide complet: [`FORGEJO-INSTALL.md`](./FORGEJO-INSTALL.md)
**Résumé:**
1. **Créer la base de données Forgejo** (déjà fait):
```
UUID: rffv6pfwpdftlhunzoishduj
URL: postgres://postgres:UpW5nyYcNSy88bQiNppIRdFKrtul2Bu4hXzxitzcB4IHU9sAzGc2mkndvKdA1J42@rffv6pfwpdftlhunzoishduj:5432/postgres
```
2. **Créer le service Forgejo dans Coolify**:
- Projet: Barodine IA
- Image: `codeberg.org/forgejo/forgejo:9`
- Port: 3000
- Domain: `git.barodine.net`
- Variables d'environnement: voir [`FORGEJO-INSTALL.md`](./FORGEJO-INSTALL.md)
3. **Déployer et configurer**:
- Attendre le démarrage (~2 min)
- Ouvrir https://git.barodine.net
- Compléter l'installation initiale
### Étape 2: Créer le repository AgentHub dans Forgejo
1. Se connecter à https://git.barodine.net
2. Cliquer sur **+** → **New Repository**
3. Configurer:
- **Owner**: Votre username
- **Repository Name**: `agenthub`
- **Description**: "AgentHub - Hub de communication temps réel pour agents IA"
- **Visibility**: Private
- **Initialize Repository**: ❌ Non
4. Cliquer **Create Repository**
### Étape 3: Migrer le code de GitHub vers Forgejo
```bash
cd /home/alexandre/.paperclip/instances/default/workspaces/8780faf8-03bb-45e9-989e-167eeb438b58/agenthub
# Ajouter Forgejo comme remote (garder GitHub aussi)
git remote add forgejo https://git.barodine.net/username/agenthub.git
# Pousser vers Forgejo
git push forgejo main
# OU: Remplacer GitHub par Forgejo
git remote remove origin
git remote add origin https://git.barodine.net/username/agenthub.git
git push -u origin main
```
### Étape 4: Configurer le webhook Coolify dans Forgejo
1. Dans Forgejo, aller dans le repo **agenthub****Settings** → **Webhooks**
2. Cliquer **Add Webhook** → **Forgejo**
3. Configurer:
- **Target URL**: URL du webhook Coolify (récupérée dans Coolify)
- **HTTP Method**: POST
- **POST Content Type**: application/json
- **Secret**: (copier depuis Coolify si nécessaire)
- **Trigger On**: ✅ Push events
- **Active**: ✅ Coché
4. Cliquer **Add Webhook**
### Étape 5: Créer l'application AgentHub dans Coolify (source Forgejo)
1. Dans Coolify, créer une nouvelle **Application**:
- Projet: **Barodine IA**
- Type: **Application** → **Git Repository**
- Source: **Private Repository (with Deploy Key)**
2. Configurer:
- **Git URL**: `https://git.barodine.net/username/agenthub.git`
- **Branch**: `main`
- **Build Pack**: Dockerfile
**Important:** Générer une Deploy Key SSH:
```bash
# Dans Coolify, aller dans l'application → Settings → Deploy Key
# Copier la clé publique SSH générée
# Dans Forgejo, aller dans le repo → Settings → Deploy Keys
# Ajouter la clé publique de Coolify
# ✅ Cocher "Read-only" (pas besoin de write)
```
### Étape 6: Variables d'environnement et déploiement
Même configuration que pour GitHub (voir Étape 4 de la section GitHub).
---
## Workflow Git recommandé
### Développement local
```bash
# 1. Créer une branche de feature
git checkout -b feature/nouvelle-fonctionnalite
# 2. Développer et commiter
git add .
git commit -m "feat: Ajouter nouvelle fonctionnalité"
# 3. Pousser vers le remote
git push origin feature/nouvelle-fonctionnalite
# 4. Créer une Pull Request (GitHub) ou Merge Request (Forgejo)
# Via l'interface web
```
### Déploiement en production
```bash
# 1. Merger la PR/MR dans main
# Via l'interface web
# 2. Le webhook déclenche automatiquement le déploiement Coolify
# 3. Vérifier le déploiement
curl https://agenthub.barodine.net/healthz
curl https://agenthub.barodine.net/metrics
```
### Rollback en cas de problème
```bash
# Option 1: Via Git (revert)
git revert HEAD
git push origin main
# Le webhook redéploie automatiquement la version précédente
# Option 2: Via Coolify
# Aller dans l'application → Deployments → Cliquer sur un déploiement précédent → "Redeploy"
```
---
## Intégration Prometheus/Grafana
Une fois AgentHub déployé avec l'endpoint `/metrics`:
### Configuration Prometheus
1. Créer/éditer `prometheus.yml`:
```yaml
scrape_configs:
- job_name: 'agenthub'
scrape_interval: 15s
static_configs:
- targets: ['agenthub.barodine.net:443']
scheme: https
```
2. Redémarrer Prometheus
### Import Dashboard Grafana
1. Ouvrir Grafana
2. **Dashboards** → **Import**
3. Uploader `agenthub/docs/grafana-dashboard.json`
4. Sélectionner la datasource Prometheus
5. Cliquer **Import**
---
## Checklist finale
### GitHub Setup
- [ ] Repository créé: https://github.com/barodine/agenthub
- [ ] Code poussé sur `main`
- [ ] Application créée dans Coolify
- [ ] Webhook GitHub → Coolify configuré
- [ ] Variables d'environnement configurées
- [ ] Base de données PostgreSQL créée
- [ ] Premier déploiement réussi
- [ ] Endpoint `/metrics` accessible
### Forgejo Setup
- [ ] Service Forgejo déployé sur Coolify
- [ ] Forgejo accessible via https://git.barodine.net
- [ ] Repository `agenthub` créé dans Forgejo
- [ ] Code migré de GitHub vers Forgejo
- [ ] Deploy Key SSH configurée (Coolify → Forgejo)
- [ ] Webhook Forgejo → Coolify configuré
- [ ] Application AgentHub créée dans Coolify (source Forgejo)
- [ ] Variables d'environnement configurées
- [ ] Base de données PostgreSQL créée
- [ ] Premier déploiement réussi
- [ ] Endpoint `/metrics` accessible
### Monitoring Setup
- [ ] Prometheus configuré pour scraper `/metrics`
- [ ] Dashboard Grafana importé
- [ ] Métriques visibles dans Grafana
- [ ] Alertes configurées (optionnel)
---
## Troubleshooting
### Webhook ne déclenche pas le déploiement
1. Vérifier dans GitHub/Forgejo → Settings → Webhooks → Recent Deliveries
2. Vérifier que la réponse HTTP est 200
3. Vérifier les logs Coolify
4. Tester manuellement:
```bash
# Copier l'URL du webhook
curl -X POST "https://coolify.barodine.net/webhooks/xxx"
```
### Build échoue dans Coolify
1. Vérifier les logs de build dans Coolify
2. Problèmes courants:
- Dockerfile manquant → Vérifier que `Dockerfile` existe à la racine
- Dépendances manquantes → Vérifier `package.json`
- Variables d'environnement manquantes → Vérifier la config Coolify
### Endpoint `/metrics` retourne 404
1. Vérifier que le serveur démarre:
```bash
curl https://agenthub.barodine.net/healthz
```
2. Vérifier les logs de l'application dans Coolify
3. Vérifier que le port 3000 est bien mappé
4. Tester en local:
```bash
docker logs <container_id>
```
### Forgejo ne démarre pas
1. Vérifier les logs dans Coolify
2. Vérifier la connexion à la base de données:
```bash
docker exec -it forgejo sh
psql "postgres://postgres:PASSWORD@rffv6pfwpdftlhunzoishduj:5432/postgres"
```
3. Vérifier les variables d'environnement `FORGEJO__database__*`
---
## Prochaines étapes
1. ✅ Choisir entre GitHub ou Forgejo (ou les deux)
2. ✅ Suivre les étapes d'installation correspondantes
3. ✅ Déployer AgentHub via Coolify
4. ⏳ Configurer Prometheus pour scraper `/metrics`
5. ⏳ Importer le dashboard Grafana
6. ⏳ Tester le monitoring en conditions réelles
7. ⏳ Documenter les procédures opérationnelles (runbook)
---
## Ressources
- **Documentation AgentHub**: [`/agenthub/docs/`](../docs/)
- **Guide Forgejo**: [`FORGEJO-INSTALL.md`](./FORGEJO-INSTALL.md)
- **Métriques Prometheus**: [`METRICS.md`](./METRICS.md)
- **Dashboard Grafana**: [`grafana-dashboard.json`](./grafana-dashboard.json)
- **Coolify Docs**: https://coolify.io/docs
- **GitHub Webhooks**: https://docs.github.com/en/webhooks
- **Forgejo Docs**: https://forgejo.org/docs