From 29a29a5074ca9c765b5a38f8b08cf8e6a584f168 Mon Sep 17 00:00:00 2001 From: Julien Gautier Date: Mon, 27 Apr 2026 00:20:50 +0200 Subject: [PATCH] docs: add complete production deployment guide --- docs/DEPLOYMENT.md | 387 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 docs/DEPLOYMENT.md diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md new file mode 100644 index 0000000..d5b2265 --- /dev/null +++ b/docs/DEPLOYMENT.md @@ -0,0 +1,387 @@ +# Guide de mise en production — Adastra + +Serveur cible : VPS Debian 11, Apache, MySQL déjà installés. +Stack : Node.js/Express (API) + Angular 18 (frontend). + +--- + +## Table des matières + +1. [Prérequis serveur](#1-prérequis-serveur) +2. [Base de données MySQL](#2-base-de-données-mysql) +3. [Base de données MongoDB](#3-base-de-données-mongodb) +4. [Déploiement de l'API](#4-déploiement-de-lapi) +5. [Déploiement du frontend](#5-déploiement-du-frontend) +6. [Configuration Apache](#6-configuration-apache) +7. [HTTPS avec Let's Encrypt](#7-https-avec-lets-encrypt) +8. [PM2 — démarrage automatique](#8-pm2--démarrage-automatique) +9. [Procédure de mise à jour](#9-procédure-de-mise-à-jour) + +--- + +## 1. Prérequis serveur + +### Node.js (via nvm — recommandé) + +```bash +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash +source ~/.bashrc +nvm install 20 +nvm use 20 +nvm alias default 20 +node -v # doit afficher v20.x.x +``` + +### PM2 (gestionnaire de process Node) + +```bash +npm install -g pm2 +``` + +### MongoDB + +L'API utilise à la fois MySQL et MongoDB. MongoDB n'est pas fourni par les dépôts Debian 11 par défaut. + +```bash +# Clé GPG et dépôt MongoDB 7 +curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \ + gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor + +echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/debian bullseye/mongodb-org/7.0 main" \ + | tee /etc/apt/sources.list.d/mongodb-org-7.0.list + +apt update && apt install -y mongodb-org +systemctl enable --now mongod +mongod --version +``` + +### Modules Apache nécessaires + +```bash +a2enmod proxy proxy_http rewrite headers ssl +systemctl restart apache2 +``` + +--- + +## 2. Base de données MySQL + +MySQL est déjà installé. Créer la base et l'utilisateur dédié. + +```sql +-- En tant que root MySQL +CREATE DATABASE adastra_prod CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE USER 'adastra'@'localhost' IDENTIFIED BY 'MOT_DE_PASSE_FORT'; +GRANT ALL PRIVILEGES ON adastra_prod.* TO 'adastra'@'localhost'; +FLUSH PRIVILEGES; +``` + +Les migrations Sequelize (voir [section 4](#4-déploiement-de-lapi)) créeront le schéma. + +--- + +## 3. Base de données MongoDB + +```bash +# Créer la base et l'utilisateur applicatif +mongosh <<'EOF' +use adastradb +db.createUser({ + user: "adastra", + pwd: "MOT_DE_PASSE_FORT", + roles: [{ role: "readWrite", db: "adastradb" }] +}) +EOF +``` + +Activer l'authentification MongoDB si elle n'est pas encore activée : + +```bash +# /etc/mongod.conf +security: + authorization: enabled +``` + +```bash +systemctl restart mongod +``` + +La `MONGODB_URI` dans le `.env` devient alors : +``` +MONGODB_URI=mongodb://adastra:MOT_DE_PASSE_FORT@localhost:27017/adastradb +``` + +--- + +## 4. Déploiement de l'API + +### Récupérer le code + +```bash +mkdir -p /var/www +cd /var/www +git clone adastra_api +cd adastra_api +git checkout master # ou la branche de production +npm install --omit=dev +``` + +### Fichier d'environnement + +```bash +cp config/env/.env.example config/env/.env.production +nano config/env/.env.production +``` + +Valeurs à renseigner obligatoirement : + +```dotenv +APP_ENV=production +NODE_ENV=production +SERVER_PORT=3200 + +# Secrets — générer avec : +# node -e "console.log(require('crypto').randomBytes(64).toString('hex'))" +SECRET=<64-octets-hex> +SESSION_SECRET=<64-octets-hex> + +# MySQL +MYSQL_DBNAME=adastra_prod +MYSQL_DBUSER=adastra +MYSQL_DBPASS=MOT_DE_PASSE_FORT +MYSQL_DBHOST=localhost +MYSQL_DBPORT=3306 +MYSQL_DBTYPE=mysql + +# MongoDB +MONGODB_URI=mongodb://adastra:MOT_DE_PASSE_FORT@localhost:27017/adastradb + +# CORS — domaine exact du frontend (sans slash final) +ALLOWED_ORIGINS=https://adastra.example.com + +# Proxy Apache → Node = 1 saut +TRUST_PROXY=1 + +# Sendgrid (si les emails sont utilisés) +SENDGRID_API_KEY= +SENDGRID_FROM_MAIL= +SENDGRID_TO_MAIL= +``` + +### Migrations et seeds initiaux + +À exécuter **une seule fois** lors du premier déploiement : + +```bash +cd /var/www/adastra_api +APP_ENV=production npx sequelize-cli db:migrate +APP_ENV=production npx sequelize-cli db:seed --seed 20251126-add-roles.js +APP_ENV=production npm run create:user # crée le premier compte admin +APP_ENV=production npx sequelize-cli db:seed --seed 20251127-add-articles.js +``` + +### Démarrer avec PM2 + +```bash +cd /var/www/adastra_api +pm2 start app.js --name adastra-api +pm2 save +``` + +Vérifier que l'API répond : + +```bash +curl http://localhost:3200/api/health # ou tout endpoint public +``` + +--- + +## 5. Déploiement du frontend + +Le build se fait **en local** (ou sur un serveur de CI), puis le répertoire `dist/` est transféré sur le serveur. + +### Build en local + +```bash +cd /chemin/local/adastra_app +npm install +npm run build # production build → dist/adastra_angular/browser/ +``` + +> **Important :** vérifier que `src/environments/environment.ts` pointe vers l'URL de l'API de production avant de builder. +> ```typescript +> apiBaseUrl: 'https://api.adastra.example.com/api' +> ``` + +### Transfert sur le serveur + +```bash +# Depuis la machine locale +rsync -avz --delete dist/adastra_angular/browser/ \ + user@serveur:/var/www/adastra_app/ +``` + +Ou avec scp : + +```bash +scp -r dist/adastra_angular/browser/* user@serveur:/var/www/adastra_app/ +``` + +### Permissions + +```bash +# Sur le serveur +chown -R www-data:www-data /var/www/adastra_app +chmod -R 755 /var/www/adastra_app +``` + +--- + +## 6. Configuration Apache + +Architecture recommandée : deux sous-domaines séparés. + +| Sous-domaine | Rôle | +|---|---| +| `adastra.example.com` | Frontend Angular (fichiers statiques) | +| `api.adastra.example.com` | API Node.js (reverse proxy) | + +### VirtualHost frontend — `/etc/apache2/sites-available/adastra-app.conf` + +```apache + + ServerName adastra.example.com + + DocumentRoot /var/www/adastra_app + + + Options -Indexes + AllowOverride None + Require all granted + + # Angular HTML5 routing — renvoie tout vers index.html + FallbackResource /index.html + + + # Compression et cache navigateur + + AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json + + + + Header set Cache-Control "max-age=31536000, public, immutable" + + + Header set Cache-Control "no-cache, no-store, must-revalidate" + + + ErrorLog ${APACHE_LOG_DIR}/adastra-app-error.log + CustomLog ${APACHE_LOG_DIR}/adastra-app-access.log combined + +``` + +### VirtualHost API — `/etc/apache2/sites-available/adastra-api.conf` + +```apache + + ServerName api.adastra.example.com + + ProxyPreserveHost On + ProxyPass / http://127.0.0.1:3200/ + ProxyPassReverse / http://127.0.0.1:3200/ + + # Transmet l'IP réelle du client à Node (requis pour TRUST_PROXY=1) + RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s" + RequestHeader set X-Forwarded-Proto "http" + + ErrorLog ${APACHE_LOG_DIR}/adastra-api-error.log + CustomLog ${APACHE_LOG_DIR}/adastra-api-access.log combined + +``` + +### Activer les vhosts + +```bash +a2ensite adastra-app.conf +a2ensite adastra-api.conf +apache2ctl configtest # doit afficher "Syntax OK" +systemctl reload apache2 +``` + +--- + +## 7. HTTPS avec Let's Encrypt + +```bash +apt install -y certbot python3-certbot-apache +certbot --apache -d adastra.example.com -d api.adastra.example.com +``` + +Certbot modifie automatiquement les vhosts pour le HTTPS et programme le renouvellement. + +Vérifier le renouvellement automatique : + +```bash +certbot renew --dry-run +``` + +Après activation du HTTPS, penser à mettre à jour dans le `.env.production` : +```dotenv +ALLOWED_ORIGINS=https://adastra.example.com +``` + +Et dans `environment.ts` avant de rebuilder le frontend : +```typescript +apiBaseUrl: 'https://api.adastra.example.com/api' +``` + +--- + +## 8. PM2 — démarrage automatique + +Pour que l'API redémarre automatiquement après un reboot : + +```bash +pm2 startup # affiche une commande à exécuter en root — la copier/coller +pm2 save +``` + +Commandes PM2 utiles : + +```bash +pm2 list # état des process +pm2 logs adastra-api # logs en temps réel +pm2 restart adastra-api # redémarrage manuel +pm2 stop adastra-api # arrêt +``` + +--- + +## 9. Procédure de mise à jour + +### Mettre à jour l'API + +```bash +cd /var/www/adastra_api +git pull origin master +npm install --omit=dev + +# Si des migrations ont été ajoutées +APP_ENV=production npx sequelize-cli db:migrate + +pm2 restart adastra-api +``` + +### Mettre à jour le frontend + +En local : + +```bash +cd /chemin/local/adastra_app +git pull origin master +npm install +npm run build +rsync -avz --delete dist/adastra_angular/browser/ user@serveur:/var/www/adastra_app/ +``` + +Aucun redémarrage Apache nécessaire — les fichiers statiques sont servis directement.