# Déploiement production — configuration et mise en service

Guide pas à pas pour livrer VIIZIA en production et tester l’application (connexion, reset mot de passe, envoi d’e-mails).

> **Rappel dev vs prod**
> - **Dev local** : `.env.local` (MailHog, Docker, ports 8180…)
> - **Production** : `.env.prod.local` sur le serveur (SMTP réel, BDD prod, HTTPS)
> - Ne **jamais** copier `.env.local` en prod ni committer de secrets.

---

## 1. Principe : où mettre la config prod

Symfony charge les fichiers d’environnement dans cet ordre (le dernier l’emporte) :

| Fichier | Rôle | Commité ? |
|---|---|---|
| `.env` | Valeurs par défaut (dev) | Oui |
| `.env.local` | Surcharges **machine de dev** | Non |
| `.env.prod` | Valeurs prod **sans secret** (optionnel) | Oui |
| **`.env.prod.local`** | **Secrets et config prod** | **Non** |
| Variables d’environnement du serveur | Prioritaires sur tout | — |

**En pratique** : créez **un seul fichier** sur le serveur de prod :

```
/var/www/viizia/.env.prod.local
```

Les fichiers YAML (`config/packages/mailer.yaml`, `config/services.yaml`) **ne contiennent pas** de host, user ou password : ils lisent des variables d’environnement (`MAILER_DSN`, `MAILER_FROM`, etc.). **Inutile de modifier le code PHP** pour la config mail ou BDD.

---

## 2. Étape 1 — Rassembler les informations

Avant de toucher au serveur, préparez :

| Variable | Exemple | Usage |
|---|---|---|
| URL publique HTTPS | `https://app.viizia.fr` | Liens dans les e-mails (reset mot de passe) |
| MySQL — host | `127.0.0.1` ou `mysql.example.com` | Connexion BDD |
| MySQL — port | `3306` | Connexion BDD |
| MySQL — user / password | `viizia` / `***` | Connexion BDD |
| MySQL — nom BDD | `viizia` | Connexion BDD |
| SMTP — host | `smtp-relay.brevo.com` | Envoi d’e-mails |
| SMTP — port | `587` (TLS) ou `465` (SSL) | Envoi d’e-mails |
| SMTP — user / password | login SMTP / clé SMTP | Authentification |
| Encryption | `tls` ou `ssl` | Chiffrement SMTP |
| `MAILER_FROM` | `noreply@votre-domaine.fr` | Expéditeur (doit être autorisé chez le fournisseur) |
| `MAILER_FROM_NAME` | `VIIZIA` | Nom affiché de l’expéditeur |

Générez un secret Symfony (32 caractères minimum) :

```bash
openssl rand -hex 32
```

Conservez le résultat pour `APP_SECRET`.

---

## 3. Étape 2 — Créer `.env.prod.local` sur le serveur

Sur le serveur, à la **racine du projet** (à côté de `composer.json`, `public/`, etc.) :

```bash
cd /chemin/vers/viizia
nano .env.prod.local
chmod 600 .env.prod.local
```

Contenu type à adapter :

```env
###> symfony/framework-bundle ###
APP_ENV=prod
APP_DEBUG=0
APP_SECRET=collez-ici-le-resultat-de-openssl-rand-hex-32
###< symfony/framework-bundle ###

###> symfony/routing ###
# URL publique HTTPS — indispensable pour les liens dans les e-mails
DEFAULT_URI=https://app.viizia.fr
###< symfony/routing ###

###> doctrine/doctrine-bundle ###
DATABASE_URL="mysql://USER:PASSWORD@HOST:3306/NOM_BDD?serverVersion=8.0&charset=utf8mb4"
###< doctrine/doctrine-bundle ###

###> symfony/messenger ###
MESSENGER_TRANSPORT_DSN=doctrine://default
###< symfony/messenger ###

###> symfony/mailer ###
# Port 587 + STARTTLS (cas le plus courant) :
MAILER_DSN="smtp://SMTP_USER:SMTP_PASSWORD@SMTP_HOST:587?encryption=tls"

# Port 465 + SSL (si votre hébergeur l’exige) — décommenter et commenter la ligne ci-dessus :
# MAILER_DSN="smtps://SMTP_USER:SMTP_PASSWORD@SMTP_HOST:465"

MAILER_FROM=noreply@votre-domaine.fr
MAILER_FROM_NAME=VIIZIA
###< symfony/mailer ###
```

### Encodage des caractères spéciaux dans `MAILER_DSN`

Le mot de passe SMTP est dans une URL. Encodez les caractères spéciaux :

| Caractère | Encodage |
|---|---|
| `@` | `%40` |
| `!` | `%21` |
| `#` | `%23` |
| `%` | `%25` |
| `:` | `%3A` |

Exemple : mot de passe `P@ss!word` → `P%40ss%21word`

### Exemples `MAILER_DSN` par fournisseur

**Brevo (ex-Sendinblue), port 587 :**

```env
MAILER_DSN="smtp://votre-login@votre-domaine.fr:CLE_SMTP@smtp-relay.brevo.com:587?encryption=tls"
```

**OVH, port 587 :**

```env
MAILER_DSN="smtp://votre-email@votre-domaine.fr:MOT_DE_PASSE@ssl0.ovh.net:587?encryption=tls"
```

**OVH, port 465 :**

```env
MAILER_DSN="smtps://votre-email@votre-domaine.fr:MOT_DE_PASSE@ssl0.ovh.net:465"
```

> **`MAILER_FROM`** doit correspondre à une adresse **validée / autorisée** chez votre fournisseur SMTP, sinon les e-mails seront rejetés ou classés spam.

---

