Comment configurer une application Node.js pour la production sur Ubuntu 18.04

introduction

Node.js est un environnement d'exécution JavaScript open source pour la création d'applications côté serveur et réseau. La plate-forme fonctionne sous Linux, macOS, FreeBSD et Windows. Bien que vous puissiez exécuter les applications Node.js en ligne de commande, ce didacticiel se concentrera sur leur exécution en tant que service. Cela signifie qu'ils redémarreront en cas de redémarrage ou d'échec et qu'ils peuvent être utilisés en toute sécurité dans un environnement de production.

Dans ce didacticiel, vous allez configurer un environnement Node.js prêt pour la production sur un seul serveur Ubuntu 18.04. Ce serveur exécutera une application Node.js gérée parPM2 et fournira aux utilisateurs un accès sécurisé à l'application via un proxy inverse Nginx. Le serveur Nginx proposera HTTPS en utilisant un certificat gratuit fourni parLet’s Encrypt.

Conditions préalables

Ce guide suppose que vous disposiez des éléments suivants:

Lorsque vous aurez rempli les conditions préalables, vous disposerez d'un serveur diffusant la page d'espace réservé par défaut de votre domaine àhttps://example.com/.

[[step-1 -—- Installing-node-js]] == Étape 1 - Installation de Node.js

Commençons par installer la dernière version LTS de Node.js, en utilisant les archives de packageNodeSource.

Commencez par installer le PPA NodeSource afin d’avoir accès à son contenu. Assurez-vous que vous vous trouvez dans votre répertoire personnel et utilisezcurl pour récupérer le script d'installation des archives Node.js 8.x:

cd ~
curl -sL https://deb.nodesource.com/setup_8.x -o nodesource_setup.sh

Vous pouvez inspecter le contenu de ce script avecnano ou votre éditeur de texte préféré:

nano nodesource_setup.sh

Lorsque vous avez terminé d'inspecter le script, exécutez-le soussudo:

sudo bash nodesource_setup.sh

Le PPA sera ajouté à votre configuration et votre cache de paquet local sera mis à jour automatiquement. Après avoir exécuté le script d'installation à partir de Nodesource, vous pouvez installer le package Node.js:

sudo apt install nodejs

Pour vérifier quelle version de Node.js vous avez installée après ces étapes initiales, tapez:

nodejs -v
Outputv8.11.3

[.note] #Note: Lors de l'installation à partir du PPA NodeSource, l'exécutable Node.js est appelénodejs, plutôt quenode.
#

Le packagenodejs contient le binairenodejs ainsi quenpm, un gestionnaire de packages pour les modules Node, vous n'avez donc pas besoin d'installernpm séparément.

npm utilise un fichier de configuration dans votre répertoire personnel pour suivre les mises à jour. Il sera créé la première fois que vous exécutereznpm. Exécutez cette commande pour vérifier quenpm est installé et pour créer le fichier de configuration:

npm -v
Output5.6.0

Pour que certains packagesnpm fonctionnent (ceux qui nécessitent la compilation de code à partir des sources, par exemple), vous devrez installer le packagebuild-essential:

sudo apt install build-essential

Vous disposez maintenant des outils nécessaires pour travailler avec les packagesnpm qui nécessitent la compilation de code à partir des sources.

Avec le moteur d’exécution Node.js installé, passons à l’écriture d’une application Node.js.

[[step-2 -—- creating-a-node-js-application]] == Étape 2 - Création d'une application Node.js

Écrivons une applicationHello World qui renvoie «Hello World» à toutes les requêtes HTTP. Cet exemple d'application vous aidera à configurer Node.js. Vous pouvez le remplacer par votre propre application - assurez-vous simplement de modifier votre application pour l'écouter sur les adresses IP et les ports appropriés.

Commençons par créer un exemple d’application appeléhello.js:

cd ~
nano hello.js

Insérez le code suivant dans le fichier:

~/hello.js

const http = require('http');

const hostname = 'localhost';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World!\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

Enregistrez le fichier et quittez l'éditeur.

Cette application Node.js écoute sur l'adresse (localhost) et le port (3000) spécifiés et renvoie «Hello World!» avec un code de réussite HTTP200. Comme nous écoutons surlocalhost, les clients distants ne pourront pas se connecter à notre application.

Pour tester votre application, tapez:

node hello.js

Vous verrez la sortie suivante:

OutputServer running at http://localhost:3000/

[.note] #Note: L'exécution d'une application Node.js de cette manière bloquera les commandes supplémentaires jusqu'à ce que l'application soit supprimée en appuyant surCTRL+C.
#

Pour tester l'application, ouvrez une autre session de terminal sur votre serveur et connectez-vous àlocalhost aveccurl:

curl http://localhost:3000

Si vous voyez la sortie suivante, l'application fonctionne correctement et écoute l'adresse et le port corrects:

OutputHello World!

Si vous ne voyez pas la sortie attendue, assurez-vous que votre application Node.js est en cours d'exécution et configurée pour écouter l'adresse et le port appropriés.

Une fois que vous êtes sûr que cela fonctionne, arrêtez l'application (si vous ne l'avez pas déjà fait) en appuyant surCTRL+C.

[[step-3 -—- Installing-pm2]] == Étape 3 - Installation de PM2

Ensuite, installons PM2, un gestionnaire de processus pour les applications Node.js. PM2 permet de démoniser des applications afin qu'elles s'exécutent en arrière-plan en tant que service.

Utiliseznpm pour installer la dernière version de PM2 sur votre serveur:

sudo npm install pm2@latest -g

