# Déploiement Portainer / Docker Swarm

Guide de déploiement de Xpeditis sur Portainer avec Docker Swarm.

---

## Infrastructure

| Composant | Image | Registry |
|-----------|-------|----------|
| Backend NestJS | xpeditis-backend | rg.fr-par.scw.cloud/weworkstudio |
| Frontend Next.js | xpeditis-frontend | rg.fr-par.scw.cloud/weworkstudio |
| PostgreSQL 15 | postgres:15-alpine | Docker Hub |
| Redis 7 | redis:7-alpine | Docker Hub |
| MinIO | minio/minio | Docker Hub |

**Registry** : Scaleway Container Registry (fr-par)
**Portainer** : https://portainer.weworkstudio.com

---

## Prérequis

### 1. Configurer le registry Scaleway dans Portainer

**Portainer → Registries → Add registry** :
- Registry URL : `rg.fr-par.scw.cloud/weworkstudio`
- Username : `nologin`
- Password : token Scaleway (Console → Registry → Push/Pull credentials)

### 2. Créer le réseau Traefik

```bash
docker network create traefik_network
```

### 3. Vérifier que les images existent

```bash
docker manifest inspect rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod
docker manifest inspect rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod
```

---

## Build et push des images

### Script de déploiement complet

```bash
# Build et push backend (supporte AMD64 + ARM64)
cd apps/backend
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod \
  --push .

# Build et push frontend
cd ../frontend
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod \
  --push .
```

> Pour ARM64 seul (serveur Hetzner CAX) : `--platform linux/arm64`

---

## Déploiement dans Portainer

1. **Portainer → Stacks → Add stack**
2. **Name** : `xpeditis-preprod`
3. **Build method** : Web editor
4. Coller le contenu de `docker/portainer-stack.yml`
5. Définir les variables d'environnement (voir section suivante)
6. **Deploy the stack**

---

## Variables d'environnement production

### Backend

```bash
NODE_ENV=production
PORT=4000
API_PREFIX=api/v1
FRONTEND_URL=https://app.xpeditis.com

# Base de données
DATABASE_HOST=xpeditis-db
DATABASE_PORT=5432
DATABASE_USER=xpeditis
DATABASE_PASSWORD=CHANGER_EN_PROD
DATABASE_NAME=xpeditis_prod
DATABASE_SYNC=false
DATABASE_LOGGING=false

# Redis
REDIS_HOST=xpeditis-redis
REDIS_PORT=6379
REDIS_PASSWORD=CHANGER_EN_PROD

# JWT
JWT_SECRET=MINIMUM_32_CARACTERES_ALEATOIRES
JWT_ACCESS_EXPIRATION=15m
JWT_REFRESH_EXPIRATION=7d

# Email
SMTP_HOST=smtp-relay.brevo.com
SMTP_PORT=587
SMTP_USER=
SMTP_PASS=
SMTP_FROM=noreply@xpeditis.com

# Storage (MinIO en prod ou S3)
AWS_ACCESS_KEY_ID=minioadmin
AWS_SECRET_ACCESS_KEY=minioadmin
AWS_REGION=us-east-1
AWS_S3_ENDPOINT=http://xpeditis-minio:9000

# Swagger
SWAGGER_USERNAME=admin
SWAGGER_PASSWORD=CHANGER_EN_PROD

# Stripe
STRIPE_SECRET_KEY=sk_live_xxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxx
STRIPE_SILVER_MONTHLY_PRICE_ID=price_xxxx
# ... autres price IDs

# Monitoring
SENTRY_DSN=
```

### Frontend

```bash
NEXT_PUBLIC_API_URL=https://api.xpeditis.com
```

---

## Migrations automatiques

Le backend exécute les migrations automatiquement au démarrage via le script `docker-entrypoint.sh` :

```bash
# apps/backend/docker-entrypoint.sh attend PostgreSQL puis :
npm run migration:run
node dist/main.js
```

Les logs Portainer affichent :
```
✅ PostgreSQL is ready
✅ Successfully ran N migration(s)
🚀 Xpeditis API Server Running
```

---

## Vérifier le déploiement

```bash
# Depuis Portainer → Containers → xpeditis-backend → Logs
# Ou en SSH sur le serveur :
docker logs xpeditis-backend --tail 50 -f

# Tester les endpoints
curl https://api.xpeditis.com/api/v1/health
# → {"status":"ok"}

curl https://app.xpeditis.com
# → 200 OK
```

---

## Problèmes courants

### CSS manquant en production (Next.js)

Vérifier que la variable `NEXT_PUBLIC_API_URL` est définie **au moment du build** (pas au runtime).
Solution : passer la variable en ARG dans le Dockerfile frontend ou utiliser `--build-arg`.

### 404 sur routes Next.js

Le frontend Next.js est configuré en mode `standalone`. Vérifier que le serveur pointe bien sur `server.js` et non sur un fichier statique.

Si Traefik retourne 404 :
```yaml
# Dans portainer-stack.yml, vérifier le label Traefik :
traefik.http.routers.frontend.rule=Host(`app.xpeditis.com`)
traefik.http.services.frontend.loadbalancer.server.port=3000
```

### Migrations échouent

```bash
docker exec -it xpeditis-backend sh
cd /app && npm run migration:run
```

Si blocage : vérifier que PostgreSQL est accessible (`DATABASE_HOST` = nom du service Docker).

### Registry pull échoue (401)

1. Vérifier le token Scaleway (peut expirer)
2. Portainer → Registries → rafraîchir les credentials
3. `docker login rg.fr-par.scw.cloud/weworkstudio`

### ARM64 / multi-architecture

Les Dockerfiles sont compatibles AMD64 et ARM64. Si le build échoue sur ARM64 :
- Vérifier que `buildx` est installé et activé
- Utiliser le builder multi-platform : `docker buildx create --use`

---

## CI/CD GitHub Actions

Le workflow `.github/workflows/ci.yml` exécute en automatique :
1. Lint + type-check
2. Tests unitaires (backend + frontend)
3. Build des images Docker
4. Push vers registry Scaleway (sur merge vers `main` ou `preprod`)

Variables GitHub Actions requises (Settings → Secrets) :
```
SCALEWAY_REGISTRY_TOKEN
PORTAINER_URL
PORTAINER_API_KEY
PORTAINER_STACK_ID
```

---

## Coûts d'infrastructure estimés

| Option | Coût/mois | Notes |
|--------|-----------|-------|
| Hetzner CAX21 (ARM64) | ~8€ | Recommandé pour preprod |
| Hetzner CX31 (AMD64) | ~12€ | Production |
| Scaleway Registry | Gratuit | Jusqu'à 1GB |

Voir [../deployment/hetzner/README.md](hetzner/README.md) pour le déploiement Kubernetes sur Hetzner.
