Fermer

janvier 7, 2024

Comment utiliser Node.js avec Docker —

Comment utiliser Node.js avec Docker —


Ce didacticiel explique les avantages de l’exécution d’applications Node.js dans des conteneurs Docker et comment créer un workflow de développement pratique.

Noeud.js vous permet de créer des applications Web rapides et évolutives en utilisant JavaScript sur le serveur ainsi que sur le client. Votre application peut fonctionner parfaitement sur votre ordinateur de développement, mais pouvez-vous être certain qu’elle fonctionnera sur les appareils ou les serveurs de production de vos collègues ?

Considérez ces scénarios :

  • Vous utilisez peut-être macOS lorsque d’autres utilisent Windows et que le serveur exécute Linux.
  • Node.js 20 est installé sur votre ordinateur, mais d’autres utilisent diverses versions d’exécution.
  • Vous utilisez des dépendances telles que des bases de données, qui présentent des différences ou peuvent ne pas être disponibles sur d’autres plateformes.
  • Êtes-vous sûr que votre nouveau code ne peut rien faire de dangereux sur un autre système d’exploitation ?
Table des matières

Docker livre

Docker aide à résoudre ceux « mais ça marche sur ma machine » problèmes énumérés ci-dessus. Plutôt que d’installer une application localement, vous l’exécutez dans un environnement léger et isolé de type machine virtuelle, appelé récipient.

Docker

Une vraie machine virtuelle émule le matériel PC afin que vous puissiez installer un système d’exploitation. Docker émule un système d’exploitation afin que vous puissiez installer des applications. Il est courant d’installer une application par conteneur basé sur Linux et de les connecter via un réseau virtuel afin qu’ils puissent communiquer sur les ports HTTP.

Les avantages:

  • Votre configuration Docker peut soit émuler un serveur Linux de production, soit être déployée à l’aide de conteneurs.
  • Vous pouvez télécharger, installer et configurer des dépendances en quelques minutes.
  • Votre application conteneurisée s’exécute de la même manière sur tous les appareils.
  • C’est plus sûr. Votre application peut détruire le système d’exploitation d’un conteneur, mais cela n’affectera pas votre PC et vous pourrez redémarrer en quelques secondes.

Avec Docker, il n’est pas nécessaire d’installer Node.js sur votre PC ou d’utiliser une option de gestion d’exécution telle que nvm.

Votre premier scénario

Installez Docker Desktop sur les fenêtres, macOSou Linux puis créez un petit script nommé version.js avec le code suivant :

console.log(`Node.js version: ${ process.version }`);

Si Node.js est installé localement, essayez d’exécuter le script. Vous verrez le résultat tel que celui-ci si la version 18 est installée :

$ node version.js
Node.js version: v18.18.2

Vous pouvez désormais exécuter le même script dans un conteneur Docker. La commande ci-dessous utilise la version de support à long terme (LTS) la plus récente de Node.js. cd dans le répertoire du script et exécutez-le sur macOS ou Linux :

$ docker run --rm --name version \
  -v $PWD:/home/node/app \
  -w /home/node/app \
  node:lts-alpine version.js

Node.js version: v20.9.0

Les utilisateurs de Windows Powershell peuvent utiliser une commande similaire avec {} parenthèses autour PWD:

> docker run --rm --name version -v ${PWD}:/home/node/app -w /home/node/app node:lts-alpine version.js

Node.js version: v20.9.0

La première exécution peut prendre une minute ou deux à mesure que Docker télécharge les dépendances. Les exécutions suivantes sont instantanées.

Essayons une autre version de Node, comme la dernière version de la version 21. Sur macOS ou Linux :

$ docker run --rm --name version \
  -v $PWD:/home/node/app \
  -w /home/node/app \
  node:21-alpine version.js

Node.js version: v21.1.0

Sous Windows PowerShell :

> docker run --rm --name version -v ${PWD}:/home/node/app -w /home/node/app node:21-alpine version.js

Node.js version: v21.1.0

N’oubliez pas que le script s’exécute dans un conteneur Linux sur lequel une version spécifique de Node.js est installée.

Explication des arguments

Pour les curieux, les arguments de la commande sont :

  • docker run démarre un nouveau conteneur à partir d’un image – plus à ce sujet ci-dessous.

  • --rm supprime le conteneur lorsqu’il se termine. Il n’est pas nécessaire de conserver les conteneurs, sauf si vous avez de bonnes raisons de les redémarrer.

  • --name version attribue un nom au conteneur pour une gestion plus simple.

  • -v $PWD:/home/node/app (ou -v ${PWD}:/home/node/app) bind monte un volume. Dans ce cas, le courant directement sur le PC hôte est monté à l’intérieur du conteneur à /home/node/app.

  • -w /home/node/app définit le répertoire de travail Node.js.

  • node:lts-alpine est le image — dans ce cas, la version LTS de Node.js exécutée sous Alpine Linux. L’image contient le système d’exploitation et les fichiers requis pour exécuter une application. Considérez-le comme un instantané de disque. Vous pouvez démarrer n’importe quel nombre de conteneurs à partir de la même image : ils font tous référence au même ensemble de fichiers, de sorte que chaque conteneur nécessite un minimum de ressources.

  • version.js est la commande à exécuter (depuis le répertoire de travail).

