DEV Community

Cover image for 🚀 Deploy d'une App Node.js avec NGINX et PM2 + Config Linux Server + Certificat SSL
Grégory CHEVALLIER
Grégory CHEVALLIER

Posted on

🚀 Deploy d'une App Node.js avec NGINX et PM2 + Config Linux Server + Certificat SSL

« Mise en prod' » , « Deploy », « Push ».. Tant d'expressions qui permettent de signifier l'aboutissement d'un long chemin de dĂ©veloppement : ça y est, votre code est fin prĂȘt Ă  ĂȘtre dĂ©ployĂ© dans un environnement de production et votre application/serveur exposĂ©(e) au monde entier.

Si vous n'avez jamais mis d'applications en ligne auparavant, les apprĂ©hensions peuvent ĂȘtre nombreuses.

Comment configurer un serveur Linux pour exécuter des applications Node.js ? Pourquoi utiliser un gestionnaire de processus ? Comment mettre en place un certificat SSL et profiter du protocole HTTPS ? Comment configurer la zone DNS d'un nom de domaine ?


⚙ PrĂ©-configuration de votre serveur

L'utilisation d'un VPS (= Virtual Private Server) est l'une des solutions les plus adaptées lorsque l'on doit déployer par exemple une ou plusieurs applications Node.js.

Vulgairement parlant, un VPS : c'est une machine comme la votre exposĂ©e via une adresse IPv4 dĂ©diĂ©e, qui a pour vocation d'ĂȘtre allumĂ©e 24h/24 - 7j/7. Elle a gĂ©nĂ©ralement la particularitĂ© d'intĂ©grer un systĂšme d'exploitation minimaliste, lĂ©ger et nĂ©cessitant peu de ressources : Linux.

đŸ“¶ La connexion Ă  ce serveur distant est effectuĂ©e via le protocole SSH (Port 22), c'est par l'intermĂ©diaire d'une invite de commande que notre serveur va ĂȘtre configurable.

Lorsque vous commandez un VPS, les informations suivantes vous sont communiquées :

  • Adresse IP (Host)
  • Username
  • Password
  • Port (22)

Ces informations permettent d'établir une connexion SSH. La plupart des systÚmes d'exploitations intÚgrent aujourd'hui un client SSH mais certains nécessitent l'utilisation d'un client SSH tierce, c'est le cas avec Windows par exemple : l'installation du logiciel PuTTY est alors requise.

Si votre VPS est livré avec un systÚme d'authentification : hÎte / nom d'utilisateur / mot de passe, il n'a cependant pas pour vocation à le rester. Ce type d'authentification est exposé à de nombreux types d'attaques, le bruteforce notament.

Pour pallier à cette problématique : l'autorisation d'un client par le serveur depuis une pair de clé SSH préalablement générée

La premiĂšre mise Ă  niveau du serveur implique alors les actions suivantes :

  • Autoriser une/des clĂ©(s) pour s'authentifier au protocole SSH
  • Supprimer l'authentification par mot de passe du protocole SSH

🔑 GĂ©nĂ©rer une nouvelle pair de clĂ© SSH, localement

🌕 Si vous utilisez Linux

Accédez localement à votre dossier ~/.ssh puis générez une nouvelle clé si vous n'en n'avez pas déjà une :

    cd ~/.ssh
    ssh-keygen -t rsa -b 4096 -C "your_label"

Enter fullscreen mode Exit fullscreen mode

Vous n'ĂȘtes pas obligĂ©(e) d'inclure une passphrase Ă  votre nouvelle clĂ©, appuyez sur ENTRER sans mĂȘme saisir de phrase de sĂ©curitĂ©, celle-ci est souvent nĂ©gligĂ©e par les dĂ©veloppeurs, notament lorsqu'une clĂ© est sollicitĂ©e en guise d'authentification via un processus automatisĂ©.

    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/yourusername/.ssh/id_rsa):
    Created directory '/home/yourusername/.ssh'.
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/yourusername/.ssh/id_rsa.
    Your public key has been saved in /home/yourusername/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:2m0FfefEAFeJ31mFw87DAfef3FA113ge your_label
    The key's randomart image is:
    +---[RSA 4096]----+
    |      .          |
    |                 |
    | .               |
    |. . . .          |
    |. .=.o .S.       |
    | =o.o. ..   .    |
    |o +   .  . o ..  |
    |.. .      oEoo . |
    |o.        .o+oo  |
    +-----------------+
Enter fullscreen mode Exit fullscreen mode

Votre pair de clé est à présent créée.

Récupérez votre clé publique grùce à la commande suivante : cat ~/.ssh/id_rsa.pub.

C'est cette clĂ© que nous autoriserons cĂŽtĂ© serveur, nous pourrons ainsi nous authentifier Ă  notre serveur distant sans mĂȘme avoir Ă  justifier d'un mot de passe*.
(*) sous réserve qu'aucune phrase de sécurité n'ai été définie

🌑 Si vous utilisez Windows

Le logiciel PuTTYGen va vous permettre de générer une nouvelle pair de clé.

Une fois le logiciel ouvert, cliquez sur "Generate", agitez la souris aux 4 coins de la fenĂȘtre (stimulation cryptographique) et patientez un instant durant la gĂ©nĂ©ration de votre clĂ©.

