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

introduction

Node.js is an open source JavaScript runtime environment for easily building server-side and networking applications. La plateforme fonctionne sous Linux, OS X, FreeBSD et Windows. Node.js applications can be run at the command line, but we’ll focus on running them as a service, so that they will automatically restart on reboot or failure, and can safely be used in a production environment.

Dans ce didacticiel, nous aborderons la configuration d’un environnement Node.js prêt pour la production sur un seul serveur Ubuntu 16.04. Ce serveur exécutera une application Node.js gérée par PM2 et fournira aux utilisateurs un accès sécurisé à l’application via un proxy inverse Nginx. Le serveur Nginx proposera HTTPS, à l’aide d’un certificat gratuit fourni par Let’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 servant la page d'espace réservé Nginx par défaut àhttps://example.com/.

Commençons par installer le runtime Node.js sur votre serveur.

Installez Node.js

Nous installerons la dernière version LTS de Node.js, en utilisant les archives de paquetsNodeSource.

Tout d’abord, vous devez 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 6.x:

cd ~
curl -sL https://deb.nodesource.com/setup_6.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

Et exécutez le script 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 de la même manière que ci-dessus:

sudo apt-get install nodejs

Le packagenodejs contient le binairenodejs ainsi quenpm, vous n'avez donc pas besoin d'installernpm séparément. Cependant, pour que certains packagesnpm fonctionnent (tels que ceux qui nécessitent la compilation du code à partir des sources), vous devrez installer le packagebuild-essential:

sudo apt-get install build-essential

Le runtime Node.js est maintenant installé et prêt à exécuter une application! Écrivons une application Node.js.

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

Créer une application Node.js

Nous écrirons une applicationHello World qui renvoie simplement «Hello World» à toutes les requêtes HTTP. Ceci est un exemple d'application qui vous aidera à configurer votre Node.js, que vous pourrez remplacer par votre propre application. Assurez-vous simplement de modifier votre application pour écouter les adresses IP et les ports appropriés.

Bonjour Code du monde

Commencez par créer et ouvrez votre application Node.js pour l’éditer. Pour ce tutoriel, nous utiliseronsnano pour éditer un exemple d'application appeléhello.js:

cd ~
nano hello.js

Insérez le code suivant dans le fichier. Si vous le souhaitez, vous pouvez remplacer le port en surbrillance,8080, aux deux emplacements (assurez-vous d'utiliser un port non-admin, c.-à-d. 1024 ou plus):

hello.js

#!/usr/bin/env nodejs
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(8080, 'localhost');
console.log('Server running at http://localhost:8080/');

Maintenant, enregistrez et quittez.

Cette application Node.js écoute simplement sur l'adresse (localhost) et le port (8080) 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.

Application de test

Afin de tester votre application, marquez l'exécutablehello.js:

chmod +x ./hello.js

Et lancez-le comme ça:

./hello.js
OutputServer running at http://localhost:8080/

[.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.
#

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

curl http://localhost:8080

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

OutputHello World

Si vous ne voyez pas la sortie appropriée, 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.

Installer le PM2

Nous allons maintenant installer PM2, un gestionnaire de processus pour les applications Node.js. PM2 offre un moyen simple de gérer et de démonaliser les applications (les exécuter en arrière-plan en tant que service).

Nous utiliseronsnpm, un gestionnaire de packages pour les modules Node qui s'installe avec Node.js, pour installer PM2 sur notre serveur. Utilisez cette commande pour installer PM2:

sudo npm install -g pm2

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

Gérer les applications avec PM2

PM2 est simple et facile à utiliser. Nous aborderons quelques utilisations de base des PM2.

Lancer l'application

La première chose que vous voudrez faire est d'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
[PM2] PM2 Successfully daemonized
[PM2] Starting hello.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────────────┬──────────┐
│ App name │ id │ mode │ pid  │ status │ restart │ uptime │ memory      │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────────────┼──────────┤
│ hello    │ 0  │ fork │ 3524 │ online │ 0       │ 0s     │ 21.566 MB   │ 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 exécutées sous PM2 seront automatiquement redémarrées si l'application se bloque ou est tuée, mais une étape supplémentaire doit être franchie pour que l'application se lance au démarrage du système (démarrage ou redémarrage). Heureusement, PM2 fournit un moyen simple de le faire, la sous-commandestartup.

La sous-commandestartup génère et configure un script de démarrage pour lancer PM2 et ses processus gérés au démarrage du serveur:

pm2 startup systemd

La dernière ligne de la sortie résultante inclura une commande que vous devez exécuter avec les privilèges de superutilisateur:

Output[PM2] Init System found: systemd
[PM2] You have to run this command as root. Execute 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 qui a été générée (similaire à la sortie en surbrillance ci-dessus, mais avec votre nom d'utilisateur au lieu desammy) pour configurer PM2 pour qu'il démarre au démarrage (utilisez la commande de votre propre sortie):

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

Cela créera un systemdunit qui exécutepm2 pour votre utilisateur au démarrage. Cette instancepm2, à son tour, exécutehello.js. Vous pouvez vérifier l'état de l'unité systemd avecsystemctl:

systemctl status pm2-sammy

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

Autre utilisation de PM2 (facultatif)

PM2 fournit de nombreuses sous-commandes qui vous permettent de gérer ou de rechercher des informations sur vos applications. Notez que l'exécution depm2 sans aucun argument affichera une page d'aide, comprenant des exemples d'utilisation, qui couvre l'utilisation de PM2 plus en détail que cette section du didacticiel.

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

pm2 stop app_name_or_id

Redémarrez une application avec cette commande (spécifiez les PM2App name ouid):

pm2 restart app_name_or_id

La liste des applications actuellement gérées par PM2 peut également être consultée avec la sous-commandelist:

pm2 list

Vous trouverez plus d'informations sur une application spécifique en utilisant la sous-commandeinfo (spécifiez les PM2App name ouid):

pm2 info example

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

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

Configurer Nginx en tant que serveur proxy inverse

Maintenant que votre application est en cours d'exécution et à l'écoute surlocalhost, vous devez configurer 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, nous avons configuré notre configuration Nginx dans le fichier/etc/nginx/sites-available/default. Ouvrez le fichier pour le modifier:

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

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/default

. . .
    location / {
        proxy_pass http://localhost:8080;
        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 port8080 à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 port8081, vous pouvez ajouter ce bloc d'emplacement pour autoriser l'accès viahttp://example.com/app2:

/etc/nginx/sites-available/default — Optional

    location /app2 {
        proxy_pass http://localhost:8081;
        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 et quittez.

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

sudo nginx -t

Ensuite, 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 16.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. Bonne chance avec votre développement Node.js!