docs: add complete production deployment guide
This commit is contained in:
@@ -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 <url-du-repo> 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
|
||||
<VirtualHost *:80>
|
||||
ServerName adastra.example.com
|
||||
|
||||
DocumentRoot /var/www/adastra_app
|
||||
|
||||
<Directory /var/www/adastra_app>
|
||||
Options -Indexes
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
|
||||
# Angular HTML5 routing — renvoie tout vers index.html
|
||||
FallbackResource /index.html
|
||||
</Directory>
|
||||
|
||||
# Compression et cache navigateur
|
||||
<IfModule mod_deflate.c>
|
||||
AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json
|
||||
</IfModule>
|
||||
|
||||
<FilesMatch "\.(js|css|woff2|png|jpg|svg)$">
|
||||
Header set Cache-Control "max-age=31536000, public, immutable"
|
||||
</FilesMatch>
|
||||
<FilesMatch "index\.html$">
|
||||
Header set Cache-Control "no-cache, no-store, must-revalidate"
|
||||
</FilesMatch>
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/adastra-app-error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/adastra-app-access.log combined
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
### VirtualHost API — `/etc/apache2/sites-available/adastra-api.conf`
|
||||
|
||||
```apache
|
||||
<VirtualHost *:80>
|
||||
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
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
### 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.
|
||||
Reference in New Issue
Block a user