Image description

Cette clĂ© publique gĂ©nĂ©rĂ©e a vocation d'ĂȘtre autorisĂ©e auprĂšs de notre serveur. Notre clĂ© privĂ©e permettra de nous authentifier avec PuTTY via le protocole SSH sans utiliser de mot de passe*.
(*) sous réserve qu'aucune phrase de sécurité n'ai été définie

Cliquez ensuite sur le bouton "Save private key" pour enregistrer votre clé au format .ppk (Putty Private Key - format dédié à PuTTY).


🚩 Connexion au serveur et autorisation de notre nouvelle clĂ©

Il est temps de se connecter pour la premiÚre fois à notre serveur, nous utiliserons logiquement l'adresse distante de notre machine, l'identifiant et le mot de passe fournis par notre hébergeur.

    ssh ubuntu@102.49.82.203
    ...

    login as: ubuntu
    ubuntu@102.49.82.203's password: 
Enter fullscreen mode Exit fullscreen mode

Une fois connecté(e),

Ouvrez le fichier authorized_keys via la commande : sudo nano ~/.ssh/authorized_keys

[...] Et ajoutez votre clé publique, précédemment générée, en la collant.

â„č Voici un exemple de ce Ă  quoi pourrait ressembler votre fichier ~/.ssh/authorized_keys si vous aviez autorisĂ© plusieurs clĂ©s; toutes les clĂ©s autorisĂ©es peuvent permettre de s'authentifier au serveur sans mot de passe :

    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQCo9+BpMRYQ/dL3DS2CyJxRF+j6ctbT3/Qp84+KeFhnii7NT7fELilKUSnxS30WAvQCCo2yU1orfgqr41mM70MB your_label
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCb4oUsXZ51L9DmH3UqSnwOAUr9w6AOZa8bYH8qsJAhypAjH9YvQteVXXQEY0ybaVE1cmpIKEyC2jmC/jOJ4b7bivlo2hgnLOrj3FPkDWO2yNNio9RnPXREBx7 special_key
Enter fullscreen mode Exit fullscreen mode

Sauvegardez Ă  prĂ©sent votre fichier, fĂ©licitations 🎉

Vous pouvez dorénavant vous authentifier auprÚs de votre serveur en utilisant la clé précédemment générée.

Voyons à présent comment s'authentifier à notre serveur.


🔒 S'authentifier Ă  notre serveur via SSH grĂące Ă  notre nouvelle clĂ©

🌕 Si vous utilisez Linux

Connectez-vous Ă  votre serveur via la commande traditionnelle : ssh user@host

✅ Aucun mot de passe n'est Ă  prĂ©sent requis, l'authentification est directement effectuĂ©e.

Si une phrase de sécurité (= passphrase) a été configurée lors de la génération de votre clé, cette derniÚre sera requise lors de la tentative de connexion :

    login as: ubuntu
    Authenticating with public key "id_rsa"
    Passphrase for key "id_rsa":
Enter fullscreen mode Exit fullscreen mode

🌑 Si vous utilisez Windows

Ouvrez le logiciel PuTTY (à ne pas confondre avec PuTTYGen permettant de générer des clés) et renseignez l'adresse de votre serveur distant, définissez le port SSH (22).

Rendez-vous dans la catégorie : Connection > SSH > Auth > Credentials.

Localisez votre clé privée (au format .ppk) préalablement enregistrée lors de l'étape de la génération de clé.

Retournez dans la catégorie "Sessions" puis cliquez sur "Save". Vos informations de connexion (y compris votre clé privée) seront alors gardés en mémoire.

Image description

Séléctionnez à présent la session que vous venez de sauvegarder et lancez-là.

Vous ĂȘtes Ă  prĂ©sent authentifiĂ©(e) Ă  votre serveur*.
(*) sous réserve qu'aucune phrase de sécurité n'ai été définie


⛔ DĂ©sactiver l'authentification par identifiant / mot de passe

Notre authentification via clĂ© SSH est Ă  prĂ©sent fonctionnelle ✅

L'authentification par l'intermĂ©diaire d'une combinaison identifiant / mot de passe peut alors ĂȘtre supprimĂ©e, elle est la potentielle porte d'entrĂ©e Ă  d'Ă©ventuelles intrustions malveillantes.

Commencons par modifier le fichier /etc/ssh/sshd_config en utilisant la commande :

sudo nano /etc/ssh/sshd_config

Notre mission : repérer les variables suivantes :

  • PasswordAuthentication
  • ChallengeResponseAuthentication
  • UsePAM

[...] et leur attribuer la valeur suivante : no.

â„č Si l'une de ces variables est absente, rajoutez-lĂ  manuellement et dĂ©finissez-lĂ  Ă  no.

La variable PubkeyAuthentication quant Ă  elle doit ĂȘtre dĂ©finie Ă  yes.

DÚs lorsque les modifications sont terminées, utilisez généralement CTRL + X pour fermer et saisissez "Y" pour confirmer les changements.