L'option-g indique ànpm d'installer le moduleglobally, afin qu'il soit disponible à l'échelle du système.

Commençons par utiliser la commandepm2 start pour exécuter votre application,hello.js, en arrière-plan:

pm2 start hello.js

Cela ajoute également votre application à la liste de processus de PM2, qui est sortie chaque fois que vous démarrez une application:

Output[PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/sammy/hello.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬───────┬──────────┐
│ App name │ id │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem       │ user  │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼───────┼──────────┤
│ hello    │ 0  │ fork │ 1338 │ online │ 0       │ 0s     │ 0%  │ 23.0 MB   │ sammy │ disabled │
└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴───────┴──────────┘
 Use `pm2 show ` to get more details about an app

Comme vous pouvez le voir, PM2 assigne automatiquement unApp name (basé sur le nom de fichier, sans l'extension.js) et un PM2id. PM2 conserve également d'autres informations, telles que lesPID du processus, son état actuel et l'utilisation de la mémoire.

Les applications qui s'exécutent sous PM2 seront redémarrées automatiquement si l'application plante ou est tuée, mais nous pouvons faire une étape supplémentaire pour que l'application se lance au démarrage du système à l'aide de la sous-commandestartup. Cette sous-commande génère et configure un script de démarrage pour lancer PM2 et ses processus gérés à l'amorçage du serveur:

pm2 startup systemd

La dernière ligne de la sortie résultante inclura une commande à exécuter avec les privilèges de superutilisateur afin de permettre à PM2 de démarrer au démarrage:

Output[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy

Exécutez la commande à partir de la sortie, avec votre nom d'utilisateur à la place desammy:

sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy

Une étape supplémentaire consiste à enregistrer la liste de processus PM2 et les environnements correspondants:

pm2 save

Vous avez maintenant créé un systemdunit qui exécutepm2 pour votre utilisateur au démarrage. Cette instancepm2, à son tour, exécutehello.js.

Démarrez le service avecsystemctl:

sudo systemctl start pm2-sammy

Vérifiez l'état de l'unité systemd:

systemctl status pm2-sammy

Pour une présentation détaillée de systemd, voirSystemd Essentials: Working with Services, Units, and the Journal.

En plus de ceux que nous avons abordés, PM2 fournit de nombreuses sous-commandes qui vous permettent de gérer ou de rechercher des informations sur vos applications.

Arrêtez une application avec cette commande (spécifiez les PM2App name ouid):

pm2 stop app_name_or_id

Redémarrez une application:

pm2 restart app_name_or_id

Répertoriez les applications actuellement gérées par PM2:

pm2 list

Obtenez des informations sur une application spécifique en utilisant sesApp name:

pm2 info app_name

Le moniteur de processus PM2 peut être extrait avec la sous-commandemonit. Ceci affiche l'état de l'application, l'utilisation du processeur et de la mémoire:

pm2 monit

Notez que l'exécution depm2 sans aucun argument affichera également une page d'aide avec un exemple d'utilisation.

Maintenant que votre application Node.js est en cours d’exécution et gérée par PM2, configurons le proxy inverse.

[[step-4 -—- setting-up-nginx-as-a-reverse-proxy-server]] == Étape 4 - Configuration de Nginx en tant que serveur proxy inverse

Votre application est en cours d'exécution et à l'écoute surlocalhost, mais vous devez définir un moyen pour vos utilisateurs d'y accéder. Nous allons configurer le serveur Web Nginx en tant que proxy inverse à cette fin.

Dans le didacticiel des prérequis, vous configurez votre configuration Nginx dans le fichier/etc/nginx/sites-available/example.com. Ouvrez ce fichier pour le modifier:

sudo nano /etc/nginx/sites-available/example.com

Dans le blocserver, vous devriez avoir un bloclocation / existant. Remplacez le contenu de ce bloc par la configuration suivante. Si votre application est configurée pour écouter sur un autre port, mettez à jour la partie en surbrillance avec le numéro de port correct:

/etc/nginx/sites-available/example.com

server {
...
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
...
}

Cela configure le serveur pour répondre aux demandes à la racine. En supposant que notre serveur est disponible àexample.com, accéder àhttps://example.com/ via un navigateur Web enverrait la requête àhello.js, en écoutant sur le port3000 àlocalhost.

Vous pouvez ajouter des blocslocation supplémentaires au même bloc serveur pour fournir l'accès à d'autres applications sur le même serveur. Par exemple, si vous exécutiez également une autre application Node.js sur le port3001, vous pouvez ajouter ce bloc d'emplacement pour autoriser l'accès viahttps://example.com/app2:

/etc/nginx/sites-available/example.com — Optional

server {
...
    location /app2 {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
...
}

Une fois que vous avez terminé d'ajouter les blocs d'emplacement pour vos applications, enregistrez le fichier et quittez votre éditeur.

Assurez-vous de ne pas avoir introduit d’erreurs de syntaxe en tapant:

sudo nginx -t

Redémarrez Nginx:

sudo systemctl restart nginx

En supposant que votre application Node.js est en cours d’exécution, et que vos configurations d’application et de Nginx sont correctes, vous devriez maintenant pouvoir accéder à votre application via le proxy inverse Nginx. Essayez-le en accédant à l’URL de votre serveur (son adresse IP publique ou son nom de domaine).

Conclusion

Toutes nos félicitations! Votre application Node.js s'exécute maintenant derrière un proxy inverse Nginx sur un serveur Ubuntu 18.04. Cette configuration de proxy inverse est suffisamment souple pour permettre à vos utilisateurs d'accéder à d'autres applications ou à du contenu Web statique que vous souhaitez partager.