Les images Docker sont disponibles sur Centre Docker et ils sont disponibles pour les applications et les environnements d’exécution, notamment Noeud.js. Les images sont souvent disponibles en plusieurs versions identifiées par une balise telle que :lts-alpine, 20-bullseye-slimou juste latest.

Noter que Alpin est une petite distribution Linux avec une taille d’image de base d’environ 5 Mo. Il ne contient pas beaucoup de bibliothèques, mais il est suffisant pour des projets simples tels que ceux de ce didacticiel.

Exécution d’applications complexes

Le version.js Le script ci-dessus est simple et ne contient aucune dépendance ni étape de construction. La plupart des applications Node.js utilisent npm pour installer et gérer des modules dans un node_modules annuaire. Vous ne pouvez pas utiliser la commande ci-dessus car :

  • Tu ne peux pas courir npm sur le PC hôte (vous n’avez peut-être pas installé Node.js ou la bonne version).
  • Certains modules nécessitent des binaires spécifiques à la plate-forme. Vous ne pouvez pas installer un binaire Windows sur le PC hôte et vous attendre à ce qu’il s’exécute dans un conteneur Linux.

La solution est de créer votre propre image Docker contenant :

  • une version appropriée du runtime Node.js
  • une version installée de votre application avec tous les modules requis

La démonstration suivante crée une application Node.js simple à l’aide du Express.js cadre. Créez un nouveau répertoire nommé simple et ajoutez un package.json fichier avec le contenu suivant :

{
  "name": "simple",
  "version": "1.0.0",
  "description": "simple Node.js and Docker example",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "debug": "node --watch --inspect=0.0.0.0:9229 index.js",
    "start": "node index.js"
  },
  "license": "MIT",
  "dependencies": {
    "express": "^4.18.2"
  }
}

Ajouter un index.js fichier avec le code JavaScript :


import express from 'express';


const cfg = {
  port: process.env.PORT || 3000
};


const app = express();


app.get('/:name?', (req, res) => {
  res.send(`Hello ${ req.params.name || 'World' }!`);
});


app.listen(cfg.port, () => {
  console.log(`server listening at http://localhost:${ cfg.port }`);
});

N’essayez pas d’installer des dépendances ou d’exécuter cette application sur le PC hôte !

Créez un fichier nommé Dockerfile avec le contenu suivant :

# base Node.js LTS image
FROM node:lts-alpine

# define environment variables
ENV HOME=/home/node/app
ENV NODE_ENV=production
ENV NODE_PORT=3000

# create application folder and assign rights to the node user
RUN mkdir -p $HOME && chown -R node:node $HOME

# set the working directory
WORKDIR $HOME

# set the active user
USER node

# copy package.json from the host
COPY --chown=node:node package.json $HOME/

# install application modules
RUN npm install && npm cache clean --force

# copy remaining files
COPY --chown=node:node . .

# expose port on the host
EXPOSE $NODE_PORT

# application launch command
CMD [ "node", "./index.js" ]

Ceci définit les étapes requises pour installer et exécuter votre application. Noter que package.json est copié sur l’image, puis npm install est exécuté avant copier les fichiers restants. C’est plus efficace que de copier tous les fichiers en même temps, car Docker crée une image couche à chaque commande. Si votre candidature dépose (index.js) changement, Docker n’a qu’à exécuter les trois dernières étapes ; ce n’est pas nécessaire npm install encore.

En option, vous pouvez ajouter un .dockerignore déposer. C’est semblable à .gitignore et empêche la copie des fichiers inutiles dans l’image en COPY . .. Par exemple:

Dockerfile

.git
.gitignore

.vscode
node_modules
README.md

Créez une image Docker nommée simple en entrant la commande suivante (noter la . point à la fin – ce qui indique que vous utilisez des fichiers dans le répertoire actuel):

$ docker image build -t simple .

L’image devrait se construire en quelques secondes si le node:lts-alpine L’image Docker utilisée ci-dessus n’a pas été supprimée de votre système.

En supposant que la compilation réussisse, démarrez un conteneur à partir de votre image :

$ docker run -it --rm --name simple -p 3000:3000 simple

server listening at http://localhost:3000

Le -p 3000:3000 publie ou expose un <host-port> à un <container-port> donc le port 3000 sur votre PC hôte est acheminé vers le port 3000 à l’intérieur du conteneur.

Ouvrez un navigateur et entrez l’URL http://localhost:3000/ pour voir « Hello World ! »

Essayez d’ajouter des noms à l’URL, tels que http://localhost:3000/Craig – pour voir des messages alternatifs.

Enfin, arrêtez l’exécution de votre application en cliquant sur le bouton arrêt icône dans le Conteneurs de Docker Desktop, ou saisissez la commande suivante dans une autre fenêtre de terminal :

docker container stop simple