â„č VĂ©rifiez parallĂšlement qu'aucun fichier .conf ne soit inclus dans les rĂ©pertoires suivants : /etc/ssh/ssh_config.d et /etc/ssh/sshd_config.d. Certains hĂ©bergeurs dĂ©finissent parfois des variables dans des fichiers de configuration Ă  ces endroits pour, entre autre, autoriser la connexion via identifiant / mot de passe.

Le serveur SSH aura besoin d'ĂȘtre redĂ©marrĂ© pour que les changements soient pris en compte, saisissez la commande suivante : sudo systemctl restart sshd ssh.

Notre serveur n'accepte dorénavant plus les connexions avec mot de passe. Seules les clés autorisées via notre registre ~/.ssh/authorized_keys pourront s'authentifier au protocole SSH de notre serveur.


đŸ“„ TĂ©lĂ©charger et installer la derniĂšre version de Node.js

Node.js est souvent téléchargé depuis les dépÎts officiels / PPA (= Personal Package Archives) Ubuntu.

Nous délaisserons cette méthode en téléchargeant directement Node.js depuis la page de téléchargement du site officiel, selon la version souhaitée. Ainsi, nous sommes certains de pouvoir profiter d'une version up-to-date.

â„č Dans un environnement de production, il est recommandĂ© d'utiliser l'une des derniĂšres versions de Node.js.

Dans ce tutoriel, nous utiliserons la version 18.15.0.

1ïžâƒŁ Localisez-vous au chemin d'accĂšs par dĂ©faut ~ de votre serveur grĂące Ă  cd ~/ puis tĂ©lĂ©chargez la version Node.js cible depuis le site officiel grĂące Ă  la commande :

wget https://nodejs.org/dist/v18.15.0/node-v18.15.0-linux-x64.tar.xz

    --2023-04-01 12:49:28
    --`https://nodejs.org/dist/v18.15.0/node-v18.15.0-linux-x64.tar.xz`
    Resolving nodejs.org (nodejs.org)... 2606:4700:10::6814:162e, 2606:4700:10::6814:172e, 104.20.23.46, ...
    Connecting to nodejs.org (nodejs.org)|2606:4700:10::6814:162e|:443... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 23637576 (23M) [application/x-xz]
    Saving to: ‘node-v18.15.0-linux-x64.tar.xz’

    `node-v18.15.0-linux` 100%[===================>]  22.54M  28.9MB/s    in 0.8s    

    2023-04-01 12:49:28 (28.9 MB/s) - ‘node-v18.15.0-linux-x64.tar.xz’ saved [23637576/23637576]
Enter fullscreen mode Exit fullscreen mode

2ïžâƒŁ DĂ©compressez le fichier .tar.xz tĂ©lĂ©chargĂ© en utilisant :

sudo tar -xvf node-v18.15.0-linux-x64.tar.xz

3ïžâƒŁ Puis transfĂ©rez les fichiers source de Node.js dans le rĂ©pertoire /usr/ en utilisant la commande :

sudo cp -r node-v18.15.0-linux-x64/{bin,include,lib,share} /usr/

4ïžâƒŁ Supprimons sans tarder notre fichier node-v18.15.0-linux-x64.tar.xz ainsi que le rĂ©pertoire dĂ©compressĂ© node-v18.15.0-linux-x64, ils ne nous seront plus d'aucune utilitĂ©.

sudo rm -rf node-v18.15.0-linux-x64 node-v18.15.0-linux-x64.tar.xz

5ïžâƒŁ Ouvrez Ă  prĂ©sent le script de votre shell via sudo nano ~/.bashrc et exposez Node.js en ajoutant la ligne suivante, Ă  la fin :

export PATH=/usr/node-v18.15.0-linux-x64/bin:$PATH

6ïžâƒŁ Rechargez Ă  prĂ©sent le script shell ~/.bashrc en utilisant source ~/.bashrc.

Node.js est normalement installĂ© ✅

VĂ©rifiez que l'installation soit conforme en saisissant node -v dans votre terminal.


🔐 Authentification auprùs de Github

Git est et restera sans doûte le meilleur ami de celles & ceux qui pratiquent la programmation. Il est un outil indispensable du quotidien et sert notament d'intermédiaire entre votre environnement de développement et votre environnement de production.

La configuration de l'authentification avec Github est particuliĂšrement importante.

L'authentification via pair de clĂ© SSH peut par exemple outrepasser la nĂ©cessitĂ© de justifier d'un mot de passe. Elle peut alors permettre la manipulation automatisĂ©e d'un 🌐 repository grĂące Ă  un processus de CI/CD (= Continuous Integration/Continuous Delivery).

🔒 IntĂ©ressons-nous Ă  l'authentification via pair de clĂ© SSH.

Lors de la configuration de notre serveur Linux : nous avions généré, localement, une pair de clé SSH et nous avions autorisé notre clé publique depuis le serveur.

Cette fois, c'est sur le serveur que la pair de clĂ© SSH va devoir ĂȘtre gĂ©nĂ©rĂ©e. La clĂ© publique sera transmise Ă  Github via les paramĂštres de notre compte et les Ă©changes avec Github seront dĂšs lors authentifiĂ©s.

Localisez-vous dans le dossier ~/.ssh de votre machine distante puis générez votre nouvelle pair de clé SSH :

    cd ~/.ssh
    ssh-keygen -t rsa -b 4096 -C "your_email@domain.com"
