Files
XIP/DEPLOY.md
Kerboul 024909b162
Some checks failed
Deploy XIP / deploy (push) Failing after 21s
feat(deploy): CI/CD Gitea Actions + stack Docker prod pour xip.kerboul.me
- docker-compose.prod.yml: postgres + redis + backend (bun) + web (nginx single-origin)
- backend/Dockerfile + entrypoint: prisma migrate deploy + seed idempotent au boot
- frontend/Dockerfile: build Vite (VITE_API_URL=https://xip.kerboul.me) servi par nginx
- deploy/nginx.conf: proxy /api + /ws vers le backend, SPA fallback
- .gitea/workflows/deploy.yml: auto-deploy SSH sur push main (runner CT121 -> CT502)
- scripts/deploy.sh: pull + rebuild de la stack
- mode open-bar (XIP_OPEN_BAR): paywall off pour tous en prod, via isFree() centralise

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 15:14:53 +02:00

65 lines
2.9 KiB
Markdown

# Déploiement XIP
Production : **https://xip.kerboul.me** — déploiement continu sur push `main`.
## Architecture (pattern Vireli, cluster SENTINEL)
```
Cloudflare (*.kerboul.me) ─► VPS WireGuard ─► Traefik (CT102, Cerberus)
│ Host(`xip.kerboul.me`) → http://192.168.1.242:80
CT502 « xip-app » (Echelon, Docker host)
┌───────────────────────────────────────┐
│ web (nginx:80) │
│ ├── / → SPA Vue (statique) │
│ ├── /api/ → backend:3000 │
│ └── /ws → backend:3000 (WS) │
│ backend (bun:3000, Hono + Prisma) │
│ postgres:16 redis:7 │
└───────────────────────────────────────┘
```
Origine unique : le front (buildé avec `VITE_API_URL=https://xip.kerboul.me`)
appelle `/api` et `wss://xip.kerboul.me/ws`, nginx proxifie vers le backend.
Traefik termine le TLS (Let's Encrypt, DNS challenge Cloudflare).
## CI/CD (Gitea Actions)
`.gitea/workflows/deploy.yml` se déclenche sur push `main` (+ `workflow_dispatch`).
Le runner (CT121) se connecte en SSH au CT502 et exécute `scripts/deploy.sh`
(`git reset --hard origin/main` + `docker compose up -d --build`).
Migrations Prisma + seed (idempotent) tournent au démarrage du conteneur backend
(`backend/docker-entrypoint.sh`).
### Secrets du repo (Gitea → Settings → Actions → Secrets)
| Secret | Rôle |
|--------|------|
| `XIP_DEPLOY_HOST` | IP du CT502 (192.168.1.242) |
| `XIP_DEPLOY_USER` | utilisateur de déploiement (`deploy`) |
| `XIP_DEPLOY_KEY` | clé privée SSH autorisée sur le CT502 |
## Fichiers
| Fichier | Rôle |
|---------|------|
| `docker-compose.prod.yml` | stack prod (postgres, redis, backend, web) |
| `backend/Dockerfile` + `docker-entrypoint.sh` | image backend, migrate+seed au boot |
| `frontend/Dockerfile` | build Vite → nginx |
| `deploy/nginx.conf` | reverse proxy single-origin |
| `scripts/deploy.sh` | script de (re)déploiement sur le CT |
| `.env.prod` (non commité) | secrets : voir `.env.prod.example` |
## Paywall
`XIP_OPEN_BAR=true` (dans `.env.prod`) = **open bar** : toutes les fonctionnalités
payantes gratuites pour tout le monde. Mettre `false` pour réactiver le paywall
(gratuit uniquement en localhost). Logique centralisée dans `backend/src/lib/ip.ts`
(`isFree()`).
## Redéploiement manuel
```bash
ssh deploy@192.168.1.242 'bash /opt/xip/scripts/deploy.sh'
```