Un meilleur flux de travail de développement Docker

Le processus ci-dessus présente quelques défauts frustrants :

  • Toute modification de votre code (dans index.js) vous oblige à arrêter le conteneur, à reconstruire l’image, à redémarrer le conteneur et à retester.

  • Vous ne pouvez pas attacher un débogueur Node.js tel que celui disponible dans Code VS.

Docker peut améliorer votre flux de travail de développement en conservant l’image existante au niveau de la production, mais en exécutant un conteneur avec des remplacements afin d’effectuer les opérations suivantes :

  • Définir des variables d’environnement telles que NODE_ENV à development.

  • Montez le répertoire local dans le conteneur.

  • Démarrez l’application avec npm run debug. Cela fonctionne node --watch --inspect=0.0.0.0:9229 index.jsqui redémarre l’application lorsque les fichiers changent (nouveau dans Node.js 18) et démarre le débogueur avec les requêtes autorisées depuis l’extérieur du conteneur.

  • Expose le port d’application 3000 et le port de débogueur 9229 à l’hôte.

Vous pouvez le faire avec un long docker run commande, mais je préfère utiliser Docker Composer. Il est installé avec Docker Desktop et est souvent utilisé pour démarrer plusieurs conteneurs. Créez un nouveau fichier nommé docker-compse.yml avec le contenu suivant :

version: '3'

services:

  simple:
    environment:
      - NODE_ENV=development
    build:
      context: ./
      dockerfile: Dockerfile
    container_name: simple
    volumes:
      - ./:/home/node/app
    ports:
      - "3000:3000"
      - "9229:9229"
    command: /bin/sh -c 'npm install && npm run debug'

Démarrez votre application en mode débogage avec :

$ docker compose up

[+] Building 0.0s
[+] Running 2/2
 ✔ Network simple_default  Created
 ✔ Container simple        Created
Attaching to simple
simple  |
simple  | up to date, audited 63 packages in 481ms
simple  |
simple  | > simple@1.0.0 debug
simple  | > node --watch --inspect=0.0.0.0:9229 index.js
simple  |
simple  | Debugger listening on ws://0.0.0.0:9229/de201ceb-5d00-1234-8692-8916f5969cba
simple  | For help, see: https://nodejs.org/en/docs/inspector
simple  | server listening at http://localhost:3000

Notez que les anciennes versions de Docker Compose sont des scripts Python exécutés à l’aide de docker-compose. Les versions plus récentes ont la fonctionnalité Compose intégrée à l’exécutable principal, elle est donc exécutée avec docker compose.

L’application en direct redémarre

Ouvrir index.jsapportez une modification (comme la chaîne à la ligne 14) et enregistrez le fichier pour voir l’application redémarrer automatiquement :

simple  | Restarting 'index.js'
simple  | Debugger listening on ws://0.0.0.0:9229/acd16665-1399-4dbc-881a-8855ddf9d34c
simple  | For help, see: https://nodejs.org/en/docs/inspector
simple  | server listening at http://localhost:3000

Ouvrez ou actualisez votre navigateur à https://localhost:3000/ pour voir la mise à jour.

Déboguer avec VS Code

Ouvrez le code VS Exécuter et déboguer panneau et cliquez sur créer un fichier launch.json.

Volet VS Code Run et Debug

Choisir Noeud.js dans la liste déroulante et un .vscode/launch.json Le fichier est créé et ouvert dans l’éditeur. Ajoutez le code suivant qui attache le débogueur au conteneur en cours d’exécution :

{
  
  
  
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "attach",
      "name": "Attach to Container",
      "address": "localhost",
      "port": 9229,
      "localRoot": "${workspaceFolder}",
      "remoteRoot": "/home/node/app",
      "skipFiles": [
        "<node_internals>/**"
      ]
    }
  ]
}

Enregistrez le fichier puis cliquez sur Attacher au conteneur en haut du volet Débogage pour démarrer le débogage.

Exécution et débogage du code VS

Une barre d’outils de débogage apparaît. Basculer vers index.js et ajoutez un point d’arrêt à la ligne 14 en cliquant sur la gouttière pour afficher un point rouge.

définir un point d'arrêt dans VS Code

Rafraîchir https://localhost:3000/ dans votre navigateur et VS Code arrêtera l’exécution au point d’arrêt et affichera l’état de toutes les variables d’application. Cliquez sur une icône dans la barre d’outils de débogage pour continuer l’exécution, parcourir le code ou déconnecter le débogueur.

Arrêtez le conteneur

Arrêtez le conteneur en cours d’exécution en ouvrant un autre terminal. cd dans le répertoire de l’application et saisissez :

docker compose down

Résumé

Bien que Docker nécessite un certain temps de configuration initiale, les avantages à long terme d’un code robuste et distribuable dépassent largement l’effort. Docker devient inestimable lorsque vous ajoutez d’autres dépendances telles que des bases de données.

Ce didacticiel explique les bases de l’exécution d’applications Node.js dans des conteneurs Docker. Pour aller plus loin, considérez ces ressources SitePoint :




Source link