# Déploiement Novelia, VPS Apache + Docker

Trois fichiers + un patch :

- [Dockerfile](../Dockerfile), build standalone Next.js 16
- [docker-compose.yml](../docker-compose.yml), service unique `web` bindé sur `127.0.0.1:3000`
- [deploy/apache/novelia.conf](apache/novelia.conf), VirtualHosts apex + www + app
- [.github/workflows/deploy.yml](../.github/workflows/deploy.yml), CI/CD SSH

Patch appliqué : [next.config.ts](../next.config.ts) reçoit `output: "standalone"` pour produire un build autonome embarquable dans Docker.

---

## 1. Préparation VPS (à faire une fois)

```bash
# Docker + compose plugin
curl -fsSL https://get.docker.com | sh
sudo apt-get install -y docker-compose-plugin

# Apache modules
sudo a2enmod proxy proxy_http proxy_wstunnel ssl headers rewrite http2 remoteip
sudo systemctl reload apache2

# Utilisateur deploy (ne pas utiliser root)
sudo adduser --disabled-password --gecos "" deploy
sudo usermod -aG docker deploy

# Dossier projet
sudo mkdir -p /var/www/html/novelia
sudo chown deploy:deploy /var/www/html/novelia
```

## 2. Cloner le repo + secrets

En SSH avec le user `deploy` :

```bash
cd /var/www/html/novelia
git clone git@github.com:<ton-org>/novelia.git .

# Variables d'env de prod (gitignored)
cp .env.production.example .env.production
nano .env.production
```

Renseigner au minimum :

| Variable             | Valeur                                                          |
| -------------------- | --------------------------------------------------------------- |
| `POSTGRES_USER`      | `novelia`                                                       |
| `POSTGRES_PASSWORD`  | Mot de passe Postgres (generer avec `openssl rand -base64 24`)  |
| `POSTGRES_DB`        | `novelia`                                                       |
| `DATABASE_URL`       | `postgres://novelia:<MDP>@db:5432/novelia` (inliner le MDP)     |
| `BETTER_AUTH_SECRET` | Secret de signature (generer avec `openssl rand -base64 32`)    |
| `BETTER_AUTH_URL`    | `https://agence-novelia.fr`                                     |
| `ANTHROPIC_API_KEY`  | Cle Anthropic (admin/realisations)                              |

**Important :** `DATABASE_URL` doit contenir le mot de passe en clair. Le format env_file ne fait PAS d'interpolation `${POSTGRES_PASSWORD}` : il faut recopier le mot de passe directement dans la chaine.

## 3. Certificat Cloudflare Origin

Dans le dashboard Cloudflare : **SSL/TLS > Origin Server > Create Certificate**. Choisir RSA 2048, validité 15 ans, hostnames `novelia.fr, *.novelia.fr`.

```bash
sudo mkdir -p /etc/ssl/cloudflare
sudo nano /etc/ssl/cloudflare/novelia.fr.pem    # coller "Origin Certificate"
sudo nano /etc/ssl/cloudflare/novelia.fr.key    # coller "Private key"
sudo chmod 600 /etc/ssl/cloudflare/novelia.fr.key

sudo curl -o /etc/ssl/cloudflare/cloudflare-origin-ca.pem \
  https://developers.cloudflare.com/ssl/static/origin_ca_rsa_root.pem
```

Dans Cloudflare > SSL/TLS > Overview, passer le mode en **Full (Strict)**.

## 4. Activer le VirtualHost Apache

```bash
sudo cp /var/www/html/novelia/deploy/apache/novelia.conf /etc/apache2/sites-available/
sudo a2ensite novelia.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
```

## 5. Premier lancement

```bash
cd /var/www/html/novelia
docker compose build
docker compose up -d
docker compose ps
docker compose logs -f web   # verifier que Next ecoute sur :3000
```

Au demarrage, l'entrypoint applique automatiquement les migrations Drizzle. Tu dois voir :

```
[entrypoint] DATABASE_URL detectee, application des migrations...
[migrate] Application des migrations...
[migrate] OK.
[entrypoint] Demarrage du serveur Next...
```

Visite `https://agence-novelia.fr`. Si erreur 502, c'est qu'Apache n'arrive pas a joindre `127.0.0.1:3010` : `curl -I http://127.0.0.1:3010` doit repondre.

### Seed du compte admin (une seule fois)

```bash
cd /var/www/html/novelia
docker compose exec -e ADMIN_PASSWORD='<le-mot-de-passe>' web node scripts/seed-admin.mjs
```

Le compte cree :
- email : `contact@agence-novelia.fr` (modifiable via `ADMIN_EMAIL`)
- role : `admin`

Le script est idempotent : si le compte existe deja avec un autre role, il est promu.

## 6. CI/CD GitHub

Crée une paire de clés SSH dédiée au déploiement (pas ta clé perso) :

```bash
# Sur ta machine
ssh-keygen -t ed25519 -f ~/.ssh/novelia_deploy -N "" -C "github-deploy"

# Coller la clé publique sur le VPS, user deploy
ssh-copy-id -i ~/.ssh/novelia_deploy.pub deploy@<IP_VPS>
```

Dans **Settings > Secrets and variables > Actions** du repo GitHub, créer :

| Secret      | Valeur                                       |
| ----------- | -------------------------------------------- |
| `SSH_HOST`  | IP ou hostname du VPS                        |
| `SSH_USER`  | `deploy`                                     |
| `SSH_KEY`   | Contenu de `~/.ssh/novelia_deploy` (privée)  |
| `SSH_PORT`  | (optionnel, défaut 22)                       |

Sur le VPS, autoriser le `deploy_key` à cloner le repo : copie la clé publique dans **GitHub repo > Settings > Deploy keys** (lecture seule suffit).

Désormais chaque `git push origin main` déclenche le workflow [.github/workflows/deploy.yml](../.github/workflows/deploy.yml) qui SSH sur le VPS, fait `git reset --hard origin/main`, rebuild l'image et relance le service.

## 7. Mise à jour manuelle (sans push)

```bash
ssh deploy@<IP_VPS>
cd /var/www/html/novelia
git pull
docker compose up -d --build
```

## Notes

- **RAM** : le build Next + Tailwind consomme jusqu'à 3 GB. Sur un VPS ≤ 2 GB de RAM, créer 2 GB de swap (`fallocate -l 2G /swapfile && mkswap /swapfile && swapon /swapfile`).
- **Logs Docker** : limités à 10 MB × 5 fichiers par conteneur (cf. `logging` dans le compose).
- **Cloudflare IPs** : la liste dans le `.conf` est à jour 2026-Q1, à rafraîchir depuis https://www.cloudflare.com/ips/.
- **Rollback** : `cd /var/www/html/novelia && git reset --hard <sha>` puis `docker compose up -d --build`.
