Files

8.7 KiB

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
  2. Base de données MySQL
  3. Base de données MongoDB
  4. Déploiement de l'API
  5. Déploiement du frontend
  6. Configuration Apache
  7. HTTPS avec Let's Encrypt
  8. PM2 — démarrage automatique
  9. Procédure de mise à jour

1. Prérequis serveur

Node.js (via nvm — recommandé)

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)

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.

# 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

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é.

-- 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) créeront le schéma.


3. Base de données MongoDB

# 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 :

# /etc/mongod.conf
security:
  authorization: enabled
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

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

cp config/env/.env.example config/env/.env.production
nano config/env/.env.production

Valeurs à renseigner obligatoirement :

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 :

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

cd /var/www/adastra_api
pm2 start app.js --name adastra-api
pm2 save

Vérifier que l'API répond :

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

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.

apiBaseUrl: 'https://api.adastra.example.com/api'

Transfert sur le serveur

# Depuis la machine locale
rsync -avz --delete dist/adastra_angular/browser/ \
    user@serveur:/var/www/adastra_app/

Ou avec scp :

scp -r dist/adastra_angular/browser/* user@serveur:/var/www/adastra_app/

Permissions

# 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

<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

<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

a2ensite adastra-app.conf
a2ensite adastra-api.conf
apache2ctl configtest   # doit afficher "Syntax OK"
systemctl reload apache2

7. HTTPS avec Let's Encrypt

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 :

certbot renew --dry-run

Après activation du HTTPS, penser à mettre à jour dans le .env.production :

ALLOWED_ORIGINS=https://adastra.example.com

Et dans environment.ts avant de rebuilder le frontend :

apiBaseUrl: 'https://api.adastra.example.com/api'

8. PM2 — démarrage automatique

Pour que l'API redémarre automatiquement après un reboot :

pm2 startup   # affiche une commande à exécuter en root — la copier/coller
pm2 save

Commandes PM2 utiles :

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

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 :

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.