Enter fullscreen mode Exit fullscreen mode

Suivez la procédure de génération, ajoutez ou non une phrase de sécurité puis patientez un instant.

    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/ubuntu/.ssh/id_rsa): 
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    Your identification has been saved in /home/ubuntu/.ssh/id_rsa
    Your public key has been saved in /home/ubuntu/.ssh/id_rsa.pub
    The key fingerprint is:
    SHA256:c7bEyoefeR09TZ9vnEmddK2LwD4XRo4ZCLfmE3kKKTWoM your_email@domain.com
    The key's randomart image is:
    +---[RSA 4096]----+
    |    o . oo  .    |
    |  .  o     . o   |
    | o .  o   . + .  |
    |o      . + + .  .|
    |E s.    S X .   +|
    |.o     . B T..+.+|
    |.       = *.+o.* |
    |  ..  .  *.  .o o|
    |        ..o.     |
    +----[SHA256]-----+
Enter fullscreen mode Exit fullscreen mode

Il ne vous reste plus qu'à copier votre clé publique en utilisant : cat ~/.ssh/id_rsa.pub.

Rendez-vous sur https://github.com/settings/keys, cliquez sur "Nouvelle clé SSH" puis ajoutez votre clé publique en l'identifiant par un nom de référence.

Image description

VĂ©rifiez, dans le terminal de votre serveur, que vous ĂȘtes bien authentifiĂ© en utilisant la commande : ssh -T git@github.com.

Si vous ĂȘtes authentifiĂ©, vous reçevrez un message similaire Ă  celui-ci 👇

Hi {username}! You've successfully authenticated, but GitHub does not provide shell access.

[...] Vous pouvez à présent cloner votre projet sur votre serveur.


🟰 Cloner une application depuis un repository Git

A la racine ~ de votre serveur distant, clĂŽnez votre application grĂące Ă  la commande :

git clone git@github.com:{username}/{project}.git

â„č Prenez soin d'actualiser les variables { } par vos donnĂ©es (= nom d'utilisateur Git et nom de projet).

Une fois votre application clÎnée et accessible en local, localisez-vous à la racine de votre projet à l'aide du nom de votre projet précédé par la commande cd.

â„č Supposons que notre application soit une simple application React.

Créez votre fichier d'environnement de production (dotenv) à la racine (= .env ou .env.local).

Installez vos dépendances et lancez le build de votre projet à l'aide de npm i et npm run build.

⚙ VĂ©rifiez que votre application puisse se lancer via npm run start et tentez de joindre votre application via l'adresse de votre machine depuis le port utilisĂ© par Node.js.

Mettez fin au processus (CTRL + C).

⚠ Soyez sĂ»re que votre application soit fonctionnelle en installant les Ă©ventuels services dĂ©pendants (= (No)SQL database, Redis, Docker, API..)


📂 Utiliser le protocole SFTP dĂ©diĂ© aux transferts de fichiers

Que vous utilisiez Mac OS, Windows ou Linux, le logiciel de transfert de fichiers FileZilla vous permettra via une interface graphique de gérer les ressources de votre serveur (répertoires/fichiers).

â„č Le transfert de fichiers se rĂ©vĂšle particuliĂšrement indispensable pour les sites web basiques incluant un systĂšme d'upload de fichiers. Ces derniers n'utilisant pas de solutions liĂ©es au cloud comme S3 AWS / Azure / Google Storage etc.. Les fichiers sont alors stockĂ©s sur le serveur.

Le transfert de fichiers requiert l'utilisation d'un protocole FTP (= File Transfert Protocol). Un serveur FTP (Port 21) doit alors ĂȘtre installĂ© sur le serveur.

Pour pallier Ă  cette Ă©preuve, une alternative s'offre Ă  nous : le SFTP (= SSH File Transfert Protocol).

Le SFTP accompli les missions du FTP mais en utilisant un autre protocole : le SSH (Port 22), le mĂȘme que nous utilisons quotidiennement pour intĂ©ragir via shell avec notre serveur distant. Nous bĂ©nĂ©ficions dĂšs lors des atouts qu'offre le SSH : Ă  savoir une connexion sĂ©curisĂ©e via pair de clĂ© SSH.

En principe et selon notre mode opératoire, FileZilla charge notre clé SSH (préalablement générée) et la transmet à notre serveur qui nous autorise à établir la connexion.

Renseignez dÚs-lors l'adresse IPv4 de votre serveur, votre identifiant, le port : 22 puis procédez à la connexion.

✅ Votre clĂ© SSH est dĂ©tectĂ©e, transmise et approuvĂ©e par le serveur, vous ĂȘtes authentifiĂ©(e).

La clé n'est pas détectée ?

Si la clé n'est pas détectée, vous utilisez probablement Windows. Dans FileZilla, localisez la clé .ppk que vous aviez générée avec PuTTYGen depuis :

Filezilla > Fichier > Gestionnaire de sites > Type d'authentification > Fichier de clef

Image description

[...] Et chargez votre clé, la connexion devrait à présent aboutir.


đŸ“„ Installer et configurer le gestionnaire de processus PM2

Le gestionnaire de processus va permettre d'initialiser chacune de vos applications Node.js en les répertoriant dans des conteneurs centralisés. Il va occuper un rÎle majeur en ce qui concerne la maintenance et le processus de déploiement de vos applications.

