# Guide de déploiement OVH (MG-120)

Cible : hébergement **mutualisé OVH**, PHP 8.3, MySQL 8, accès SSH.

---

## 1. Pré-requis côté OVH

### Vérifier la version de PHP

Dans l'espace client OVH → *Hébergements* → votre hébergement → onglet
*Multisite* → modifier le domaine → **PHP 8.3**.

En SSH, contrôler :

```bash
php -v          # doit afficher 8.3.x
php -m | grep -E 'pdo_mysql|intl|gd|zip|opcache|exif'
```

Les six extensions doivent être présentes. `intl` et `gd` manquent parfois sur
les offres d'entrée de gamme : sans elles, Symfony et LiipImagine ne démarrent pas.

### Créer la base de données

Espace client → *Bases de données* → *Créer une base de données*.

- Moteur : **MySQL 8.0**
- Nom : `maudgaquere` (OVH préfixe automatiquement)
- Noter **serveur, nom, utilisateur et mot de passe** : ils iront dans `.env.prod.local`

> Le serveur n'est pas `localhost` chez OVH mais quelque chose comme
> `maudgaquere.mysql.db`. C'est la cause d'échec la plus fréquente.

### Activer l'accès SSH

Espace client → *Hébergements* → onglet *FTP - SSH* → activer SSH.
Puis déposer sa clé publique :

```bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub monlogin@ftp.cluster0XX.hosting.ovh.net
ssh monlogin@ftp.cluster0XX.hosting.ovh.net
```

---

## 2. Arborescence

Sur un mutualisé OVH, le domaine pointe vers un dossier précis. **Le dossier
racine du domaine doit être `public/`, pas la racine du projet** : sinon
`.env.prod.local`, `vendor/` et `var/` seraient accessibles depuis le web.

Configuration recommandée :

```
~/www/            ← racine du domaine configurée sur ~/www/gaquere/public
~/gaquere/        ← le projet
    public/       ← dossier racine du domaine
    src/
    var/
    vendor/
    .env.prod.local
```

Dans l'espace client → *Multisite* → modifier le domaine → **Répertoire racine** :
`gaquere/public`.

> Si l'offre ne permet pas de changer le répertoire racine, déposer le contenu
> de `public/` dans `~/www/` et le reste du projet **au-dessus** de `www/`,
> puis ajuster les chemins dans `public/index.php`.

---

## 3. Premier déploiement

### Récupérer le code

```bash
cd ~
git clone git@github.com:VOTRE-COMPTE/gaquere.git
cd gaquere
```

(Voir `infra/GIT_SSH_SETUP.md` pour la clé de déploiement.)

### Configurer l'environnement

```bash
cp deploy/.env.prod.template .env.prod.local
nano .env.prod.local
chmod 600 .env.prod.local      # le fichier contient des secrets
```

Renseigner au minimum `APP_SECRET`, `DATABASE_URL`, `MAILER_DSN`,
`DOCTOLIB_URL` et les clés hCaptcha.

Générer un `APP_SECRET` :

```bash
php -r 'echo bin2hex(random_bytes(16)), PHP_EOL;'
```

### Installer et préparer

```bash
composer install --no-dev --optimize-autoloader
php bin/console cache:clear --env=prod
php bin/console doctrine:migrations:migrate --no-interaction --env=prod
```

### Créer le compte d'administration

Les fixtures sont un outil de développement : **ne jamais les charger en
production**, elles effacent la base. Créer le compte à la main :

```bash
php bin/console doctrine:query:sql "
  INSERT INTO user (email, roles, password, nom, prenom)
  VALUES ('maud@exemple.fr', '[\"ROLE_SUPER_ADMIN\"]', 'PLACEHOLDER', 'Gaquère', 'Maud')
" --env=prod
```

puis générer un vrai mot de passe haché :

```bash
php bin/console security:hash-password --env=prod
```

et remplacer `PLACEHOLDER` par le résultat.

> Plus simple : créer le compte en local, exporter la ligne, l'importer.

### Contenu initial

Les neuf pages, les trois ateliers et les quatorze questions n'existent pas en
production. Deux possibilités :

1. exporter les tables `page`, `atelier` et `faq` depuis la base de
   développement et les importer ;
2. les ressaisir depuis le back-office.

L'export est plus sûr :

```bash
# en local
docker compose exec mysql mysqldump -uroot -proot maud_gaquere \
  page atelier faq > contenu-initial.sql

# sur le serveur
mysql -h SERVEUR -u UTILISATEUR -p BASE < contenu-initial.sql
```

### Assets

Les fichiers de `public/build/` sont générés par Webpack Encore. Le serveur
mutualisé n'a pas Node : **les construire en local et les committer**, ou les
téléverser :

```bash
# en local
npm run build
rsync -avz public/build/ monlogin@ftp.clusterXXX:~/gaquere/public/build/
```

Ne pas oublier `public/images/` (visuels et variantes WebP).

### Droits d'écriture

```bash
chmod -R 775 var/
chmod -R 775 public/uploads/
```

---

## 4. Déploiements suivants

Utiliser `deploy/deploy.sh` (voir ce fichier).

---

## 5. Tâches planifiées

Espace client OVH → *Hébergements* → onglet *Tâches planifiées*.

### Purge RGPD (MG-092) — obligatoire

| Réglage | Valeur |
|---|---|
| Commande | `~/gaquere/bin/console app:purge-contacts --env=prod` |
| Langage | PHP 8.3 |
| Fréquence | une fois par mois |
| Connexion | SSH |

C'est cette tâche qui rend vraie la promesse de conservation limitée à trois
ans affichée dans la politique de confidentialité.

### Worker Messenger — non nécessaire

Les e-mails partent **synchronement** (voir `config/packages/messenger.yaml`) :
aucun worker à faire tourner. Si un jour le volume le justifie, rétablir le
routage asynchrone et ajouter :

```
~/gaquere/bin/console messenger:consume async --time-limit=300 --env=prod
```

toutes les 5 minutes.

---

## 6. Vérification

Dérouler `deploy/VERIFICATION_PROD.md`.

---

## 7. Dépannage

| Symptôme | Cause probable |
|---|---|
| Page blanche | `var/` non inscriptible, ou `APP_ENV` resté en `dev` |
| « Unable to connect to database » | serveur MySQL OVH mal renseigné (ce n'est pas `localhost`) |
| 500 sur toutes les pages | `composer install` non lancé, ou cache prod non vidé |
| CSS et JS absents | `public/build/` non téléversé |
| Images absentes | `public/images/` non téléversé |
| Uploads impossibles | droits sur `public/uploads/` |
| Formulaire sans style d'erreur | normal : Symfony renvoie 422, la page se réaffiche |
| E-mails non reçus | `MAILER_DSN` — voir `infra/EMAILS_OVH_GUIDE.md` |

Consulter les logs :

```bash
tail -50 ~/gaquere/var/log/prod.log
tail -50 ~/logs/*.error.log      # logs Apache OVH
```
