docs: mise à jour DEPLOYMENT.md et PRODUCTION_CHECKLIST pour nouvelle structure
This commit is contained in:
+160
-100
@@ -1,122 +1,182 @@
|
||||
# Guide de déploiement — Imago sur serveur Docker
|
||||
|
||||
> Cible : serveur Docker du lab (dev.lab.home / Proxmox)
|
||||
> Registry : `docker-registry.dev.home:5000`
|
||||
> Prérequis : Docker 24+, Docker Compose v2, accès SSH
|
||||
> Cible : serveur Linux avec Docker 24+, Docker Compose v2
|
||||
> Registry : `docker-registry.dev.home:5000` (images pré-buildées)
|
||||
|
||||
---
|
||||
|
||||
## Étape 1 — Builder et pousser l'image vers le registry
|
||||
## Déploiement rapide (2 commandes)
|
||||
|
||||
Depuis le poste de développement (Windows + WSL Debian) :
|
||||
```bash
|
||||
# 1. Cloner le dépôt
|
||||
git clone https://git.dracodev.net/Projets/Imago.git /opt/imago
|
||||
cd /opt/imago
|
||||
|
||||
# 2. Préparer le serveur (une seule fois)
|
||||
sudo ./scripts/setup.sh
|
||||
```
|
||||
|
||||
Déconnectez/reconnectez-vous (groupe docker), puis :
|
||||
|
||||
```bash
|
||||
cd /opt/imago
|
||||
./scripts/deploy.sh
|
||||
```
|
||||
|
||||
L'assistant interactif vous guide : choix du stockage (local/S3), configuration AI, OCR, CORS. Les secrets sont générés automatiquement.
|
||||
|
||||
### Commandes quotidiennes
|
||||
|
||||
```bash
|
||||
./scripts/deploy.sh -u # Mise à jour (pull + recréation)
|
||||
./scripts/deploy.sh -s # État des conteneurs
|
||||
./scripts/deploy.sh -l # Logs en temps réel
|
||||
./scripts/deploy.sh --reconfigure # Modifier la configuration
|
||||
```
|
||||
|
||||
### URLs d'accès
|
||||
|
||||
| Service | URL |
|
||||
|---|---|
|
||||
| Admin UI | `http://<serveur>:3001` |
|
||||
| API Docs (Swagger) | `http://<serveur>:8001/docs` |
|
||||
| Health check | `http://<serveur>:8001/health` |
|
||||
|
||||
---
|
||||
|
||||
## Structure du projet
|
||||
|
||||
```
|
||||
/opt/imago/
|
||||
├── docker-compose/
|
||||
│ ├── docker-compose.yml # Développement
|
||||
│ ├── docker-compose.prod.yml # Production
|
||||
│ └── .env.example # Template
|
||||
├── scripts/
|
||||
│ ├── setup.sh # Préparation serveur
|
||||
│ └── deploy.sh # Déploiement
|
||||
├── .env # Config (généré par deploy.sh)
|
||||
└── backups/ # Dumps PostgreSQL
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Build des images (développeurs)
|
||||
|
||||
Depuis un poste Windows avec WSL Debian :
|
||||
|
||||
```powershell
|
||||
cd C:\dev\git\python\imago\docker
|
||||
# Backend
|
||||
cd C:\dev\git\python\imago
|
||||
docker build --no-cache -t docker-registry.dev.home:5000/imago-backend:latest -f Dockerfile .
|
||||
docker push docker-registry.dev.home:5000/imago-backend:latest
|
||||
|
||||
# Builder l'image
|
||||
.\build-img.ps1
|
||||
|
||||
# Pousser vers le registry (version semver auto-incrémentée)
|
||||
.\deploy-img.ps1
|
||||
```
|
||||
|
||||
L'image est disponible à :
|
||||
- `docker-registry.dev.home:5000/imago-backend:latest`
|
||||
- `docker-registry.dev.home:5000/imago-backend:2.0.0`
|
||||
|
||||
---
|
||||
|
||||
## Étape 2 — Préparer les secrets de production
|
||||
|
||||
```bash
|
||||
# Générer des secrets forts (à faire UNE SEULE fois)
|
||||
openssl rand -hex 32 # SECRET_KEY
|
||||
openssl rand -hex 32 # ADMIN_API_KEY → note-la, c'est ta clé admin
|
||||
openssl rand -hex 32 # JWT_SECRET_KEY
|
||||
openssl rand -hex 32 # SIGNED_URL_SECRET
|
||||
openssl rand -hex 16 # MINIO_ROOT_PASSWORD
|
||||
openssl rand -hex 16 # POSTGRES_PASSWORD
|
||||
```
|
||||
|
||||
Créer `.env.production` (remplacer les `<...>`) :
|
||||
|
||||
```bash
|
||||
# ── Application ──
|
||||
APP_NAME=Imago
|
||||
APP_VERSION=2.0.0
|
||||
DEBUG=false
|
||||
SECRET_KEY=<valeur générée>
|
||||
|
||||
# ── Base de données ──
|
||||
DATABASE_URL=postgresql+asyncpg://imago:<POSTGRES_PASSWORD>@db:5432/imago
|
||||
|
||||
# ── Stockage MinIO ──
|
||||
STORAGE_BACKEND=s3
|
||||
S3_BUCKET=imago
|
||||
S3_ENDPOINT_URL=http://minio:9000
|
||||
S3_ACCESS_KEY=minioadmin
|
||||
S3_SECRET_KEY=<S3_SECRET_KEY généré>
|
||||
S3_REGION=us-east-1
|
||||
SIGNED_URL_SECRET=<valeur générée>
|
||||
|
||||
# ── Redis ──
|
||||
REDIS_URL=redis://redis:***@ADMIN_API_KEY=<valeur générée>
|
||||
JWT_SECRET_KEY=<valeur générée>
|
||||
JWT_ALGORITHM=HS256
|
||||
|
||||
# ── AI ──
|
||||
AI_ENABLED=true
|
||||
AI_PROVIDER=openrouter
|
||||
OPENROUTER_API_KEY=<clé OpenRouter>
|
||||
OPENROUTER_MODEL=qwen/qwen2.5-vl-72b-instruct
|
||||
AI_TAGS_MIN=5
|
||||
AI_TAGS_MAX=10
|
||||
AI_DESCRIPTION_LANGUAGE=francais
|
||||
AI_REQUEST_TIMEOUT=60
|
||||
AI_MAX_RETRIES=2
|
||||
|
||||
# ── OCR ──
|
||||
OCR_ENABLED=true
|
||||
OCR_LANGUAGES=fra+eng
|
||||
|
||||
# ── CORS ──
|
||||
CORS_ORIGINS=["http://localhost:3000", "http://localhost:8000"]
|
||||
|
||||
# ── Pipeline ──
|
||||
PIPELINE_TIMEOUT=300
|
||||
PIPELINE_MAX_RETRIES=3
|
||||
|
||||
# ── Rate Limiting (Redis persistence) ──
|
||||
RATE_LIMIT_STORAGE_URL=redis://redis:***@#!/bin/bash
|
||||
# Backup PostgreSQL — tous les jours à 2h
|
||||
0 2 * * * docker exec imago-db-1 pg_dump -U imago imago > /opt/imago/backups/imago_$(date +\%Y\%m\%d).sql
|
||||
|
||||
# Nettoyer les backups de plus de 30 jours
|
||||
0 3 * * * find /opt/imago/backups -name "*.sql" -mtime +30 -delete
|
||||
# Admin (React + Nginx)
|
||||
cd imago-admin
|
||||
docker build --no-cache -t docker-registry.dev.home:5000/imago-admin:latest .
|
||||
docker push docker-registry.dev.home:5000/imago-admin:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Étape 5 — Vérifications post-déploiement
|
||||
## Configuration manuelle du .env (sans l'assistant)
|
||||
|
||||
Si vous préférez créer le `.env` manuellement :
|
||||
|
||||
```bash
|
||||
# Vérifier que tous les conteneurs tournent
|
||||
docker compose -f /opt/imago/docker-compose.production.yml ps
|
||||
cp docker-compose/.env.example .env
|
||||
nano .env
|
||||
```
|
||||
|
||||
Variables essentielles :
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `SECRET_KEY` | Clé secrète (générer : `openssl rand -hex 32`) |
|
||||
| `STORAGE_BACKEND` | `local` ou `s3` |
|
||||
| `UPLOAD_DIR` | Chemin uploads dans le conteneur |
|
||||
| `SIGNED_URL_SECRET` | Clé pour URLs signées HMAC |
|
||||
| `OPENROUTER_API_KEY` | Clé API OpenRouter (ou `GEMINI_API_KEY`) |
|
||||
| `CORS_ORIGINS` | JSON array des origines autorisées |
|
||||
|
||||
Pour le stockage S3, ajouter : `S3_BUCKET`, `S3_ENDPOINT_URL`, `S3_ACCESS_KEY`, `S3_SECRET_KEY`, `S3_REGION`.
|
||||
|
||||
---
|
||||
|
||||
## Services
|
||||
|
||||
| Service | Image | Port interne | Rôle |
|
||||
|---|---|---|---|
|
||||
| `backend` | `imago-backend:latest` | 8000 | API FastAPI |
|
||||
| `admin` | `imago-admin:latest` | 80 | Interface React + Nginx |
|
||||
| `db` | `postgres:16-alpine` | 5432 | Base de données |
|
||||
| `redis` | `redis:7-alpine` | 6379 | Cache, broker, pub/sub |
|
||||
|
||||
---
|
||||
|
||||
## Vérifications post-déploiement
|
||||
|
||||
```bash
|
||||
# Santé de l'API
|
||||
curl http://localhost:8000/health
|
||||
curl http://localhost:8001/health
|
||||
|
||||
# Santé détaillée (tous les services)
|
||||
curl http://localhost:8000/health/detailed
|
||||
# Santé détaillée
|
||||
curl http://localhost:8001/health/detailed
|
||||
|
||||
# Accéder au panneau admin
|
||||
curl http://localhost:3000
|
||||
# État des conteneurs
|
||||
./scripts/deploy.sh -s
|
||||
```
|
||||
|
||||
Checklist :
|
||||
- [ ] `http://localhost:8000/health` → `{"status":"healthy"}`
|
||||
- [ ] `http://localhost:8000/health/detailed` → tous les checks OK
|
||||
- [ ] `http://localhost:3000` → page de login accessible
|
||||
- [ ] Connexion admin avec `ADMIN_API_KEY`
|
||||
- [ ] Upload d'une image test → pipeline OK
|
||||
- [ ] Métriques Prometheus `/metrics` → données présentes
|
||||
- [ ] `http://<serveur>:8001/health` → `{"status":"healthy"}`
|
||||
- [ ] `http://<serveur>:3001` → page de login accessible
|
||||
- [ ] Connexion admin avec la clé bootstrap (affichée dans les logs au 1er démarrage)
|
||||
- [ ] Upload d'une image test → traitement OK
|
||||
- [ ] Suppression d'une image → OK
|
||||
|
||||
---
|
||||
|
||||
## Sauvegardes
|
||||
|
||||
```bash
|
||||
# Backup manuel
|
||||
docker exec imago-db-1 pg_dump -U imago imago > ./backups/imago_$(date +%Y%m%d).sql
|
||||
|
||||
# Restauration
|
||||
docker exec -i imago-db-1 psql -U imago imago < ./backups/imago_20250101.sql
|
||||
```
|
||||
|
||||
Pour automatiser (cron) :
|
||||
|
||||
```bash
|
||||
# /etc/cron.d/imago-backup
|
||||
0 2 * * * root docker exec imago-db-1 pg_dump -U imago imago > /opt/imago/backups/imago_$(date +\%Y\%m\%d).sql
|
||||
0 3 * * * root find /opt/imago/backups -name "*.sql" -mtime +30 -delete
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Résolution de problèmes
|
||||
|
||||
### Les conteneurs ne démarrent pas
|
||||
```bash
|
||||
docker compose -f docker-compose/docker-compose.prod.yml logs
|
||||
```
|
||||
|
||||
### Réseau Docker saturé
|
||||
```bash
|
||||
docker network prune -f
|
||||
```
|
||||
|
||||
### Espace disque
|
||||
```bash
|
||||
docker system df
|
||||
docker system prune -a -f
|
||||
```
|
||||
|
||||
### Réinitialiser la base de données
|
||||
```bash
|
||||
docker compose -f docker-compose/docker-compose.prod.yml down -v db
|
||||
docker compose -f docker-compose/docker-compose.prod.yml up -d db
|
||||
# Attendre que la BDD soit prête, puis relancer les autres services
|
||||
```
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
| # | Tâche | Pourquoi |
|
||||
|---|---|---|
|
||||
| 15 | Backup automatique PostgreSQL (pg_dump cron daily) | Perte de toutes les métadonnées |
|
||||
| 16 | Backup MinIO/S3 (rclone ou S3 replication) | Perte de toutes les images |
|
||||
| 16 | Backup des fichiers uploadés (rsync ou rclone) | Perte de toutes les images |
|
||||
| 17 | Tester une restauration complète (backup + restore) | Un backup non testé n'existe pas |
|
||||
|
||||
### 🔄 Migrations BDD
|
||||
@@ -119,14 +119,16 @@
|
||||
### Quick Start (top 5 à faire aujourd'hui)
|
||||
|
||||
```bash
|
||||
# 1. Générer des secrets forts
|
||||
openssl rand -hex 32 # pour SECRET_KEY
|
||||
openssl rand -hex 32 # pour ADMIN_API_KEY
|
||||
openssl rand -hex 32 # pour JWT_SECRET_KEY
|
||||
openssl rand -hex 16 # pour MINIO_ROOT_PASSWORD
|
||||
# 1. Déployer avec l'assistant interactif
|
||||
./scripts/deploy.sh
|
||||
|
||||
# 2. Mettre à jour .env avec ces valeurs
|
||||
# 3. DEBUG=false
|
||||
# 4. CORS_ORIGINS=["https://ton-domaine.com"]
|
||||
# 5. docker compose up -d
|
||||
# 2. Vérifier la santé
|
||||
curl http://localhost:8001/health
|
||||
|
||||
# 3. Configurer CORS pour le domaine de production
|
||||
# Éditer .env : CORS_ORIGINS=["https://ton-domaine.com"]
|
||||
|
||||
# 4. Activer DEBUG=false dans .env
|
||||
|
||||
# 5. Mettre en place les backups automatiques (voir docs/DEPLOYMENT.md)
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user