Chacun de ces conteneurs peut alors ĂȘtre (re)dĂ©marrĂ©/arrĂȘtĂ© et exploitĂ© individuellement.

🔁 En cas de redĂ©marrage impromptu du serveur, le gestionnaire de processus permet de redĂ©marrage de l'intĂ©gralitĂ© de vos applications afin d'Ă©viter une indisponibilitĂ© prolongĂ©e de vos services. Il donne Ă©galement accĂšs aux logs et Ă  un systĂšme de monitoring efficace concernant vos processus.

Nous utiliserons PM2, une librairie disponible sur yarn et npm, simple, complĂšte et efficace d'utilisation.

💡 Et si nous n'utilisions pas de gestionnaire de processus ?

Si par exemple vous démarriez votre application via une session SSH sans utiliser de gestionnaire de processus (via npm run start par exemple) : un processus serait alors lancé.

Dans l'hypothĂšse oĂč vous abandonneriez ce(tte) terminal/session, vous perderiez la main sur le processus mais celui-ci continuerai alors d'ĂȘtre exĂ©cutĂ© en arriĂšre plan (vous pourriez Ă©videment le reprendre dans une session ultĂ©rieure).

Si hasardeusement, vous oublieriez qu'une application Node.js Ă©tait dĂ©jĂ  en cours d'exĂ©cution, vous la lanceriez une nouvelle fois et il n'existerait alors pas moins de deux occurences d'une mĂȘme application Node.js (x2 processus en arriĂšre plan).

Autrement, si vous aviez par exemple plusieurs applications Node.js sur le mĂȘme serveur, vous ne pourriez mĂȘme pas les distinguer dans la liste des processus en cours d'exĂ©cution.

C'est Ă  ces problĂ©matiques que le gestionnaire de processus PM2 apporte des solutions đŸ”„

đŸ’č Comment ça fonctionne ?

Installons maintenant notre gestionnaire de processus, sur notre serveur distant, via la commande :

sudo npm i pm2 -g

Vérifiez que PM2 soit installé sur votre machine en exécutant : pm2 -v.

â„č Le drapeau -g permet d'installer la librairie globalement et d'enregistrer la nouvelle variable d'environnement pm2.

Le mode de fonctionnement de PM2 permet d'initialiser un nouveau processus depuis la racine d'une application Node.js, au mĂȘme niveau que notre traditionnel package.json.

Il intÚgre d'ailleurs la reconnaissance d'un fichier de configuration intitulé ecosystem.config.js. DÚs lorsque ce fichier est présent à la racine de votre projet, il va permettre au gestionnaire de processus de démarrer votre application avec les différentes propriétés spécifiées.

â„č La documentation des diffĂ©rentes propriĂ©tĂ©s disponibles pour la configuration du fichier ecosystem.config.js est disponible en ligne.

Avant d'initialiser votre application dans PM2, prenez-soin de créer un fichier ecosystem.config.js à la racine de votre projet puis d'y apporter la configuration requise minimale :

    module.exports = {
        apps : [{
            name: 'my-process-name',
            script : "npm run start",
        }]
    };
Enter fullscreen mode Exit fullscreen mode

Exécutez à présent la commande pm2 start à la racine de votre projet.

    [PM2][WARN] Applications my-process-name not running, starting...
    [PM2] App [my-process-name] launched (1 instances)
    ┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
    │ id │ name               │ mode     │  â†ș   │ status    │ cpu      │ memory   │
    ├────┌────────────────────┌──────────┌──────┌───────────┌──────────┌───────────
    │ 0  │ my-process-name    │ fork     │ 0    │ online    │ 0%       │ 10.2mb   │
    └────┮────────────────────┮──────────┮──────┮───────────┮──────────┮──────────┘
Enter fullscreen mode Exit fullscreen mode

Le nouveau processus est crĂ©Ă© et dĂ©marrĂ© 🎉

D'autres applications peuvent ainsi ĂȘtre ajoutĂ©es Ă  la liste des processus PM2.

â„č La commande pm2 startup ubuntu permet de garantir le redĂ©marrage de vos processus aprĂšs un Ă©ventuel crash/reboot intempestif de votre machine.

L'exĂ©cution, l'arrĂȘt et le redĂ©marrage de votre application devra Ă  prĂ©sent passer par PM2.

    // Lister les processus référencés
    pm2 list

    // DĂ©marrer une application
    pm2 start my-process-name

    // ArrĂȘter une application
    pm2 stop my-process-name

    // Redémarrer une application
    pm2 restart my-process-name

    // Accéder aux logs d'une application
    pm2 logs my-process-name

    // Accéder au panel de monitoring instantanée
    pm2 monit

    // Sauvegarder le référencement des applications chargées
    pm2 save

    // Restaurer des applications depuis une sauvegarde
    pm2 resurrect

    // Démarrer les processus lors du démarrage du systÚme
    pm2 startup ubuntu
Enter fullscreen mode Exit fullscreen mode

đŸ“„ Installer et configurer le serveur web NGINX