## 4. Étape 3 — Déployer le code

Sur le serveur (ou via CI), dans le dossier du projet :

```bash
git pull origin master   # ou la branche de production

composer install --no-dev --optimize-autoloader

php bin/console doctrine:migrations:migrate --no-interaction --env=prod

php bin/console cache:clear --env=prod
php bin/console cache:warmup --env=prod
```

### Web server

- La racine documentaire doit pointer vers **`public/`** (pas la racine du dépôt).
- HTTPS obligatoire en prod (`Strict-Transport-Security`, cookies `secure` — cf. [security-checklist.md](security-checklist.md)).

---

## 5. Étape 4 — Vérifier la config

### Environnement Symfony

```bash
php bin/console about --env=prod
```

Attendu :

- **Environment** : `prod`
- **Debug** : `false`

### Test d’envoi d’e-mail (si disponible)

```bash
php bin/console mailer:test votre-email@example.com --env=prod
```

Sinon, passez directement au test fonctionnel (étape 5).

---

## 6. Étape 5 — Test fonctionnel en prod

Checklist manuelle après déploiement :

1. [ ] Ouvrir `https://votre-domaine.fr/login`
2. [ ] Se connecter avec un compte existant
3. [ ] Cliquer **Mot de passe oublié ?**
4. [ ] Saisir un e-mail connu → message « Vérifiez votre boîte mail »
5. [ ] Recevoir l’e-mail (vérifier aussi les spams)
6. [ ] Vérifier que le lien commence par **`https://votre-domaine.fr/reset-password/...`** (pas `localhost`)
7. [ ] Définir un nouveau mot de passe → redirection login + flash succès
8. [ ] Se connecter avec le **nouveau** mot de passe

---

## 7. Dépannage

| Symptôme | Cause probable | Action |
|---|---|---|
| Lien e-mail pointe vers `localhost` | `DEFAULT_URI` incorrect ou absent | Corriger dans `.env.prod.local`, vider le cache prod |
| E-mail non reçu | `MAILER_DSN` incorrect | Vérifier host, port, user, password, encryption |
| E-mail rejeté / spam | Expéditeur non autorisé | Valider `MAILER_FROM` chez le fournisseur SMTP |
| Erreur connexion BDD | `DATABASE_URL` incorrect | Vérifier host, user, password, nom BDD |
| Formulaire reset sans effet | Cache prod obsolète | `php bin/console cache:clear --env=prod` |
| Erreur 500 | Exception non visible | Consulter `var/log/prod.log` sur le serveur |
| « Lien expiré » immédiatement | Jeton déjà consommé ou > 1 h | Demander un **nouveau** lien via `/forgot-password` |

---

## 8. Déploiement Docker en production

Le projet local utilise Docker + MailHog (cf. [docker-conventions.md](docker-conventions.md)). En prod :

- **Option A (recommandée)** : VPS classique, PHP-FPM + nginx, fichier `.env.prod.local` sur le serveur.
- **Option B** : Docker prod — monter le code et créer `.env.prod.local` dans le volume, **ou** passer les variables en env du conteneur PHP.

Dans `compose.yaml`, les variables `DATABASE_URL` et `MAILER_DSN` **ne sont pas** injectées volontairement dans le conteneur : Symfony charge `.env` + `.env.prod.local` depuis le volume du projet.

Si vous injectez des variables au niveau du conteneur, elles **écrasent** les fichiers `.env` (priorité maximale).

---

## 9. Variables lues par l’application

Récapitulatif des variables utilisées directement par VIIZIA :

| Variable | Fichier de config | Rôle |
|---|---|---|
| `APP_ENV` | Framework | `prod` en production |
| `APP_DEBUG` | Framework | `0` en production |
| `APP_SECRET` | Framework | Signature CSRF, cookies, etc. |
| `DEFAULT_URI` | `config/packages/routing.yaml` | URL absolues (e-mails reset password) |
| `DATABASE_URL` | `config/packages/doctrine.yaml` | Connexion MySQL |
| `MAILER_DSN` | `config/packages/mailer.yaml` | Transport SMTP |
| `MAILER_FROM` | `config/services.yaml` | Adresse expéditeur |
| `MAILER_FROM_NAME` | `config/services.yaml` | Nom expéditeur |

Routes concernées par le mailer :

- `GET|POST /forgot-password`
- `GET|POST /reset-password/reset/{token?}`

---

## 10. Checklist avant go-live

- [ ] `.env.prod.local` créé sur le serveur, permissions `600`
- [ ] Aucun secret dans Git (`.env.local`, `.env.prod.local` ignorés)
- [ ] `APP_ENV=prod`, `APP_DEBUG=0`
- [ ] `DEFAULT_URI` = URL HTTPS publique réelle
- [ ] Migrations exécutées (`doctrine:migrations:migrate --env=prod`)
- [ ] Cache prod vidé et réchauffé
- [ ] HTTPS actif, webroot = `public/`
- [ ] Test login OK
- [ ] Test mot de passe oublié + réception e-mail OK
- [ ] Test reset mot de passe + connexion avec nouveau mot de passe OK

Voir aussi : [security-checklist.md](security-checklist.md), section « Déploiement ».

---

## 11. Références

- [docker-conventions.md](docker-conventions.md) — environnement de dev local
- [security-checklist.md](security-checklist.md) — contrôles sécurité avant merge / prod
- [git-workflow.md](git-workflow.md) — fichiers `.env*` et `.gitignore`
- [Symfony — Configuration based on environment](https://symfony.com/doc/current/configuration.html#configuration-based-on-environment)
- [Symfony — Sending Emails](https://symfony.com/doc/current/mailer.html)
