Update deploy doc to use docker-registry.dev.home:5000 + production compose
CI / Lint & Format (push) Failing after 9s
CI / Tests (push) Has been skipped
CI / Security Scan (push) Failing after 7s
CI / Docker Build (push) Has been skipped

This commit is contained in:
2026-06-22 20:30:22 -04:00
parent a4a38cda14
commit 0050ace888
2 changed files with 125 additions and 224 deletions
+38 -224
View File
@@ -1,46 +1,28 @@
# Guide de déploiement — Imago sur serveur Docker
> Cible : serveur Docker distant (VM Proxmox, VPS, ou bare metal)
> 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
---
## Étape 1 — Préparer le registry d'images
## Étape 1 — Builder et pousser l'image vers le registry
Choisir UNE des options :
Depuis le poste de développement (Windows + WSL Debian) :
### Option A : Gitea Container Registry (recommandé si Gitea dispo)
```bash
# Builder et tagger l'image
cd C:\dev\git\python\imago
docker build -t gitea.dracodev.net/projets/imago-backend:latest .
docker build -t gitea.dracodev.net/projets/imago-admin:latest ./imago-admin
```powershell
cd C:\dev\git\python\imago\docker
# Se connecter au registry Gitea
docker login gitea.dracodev.net -u bruno
# Builder l'image
.\build-img.ps1
# Pusher
docker push gitea.dracodev.net/projets/imago-backend:latest
docker push gitea.dracodev.net/projets/imago-admin:latest
# Pousser vers le registry (version semver auto-incrémentée)
.\deploy-img.ps1
```
### Option B : Docker Hub
```bash
docker build -t tonuser/imago-backend:latest .
docker build -t tonuser/imago-admin:latest ./imago-admin
docker push tonuser/imago-backend:latest
docker push tonuser/imago-admin:latest
```
### Option C : Registry local sur le serveur
```bash
# Sur le serveur cible
docker run -d -p 5000:5000 --name registry registry:2
# En local, builder et pusher
docker build -t localhost:5000/imago-backend:latest .
docker push localhost:5000/imago-backend:latest
```
L'image est disponible à :
- `docker-registry.dev.home:5000/imago-backend:latest`
- `docker-registry.dev.home:5000/imago-backend:2.0.0`
---
@@ -49,15 +31,15 @@ docker push localhost:5000/imago-backend:latest
```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é d'accès admin
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 # S3_SECRET_KEY
openssl rand -hex 16 # MINIO_ROOT_PASSWORD
openssl rand -hex 16 # POSTGRES_PASSWORD
```
Créer le fichier `.env.production` :
Créer `.env.production` (remplacer les `<...>`) :
```bash
# ── Application ──
APP_NAME=Imago
@@ -68,7 +50,7 @@ SECRET_KEY=<valeur générée>
# ── Base de données ──
DATABASE_URL=postgresql+asyncpg://imago:<POSTGRES_PASSWORD>@db:5432/imago
# ── Stockage S3/MinIO ──
# ── Stockage MinIO ──
STORAGE_BACKEND=s3
S3_BUCKET=imago
S3_ENDPOINT_URL=http://minio:9000
@@ -85,7 +67,7 @@ JWT_ALGORITHM=HS256
# ── AI ──
AI_ENABLED=true
AI_PROVIDER=openrouter
OPENROUTER_API_KEY=<ta clé OpenRouter>
OPENROUTER_API_KEY=<clé OpenRouter>
OPENROUTER_MODEL=qwen/qwen2.5-vl-72b-instruct
AI_TAGS_MIN=5
AI_TAGS_MAX=10
@@ -98,179 +80,14 @@ OCR_ENABLED=true
OCR_LANGUAGES=fra+eng
# ── CORS ──
CORS_ORIGINS=["https://admin.ton-domaine.com"]
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:6379/1
```
---
## Étape 3 — Préparer le docker-compose.production.yml
```yaml
services:
traefik:
image: traefik:v3.0
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
- "--certificatesresolvers.letsencrypt.acme.email=bruno.charest@gmail.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik_certs:/letsencrypt
restart: unless-stopped
backend:
image: gitea.dracodev.net/projets/imago-backend:latest
env_file: .env.production
labels:
- "traefik.enable=true"
- "traefik.http.routers.imago-api.rule=Host(`api.ton-domaine.com`)"
- "traefik.http.routers.imago-api.entrypoints=websecure"
- "traefik.http.routers.imago-api.tls.certresolver=letsencrypt"
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
deploy:
resources:
limits:
memory: 1G
cpus: '2'
worker:
image: gitea.dracodev.net/projets/imago-backend:latest
command: python worker.py
env_file: .env.production
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
cpus: '1'
admin:
image: nginx:alpine
ports:
- "127.0.0.1:3000:80"
volumes:
- ./admin-dist:/usr/share/nginx/html:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.imago-admin.rule=Host(`admin.ton-domaine.com`)"
- "traefik.http.routers.imago-admin.entrypoints=websecure"
- "traefik.http.routers.imago-admin.tls.certresolver=letsencrypt"
restart: unless-stopped
db:
image: postgres:16-alpine
env_file: .env.production
environment:
POSTGRES_USER: imago
POSTGRES_DB: imago
volumes:
- pgdata:/var/lib/postgresql/data
- ./backups:/backups
healthcheck:
test: ["CMD-SHELL", "pg_isready -U imago -d imago"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
redis:
image: redis:7-alpine
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redisdata:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
memory: 256M
minio:
image: minio/minio
command: server /data --console-address ":9001"
env_file: .env.production
volumes:
- miniodata:/data
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
volumes:
pgdata:
redisdata:
miniodata:
traefik_certs:
```
---
## Étape 4 — Déployer sur le serveur
```bash
# 1. Se connecter au serveur
ssh ton-serveur
# 2. Créer le répertoire de l'application
mkdir -p /opt/imago && cd /opt/imago
# 3. Copier les fichiers de configuration
# (depuis ton poste local)
scp docker-compose.production.yml ton-serveur:/opt/imago/
scp .env.production ton-serveur:/opt/imago/
# 4. S'assurer que les volumes de backup existent
mkdir -p backups
# 5. Démarrer la stack
docker compose -f docker-compose.production.yml up -d
# 6. Vérifier les logs
docker compose -f docker-compose.production.yml logs -f backend
# 7. Vérifier la santé
curl https://api.ton-domaine.com/health
```
---
## Étape 5 — Backup automatique (cron)
Ajouter au crontab du serveur :
```cron
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
@@ -280,29 +97,26 @@ Ajouter au crontab du serveur :
---
## Étape 6 — Vérifications post-déploiement
- [ ] `https://api.ton-domaine.com/health` → `{"status":"healthy"}`
- [ ] `https://api.ton-domaine.com/health/detailed` → tous les checks OK
- [ ] `https://admin.ton-domaine.com` → page de login accessible
- [ ] Connexion admin avec `ADMIN_API_KEY`
- [ ] Upload d'une image test → pipeline OK
- [ ] WebSocket `/ws/pipeline/{id}` → événements reçus
- [ ] Métriques Prometheus `/metrics` → données présentes
---
## Résumé des commandes rapides
## Étape 5 — Vérifications post-déploiement
```bash
# Builder les images (local)
docker build -t gitea.dracodev.net/projets/imago-backend:latest .
docker login gitea.dracodev.net
docker push gitea.dracodev.net/projets/imago-backend:latest
# Vérifier que tous les conteneurs tournent
docker compose -f /opt/imago/docker-compose.production.yml ps
# Déployer (serveur)
ssh serveur "cd /opt/imago && docker compose pull && docker compose up -d"
# Santé de l'API
curl http://localhost:8000/health
# Vérifier
curl https://api.ton-domaine.com/health
# Santé détaillée (tous les services)
curl http://localhost:8000/health/detailed
# Accéder au panneau admin
curl http://localhost:3000
```
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