L'utilisation d'un serveur web en guise de surcouche à Node.js est tout à fait recommandé. Le serveur web Nginx offre par exemple de nombreux avantages :

  • Concentrer l'audience de vos applications sur un mĂȘme port (80 par dĂ©faut)
  • IntĂ©grer d'indĂ©nombrables fichiers de configuration clairs et documentĂ©s. (Voir la documentation officielle)
  • Optimiser le traitement des requĂȘtes
  • GĂ©rer la mise en cache et la compression des donnĂ©es

[...] Et surtout : permettre l'utilisation d'un Reverse Proxy đŸ”„

Le proxy inverse permet de :

  • Rediriger des requĂȘtes entrantes vers diffĂ©rents serveurs internes utilisant diffĂ©rents protocoles.
  • Agir en tant que rĂ©partiteur de charge entre plusieurs serveurs, si configurĂ© comme tel.
  • DĂ©charger les serveurs d'une charge d'objets/pages statiques via la gestion d'un cache web local.
  • Agir en tant que point de terminaison TLS et permettre le chiffrement via certificat SSL.
  • RĂ©duire la charge de traitement cryptographique (= HTTPS) si installĂ© sur une machine diffĂ©rente des serveurs applicatifs.
  • [...]

â„č L'utilisation du reverse proxy a pour vocation de n'exposer que le port 80. Ainsi, les diffĂ©rents ports qu'occupent nos applications internes pourront ĂȘtre bloquĂ©s par notre pare-feu.

Procédons à l'installation de Nginx sur notre machine distante :

sudo apt install nginx

    Reading package lists... Done
    Building dependency tree... Done
    Reading state information... Done
    The following packages were automatically installed and are no longer required:
      javascript-common libc-ares2 libjs-highlight.js libnode72 nodejs-doc
    Use 'sudo apt autoremove' to remove them.
    The following additional packages will be installed:
      libnginx-mod-http-geoip2 libnginx-mod-http-image-filter
      libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream
      libnginx-mod-stream-geoip2 nginx-common nginx-core
    Suggested packages:
      fcgiwrap nginx-doc ssl-cert
    The following NEW packages will be installed:
      libnginx-mod-http-geoip2 libnginx-mod-http-image-filter
      libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream
      libnginx-mod-stream-geoip2 nginx nginx-common nginx-core
    0 upgraded, 9 newly installed, 0 to remove and 0 not upgraded.
    Need to get 696 kB of archives.
    After this operation, 2395 kB of additional disk space will be used.
    Do you want to continue? [Y/n]
Enter fullscreen mode Exit fullscreen mode

Saisissez "Y" et appuyez sur ENTRER.

✅ Nginx est Ă  prĂ©sent installĂ© sur votre machine.

Remplacez intégralement le contenu du fichier /etc/nginx/sites-available/default :

sudo nano /etc/nginx/sites-available/default

[...] par le code suivant :

    server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name yourdomain.com www.yourdomain.com;
        location / {
            proxy_pass 'http://127.0.0.1:{port}';
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Port $server_port;
        }
    }
Enter fullscreen mode Exit fullscreen mode

â„č Soyez certain(e) d'avoir remplacer la variable {port} par le port utilisĂ© par votre application Node.js et (www.)yourdomain.com par votre nom de domaine. Nous pourrons ensuite installer un certificat SSL.

Lorsque vous installez Nginx, la taille maximale d'une requĂȘte prise en charge par Nginx est restreinte Ă  1MB par dĂ©faut. Au delĂ , le requĂȘte sera rejetĂ©e ou ignorĂ©e.

Pour modifier ce paramÚtre, ouvrez le fichier de configuration /etc/nginx/nginx.conf et ajoutez la ligne suivante dans la section http si elle n'existe pas déjà :

client_max_body_size 50M;

⚠ VĂ©rifiez que la configuration globale soit conforme en exĂ©cutant sudo nginx -t puis redĂ©marrez Nginx pour intĂ©grer les modifications.

Utilisez sudo service nginx restart ou sudo systemctl restart nginx.

Lancez à présent votre application via PM2 et essayez de joindre votre application via HTTP (port 80 de votre machine).

â„č L'installation d'un certificat SSL via la librairie Certbot viendra complĂ©ter le fichier de configuration /etc/nginx/sites-available/default pour permettre l'utilisation et la redirection HTTPS.

Si vous vouliez par exemple créer des sous-domaines et utiliser plusieurs méthodes de Proxy Reverse, vous pourriez configurer votre fichier /etc/nginx/sites-available/default selon le principe suivant :

    # Domain | www.domain.com

    server {
        server_name domain.com www.domain.com;
        location / {
            proxy_pass 'http://hostname:{port}';
        }
    }

    # Sub-domain n°1 | subdomain1.domain.com

    server {
        server_name subdomain1.domain.com www.subdomain1.domain.com;
        location / {
            proxy_pass 'http://hostname:{port}';
        }
    }

    # Sub-domain n°2 | subdomain2.domain.com

    server {
        server_name subdomain2.domain.com www.subdomain2.domain.com;
        location / {
            proxy_pass 'http://hostname:{port}';
        }
    }
Enter fullscreen mode Exit fullscreen mode

