# Guide de Construction des Images Docker - Xpeditis

Ce guide explique comment construire les images Docker pour backend et frontend.

---

## 📋 Prérequis

### 1. Docker Installé
```bash
docker --version
# Docker version 24.0.0 ou supérieur
```

### 2. Docker Registry Access
- **Docker Hub**: Créer un compte sur https://hub.docker.com
- **Ou** GitHub Container Registry (GHCR)
- **Ou** Registry privé

### 3. Login au Registry
```bash
# Docker Hub
docker login

# GitHub Container Registry
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin

# Registry privé
docker login registry.example.com
```

---

## 🚀 Méthode 1: Script Automatique (Recommandé)

### Build Staging

```bash
# Build seulement (pas de push)
./docker/build-images.sh staging

# Build ET push vers Docker Hub
./docker/build-images.sh staging --push
```

### Build Production

```bash
# Build seulement
./docker/build-images.sh production

# Build ET push
./docker/build-images.sh production --push
```

### Configuration du Registry

Par défaut, le script utilise `docker.io/xpeditis` comme registry.

Pour changer:
```bash
export DOCKER_REGISTRY=ghcr.io
export DOCKER_REPO=your-org
./docker/build-images.sh staging --push
```

---

## 🛠️ Méthode 2: Build Manuel

### Backend Image

```bash
cd apps/backend

# Staging
docker build \
  --file Dockerfile \
  --tag xpeditis/backend:staging-latest \
  --platform linux/amd64 \
  .

# Production
docker build \
  --file Dockerfile \
  --tag xpeditis/backend:latest \
  --platform linux/amd64 \
  .
```

### Frontend Image

```bash
cd apps/frontend

# Staging
docker build \
  --file Dockerfile \
  --tag xpeditis/frontend:staging-latest \
  --build-arg NEXT_PUBLIC_API_URL=https://api-staging.xpeditis.com \
  --build-arg NEXT_PUBLIC_APP_URL=https://staging.xpeditis.com \
  --build-arg NEXT_PUBLIC_SENTRY_ENVIRONMENT=staging \
  --platform linux/amd64 \
  .

# Production
docker build \
  --file Dockerfile \
  --tag xpeditis/frontend:latest \
  --build-arg NEXT_PUBLIC_API_URL=https://api.xpeditis.com \
  --build-arg NEXT_PUBLIC_APP_URL=https://xpeditis.com \
  --build-arg NEXT_PUBLIC_SENTRY_ENVIRONMENT=production \
  --platform linux/amd64 \
  .
```

### Push Images

```bash
# Backend
docker push xpeditis/backend:staging-latest
docker push xpeditis/backend:latest

# Frontend
docker push xpeditis/frontend:staging-latest
docker push xpeditis/frontend:latest
```

---

## 🧪 Tester les Images Localement

### 1. Créer un network Docker

```bash
docker network create xpeditis-test
```

### 2. Lancer PostgreSQL

```bash
docker run -d \
  --name postgres-test \
  --network xpeditis-test \
  -e POSTGRES_DB=xpeditis_test \
  -e POSTGRES_USER=xpeditis \
  -e POSTGRES_PASSWORD=test123 \
  -p 5432:5432 \
  postgres:15-alpine
```

### 3. Lancer Redis

```bash
docker run -d \
  --name redis-test \
  --network xpeditis-test \
  -p 6379:6379 \
  redis:7-alpine \
  redis-server --requirepass test123
```

### 4. Lancer Backend

```bash
docker run -d \
  --name backend-test \
  --network xpeditis-test \
  -e NODE_ENV=development \
  -e PORT=4000 \
  -e DATABASE_HOST=postgres-test \
  -e DATABASE_PORT=5432 \
  -e DATABASE_NAME=xpeditis_test \
  -e DATABASE_USER=xpeditis \
  -e DATABASE_PASSWORD=test123 \
  -e REDIS_HOST=redis-test \
  -e REDIS_PORT=6379 \
  -e REDIS_PASSWORD=test123 \
  -e JWT_SECRET=test-secret-key-256-bits-minimum-length-required \
  -e CORS_ORIGIN=http://localhost:3000 \
  -p 4000:4000 \
  xpeditis/backend:staging-latest
```

### 5. Lancer Frontend

```bash
docker run -d \
  --name frontend-test \
  --network xpeditis-test \
  -e NODE_ENV=development \
  -e NEXT_PUBLIC_API_URL=http://localhost:4000 \
  -e NEXT_PUBLIC_APP_URL=http://localhost:3000 \
  -e API_URL=http://backend-test:4000 \
  -p 3000:3000 \
  xpeditis/frontend:staging-latest
```

### 6. Vérifier

```bash
# Backend health check
curl http://localhost:4000/health

# Frontend
curl http://localhost:3000/api/health

# Ouvrir dans navigateur
open http://localhost:3000
```

### 7. Voir les logs

```bash
docker logs -f backend-test
docker logs -f frontend-test
```

### 8. Nettoyer