Pour garantir de bonnes conditions de maintenance et renforcer l'organisation structurelle de notre Reverse Proxy, il serait préférable de supprimer notre fichier /etc/nginx/sites-available/default et de créer un fichier pour chaque (sous-)domaine.

L'arborescence des (sous-)domaines serait alors plus simple Ă  distinguer.

    # Domain | www.domain.com

    server {
        server_name domain.com www.domain.com;
        location / {
            proxy_pass 'http://hostname:{port}';
        }
    }
Enter fullscreen mode Exit fullscreen mode
    # Sub-domain n°1 | subdomain1.domain.com

    server {
        server_name subdomain1.domain.com www.subdomain1.domain.com;
        location / {
            proxy_pass 'http://hostname:{port}';
        }
    }
Enter fullscreen mode Exit fullscreen mode

Une fois les fichiers de configurations référents à vos différents (sous-)domaines créés dans le répertoire /etc/nginx/sites-available, créez un lien symbolique pour chacun de vos fichiers depuis ce répertoire, au répertoire /etc/nginx/sites-enabled/ en utilisant :

    cd ~
    sudo ln -s /etc/nginx/sites-available/domain.com /etc/nginx/sites-enabled/domain.com
    sudo ln -s /etc/nginx/sites-available/subdomain1.domain.com /etc/nginx/sites-enabled/subdomain1.domain.com
    ...
Enter fullscreen mode Exit fullscreen mode

⚠ VĂ©rifiez que la configuration globale soit conforme en exĂ©cutant sudo nginx -t puis redĂ©marrez Nginx pour intĂ©grer les modifications.

Utilisez sudo service nginx restart ou sudo systemctl restart nginx.


đŸ›Ąïž Activation du pare-feu serveur

DĂšs lorsque nos applications Node.js sont accessible via le port 80 qu'utilise notre serveur web Nginx, il est judicieux d'activer le pare-feu et ainsi n'autoriser que les protocoles ayant pour vocation d'ĂȘtre exploitĂ©s sur notre machine tels que :

  • SSH / SFTP (22)
  • HTTP(S) (80 / 443)

Exécutez les commandes suivantes :

    sudo ufw enable
    sudo ufw allow ssh
    sudo ufw allow http
    sudo ufw allow https
Enter fullscreen mode Exit fullscreen mode

Utilisez la commande sudo ufw status pour obtenir une synthÚse des réglementations.

    Status: active

    To                         Action      From
    --                         ------      ----
    22/tcp                     ALLOW       Anywhere                  
    80                         ALLOW       Anywhere                  
    443                        ALLOW       Anywhere                  
    22/tcp (v6)                ALLOW       Anywhere (v6)             
    80 (v6)                    ALLOW       Anywhere (v6)             
    443 (v6)                   ALLOW       Anywhere (v6)      
Enter fullscreen mode Exit fullscreen mode

🌐 Configuration de la zone DNS d'un nom de domaine

C'est une étape primordiale lorsqu'une activitée prend naissance sur le web : la configuration de la zone DNS du nom de domaine.

La zone DNS d'un nom de domaine est un espace administratif gérée par une organisation ou un administrateur spécifique qui permet le contrÎle sur les différentes entrées du nom de domaine.

Lorsque vous reçevez votre nouveau nom de domaine, la zone DNS de votre nom de domaine est souvent pré-configuré par votre hébergeur de telle sorte à ce que vous puissiez dors et déjà par exemple accéder au protocole FTP du serveur cible via la pré-configuration d'un enregistrement CNAME (= ftp.domain.com).

â„č Retrouvez la liste des diffĂ©rents enregistrements DNS existants

Exemple d'espace d'administration de la zone DNS d'un nom de domaine (OVH) 👇

Image description

Ci-dessous, un aperçu textuel de la configuration de la zone DNS de notre nom de domaine :

    $TTL 3600
    @   IN SOA dns200.anycast.me. tech.ovh.net. (2023020018 86400 3600 3600000 60)
                              IN NS     ns200.anycast.me.
                              IN NS     dns200.anycast.me.
                              IN MX     1 mx4.mail.ovh.net.
                              IN MX     10 mx3.mail.ovh.net.
                              IN A      164.132.50.110
                              IN TXT    "1|www.domain.com"
    _autodiscover._tcp        IN SRV    0 0 443 mailconfig.ovh.net.
    _imaps._tcp               IN SRV    0 0 993 ssl0.ovh.net.
    _submission._tcp          IN SRV    0 0 465 ssl0.ovh.net.
    subdomain1                IN CNAME  domain.com.
    autoconfig                IN CNAME  mailconfig.ovh.net.
    autodiscover              IN CNAME  mailconfig.ovh.net.
    ftp                       IN CNAME  domain.com.
    subdomain2                IN CNAME  domain.com.
    www                       IN A      164.132.50.110
    www                       IN TXT    "3|welcome"
Enter fullscreen mode Exit fullscreen mode

La premiÚre action à entreprendre : modifier l'adresse IPv4 cible de l'enregistrement de Type A en renseignant l'adresse IPv4 de votre serveur distant, pour les deux entrées existantes : domain.com (Type A) et www.domain.com (Type A).

Le nom de domaine sera dĂšs lors reconnu par n'importe quel naviguateur et dirigera le client Ă  votre serveur distant.

Pour créer un sous-domaine, créez une nouvelle entrée de Type CNAME, ciblez votre nom de domaine et spécifiez l'intitulé du sous-domaine à créer, puis validez.

â„č Un dĂ©lai de propagation implique parfois d'attendre jusqu'Ă  24 heures avant de garantir l'accessibilitĂ© Ă  votre nouveau sous-domaine.

Lorsque vous requĂȘterez votre sous-domaine, Nginx sera capable d'interprĂȘter l'origine de la requĂȘte et vous redirigera auprĂšs de l'application cible (selon votre configuration via proxy).


🔒 Mise en place d'un certificat SSL avec Certbot

Maintenant que notre nom de domaine nous redirige vers notre serveur distant, que le serveur web Nginx interprĂȘte l'origine de notre requĂȘte et nous redirige vers l'application cible ;

Etablissons une connexion sécurisée entre client/serveur grùce au protocole HTTPS.

L'utilisation du protocole HTTPS nécessite l'utilisation d'un certificat numérique permettant aux navigateurs de vérifier l'identité des serveurs web. Des tiers de confiance, soit des autorités de certification (AC) sont chargées de déléguer les certificats aux serveurs web.

Une librairie nommée « Certbot » récupÚre des certificats depuis l'autorité de certification Let's Encrypt, (autorité de certification lancée à l'initiative de Mozilla notament). Nous l'utiliserons pour implémenter rapidement notre certificat SSL avec Nginx.

Installons Certbot, depuis notre machine distante :

sudo apt install certbot python3-certbot-nginx

Procédons à l'installation de notre certificat SSL en utilisant Certbot :

sudo certbot --nginx -d domain.com -d www.domain.com

    Saving debug log to '/var/log/letsencrypt/letsencrypt.log'
    Enter email address (used for urgent renewal and security notices)
     (Enter 'c' to cancel): your_email@domain.com

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Please read the Terms of Service at
    https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
    agree in order to register with the ACME server. Do you agree?
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (Y)es/(N)o: y

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Would you be willing, once your first certificate is successfully issued, to
    share your email address with the Electronic Frontier Foundation, a founding
    partner of the Lets Encrypt project and the non-profit organization that
    develops Certbot? We would like to send you email about our work encrypting the web,
    EFF news, campaigns, and ways to support digital freedom.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (Y)es/(N)o: y
    Account registered.
    Requesting a certificate for 'domain.com' and 'www.domain.com'

    Successfully received certificate.
    Certificate is saved at: '/etc/letsencrypt/live/domain.com/fullchain.pem'
    Key is saved at:         '/etc/letsencrypt/live/domain.com/privkey.pem'
    This certificate expires on 2023-07-01.
    These files will be updated when the certificate renews.
    Certbot has set up a scheduled task to automatically renew this certificate in the background.

    Deploying certificate
    Successfully deployed certificate for 'domain.com to' '/etc/nginx/sites-enabled/default'
    Successfully deployed certificate for 'www.domain.com' to '/etc/nginx/sites-enabled/default'
    Congratulations! You have successfully enabled HTTPS on 'https://domain.com' and 'https://www.domain.com'

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    If you like Certbot, please consider supporting our work by:
     * Donating to ISRG / Lets Encrypt:   https://letsencrypt.org/donate
     * Donating to EFF:                    https://eff.org/donate-le
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Enter fullscreen mode Exit fullscreen mode

Une rÚgle a été créée auprÚs de votre serveur web pour rediriger le client du protocole HTTP au HTTPS. Une tùche pour renouveller le certificat a quant à elle été initialisée et sera renouvellée chaque 90 jours.

Vérifiez que celle-ci soit créée via sudo systemctl status certbot.timer

    ● certbot.timer - Run certbot twice daily
    Loaded: loaded ('/lib/systemd/system/certbot.timer'; enabled; vendor preset:>
    Active: active (waiting) since Sun 2023-04-02 10:50:45 UTC; 4min 58s ago
    Trigger: Sun 2023-04-02 15:19:19 UTC; 4h 23min left
    Triggers: ● certbot.service

    Apr 02 10:50:45 vps systemd[1]: Started Run certbot twice daily.
Enter fullscreen mode Exit fullscreen mode

Un email de Let's Encrypt devrait vous parvenir avant l'expiration de votre certificat.

Utilisez sudo certbot renew --dry-run Ă  l'avenir pour renouveller votre certificat.

â„č Vous pourrez remarquer que le fichier de configuration Nginx liĂ© au nom de domaine que vous avez certifiĂ© Ă  Ă©tĂ© modifiĂ© par Certbot. Notre fichier /etc/nginx/sites-available/default ou /etc/nginx/sites-available/domain.com a hĂ©ritĂ© de nouvelles propriĂ©tĂ©s pour permettre l'utilisation du protocole HTTPS.

FĂ©licitations 🎉

Vous pouvez dorénavant profiter de votre application depuis le protocole HTTPS.

Top comments (1)

Collapse
 
techengagepro profile image
Ayesha Javed

Helpful Article.Pour déployer une application server location Node.js avec NGINX et PM2 sur un serveur Linux avec un certificat SSL, vous pouvez suivre les étapes suivantesAccÚs à un serveur Linux (par exemple Ubuntu).