```bash
docker stop backend-test frontend-test postgres-test redis-test
docker rm backend-test frontend-test postgres-test redis-test
docker network rm xpeditis-test
```

---

## 📊 Optimisation des Images

### Tailles d'Images Typiques

- **Backend**: ~150-200 MB (après compression)
- **Frontend**: ~120-150 MB (après compression)
- **Total**: ~300 MB (pour les 2 images)

### Multi-Stage Build

Les Dockerfiles utilisent des builds multi-stage:

1. **Stage Dependencies**: Installation des dépendances
2. **Stage Builder**: Compilation TypeScript/Next.js
3. **Stage Production**: Image finale (seulement le nécessaire)

Avantages:
- ✅ Images légères (pas de dev dependencies)
- ✅ Build rapide (cache des layers)
- ✅ Sécurisé (pas de code source dans prod)

### Build Cache

Pour accélérer les builds:

```bash
# Build avec cache
docker build --cache-from xpeditis/backend:staging-latest -t xpeditis/backend:staging-latest .

# Ou avec BuildKit (plus rapide)
DOCKER_BUILDKIT=1 docker build -t xpeditis/backend:staging-latest .
```

### Scan de Vulnérabilités

```bash
# Scan avec Docker Scout (gratuit)
docker scout cves xpeditis/backend:staging-latest

# Scan avec Trivy
trivy image xpeditis/backend:staging-latest
```

---

## 🔄 CI/CD Integration

### GitHub Actions Example

Voir `.github/workflows/docker-build.yml` (à créer):

```yaml
name: Build and Push Docker Images

on:
  push:
    branches:
      - main
      - develop

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and Push
        run: |
          if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
            ./docker/build-images.sh production --push
          else
            ./docker/build-images.sh staging --push
          fi
```

---

## 🐛 Dépannage

### Problème 1: Build échoue avec erreur "npm ci"

**Symptôme**: `npm ci` failed with exit code 1

**Solution**:
```bash
# Nettoyer le cache Docker
docker builder prune -a

# Rebuild sans cache
docker build --no-cache -t xpeditis/backend:staging-latest apps/backend/
```

### Problème 2: Image trop grosse (>500 MB)

**Symptôme**: Image très volumineuse

**Solution**:
- Vérifier que `.dockerignore` est présent
- Vérifier que `node_modules` n'est pas copié
- Utiliser `npm ci` au lieu de `npm install`

```bash
# Analyser les layers
docker history xpeditis/backend:staging-latest
```

### Problème 3: Next.js standalone build échoue

**Symptôme**: `Error: Cannot find module './standalone/server.js'`

**Solution**:
- Vérifier que `next.config.js` a `output: 'standalone'`
- Rebuild frontend:
```bash
cd apps/frontend
npm run build
# Vérifier que .next/standalone existe
ls -la .next/standalone
```

### Problème 4: CORS errors en production

**Symptôme**: Frontend ne peut pas appeler le backend

**Solution**:
- Vérifier `CORS_ORIGIN` dans backend
- Vérifier `NEXT_PUBLIC_API_URL` dans frontend
- Tester avec curl:
```bash
curl -H "Origin: https://staging.xpeditis.com" \
     -H "Access-Control-Request-Method: GET" \
     -X OPTIONS \
     https://api-staging.xpeditis.com/health
```

### Problème 5: Health check fails

**Symptôme**: Container restart en boucle

**Solution**:
```bash
# Voir les logs
docker logs backend-test

# Tester health check manuellement
docker exec backend-test curl -f http://localhost:4000/health

# Si curl manque, installer:
docker exec backend-test apk add curl
```

---

## 📚 Ressources

- **Dockerfile Best Practices**: https://docs.docker.com/develop/dev-best-practices/
- **Next.js Docker**: https://nextjs.org/docs/deployment#docker-image
- **NestJS Docker**: https://docs.nestjs.com/recipes/docker
- **Docker Build Reference**: https://docs.docker.com/engine/reference/commandline/build/

---

## 🔐 Sécurité

### Ne PAS Inclure dans les Images

❌ Secrets (JWT_SECRET, API keys)
❌ Fichiers `.env`
❌ Code source TypeScript (seulement JS compilé)
❌ node_modules de dev
❌ Tests et mocks
❌ Documentation

### Utiliser

✅ Variables d'environnement au runtime
✅ Docker secrets (si Swarm)
✅ Kubernetes secrets (si K8s)
✅ AWS Secrets Manager / Vault
✅ Non-root user dans container
✅ Health checks
✅ Resource limits

---

## 📈 Métriques de Build

Après chaque build, vérifier:

```bash
# Taille des images
docker images | grep xpeditis

# Layers count
docker history xpeditis/backend:staging-latest | wc -l

# Scan vulnérabilités
docker scout cves xpeditis/backend:staging-latest
```

**Objectifs**:
- ✅ Backend < 200 MB
- ✅ Frontend < 150 MB
- ✅ Build time < 5 min
- ✅ Zéro vulnérabilité critique

---

*Dernière mise à jour*: 2025-10-14
*Version*: 1.0.0
