Introduction
Docker est une plateforme de conteneurs qui constitue un environnement standardisé, léger, virtualisé, portable et défini par logiciel. Il permet au logiciel de s'exécuter de manière isolée des autres logiciels s'exécutant sur la machine hôte physique. Docker est un composant déterminant de l'aspect Développement et Intégration Continus du développement logiciel. Il offre une alternative légère aux machines virtuelles et permet aux développeurs de profiter d'architectures d'applications distribuées. Pour un aperçu complet de l'écosystème Docker, consultez cet article.
Le processus de création d'une application avec Docker commence par la création d'une image par un développeur pour son application. Ensuite, l'image sera déployée dans un conteneur. L'image contient les composants définissant une application tels que le code de l'application, les bibliothèques, les fichiers de configuration, les variables d'environnement et l'environnement d'exécution. L'image standardise l'environnement à l'intérieur d'un conteneur, ce qui confère à la conteneurisation ses caractéristiques de portabilité. Node.js est un environnement d'exécution JavaScript backend open-source et multiplateforme qui peut exécuter du code JavaScript en dehors d'un navigateur web. Il est construit sur le moteur JavaScript V8 de Chrome. Express.js est un framework JavaScript backend minimaliste qui s'exécute sur Node.js.
Dans ce tutoriel, nous allons créer une image pour un site web qui fonctionne sur le framework Express. Nous utiliserons Bootstrap, qui est une bibliothèque frontend, pour rendre le frontend plus attrayant. Une fois que nous aurons créé l'image, nous construirons un conteneur et le pousserons vers Docker Hub. Docker Hub permet aux développeurs d'héberger des applications conteneurisées pour un déploiement facile dans n'importe quel environnement Docker. Une fois votre conteneur hébergé sur Docker Hub, nous le récupérerons et construirons une autre image qui servira réellement notre site web.
Prérequis
Il s'agit d'un tutoriel pratique. Vous devez créer un environnement qui vous permettra de suivre les étapes.
- Vous devez disposer d'une installation d'Ubuntu 20.04 comme environnement d'exploitation initial et créer un utilisateur non-root avec des privilèges sudo. Connectez-vous avec l'utilisateur non-root et passez aux étapes suivantes.
- Vous devez installer Docker. Suivez les étapes 1, 2, 3 et 4 de notre tutoriel sur comment installer et utiliser Docker sur Ubuntu. Cela devrait fonctionner pour n'importe quelle distribution Ubuntu.
- Créez un compte Docker Hub si vous n'en avez pas déjà un. Vous pouvez suivre ce lien pour le Guide de démarrage rapide de Docker Hub.
- Installez Node.js et NPM. NPM est un gestionnaire de paquets JavaScript. Vous pouvez suivre ces instructions sur l'installation de Node et npm.
Étape 1 : Configurer les dépendances de l'application
You need to create your application source code before you can create the image. The application source code includes code, static content, and dependencies that will be copied to the container. Start by creating a directory for your project in the home directory of the non-root. We will call it node_express, but you are free to use a directory name that you like:
|
1 |
mkdir node_express |
Ensuite, déplacez-vous dans ce répertoire :
|
1 |
cd node_express |
This will be your application root directory. A node.js application expects a package.json file in the root folder. Npm uses this file to determine what dependencies your application needs. Enter the following command to create this file:
|
1 |
nano package.json |
Après cela, ajoutez l'extrait de code suivant au fichier. Vous pouvez mettre à jour le nom, l'auteur, la description et le fichier de point d'entrée comme vous le souhaitez :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "name": "node-express-docker-image", "version": "1.0.0", "description": "Nodejs Express Docker Image Example", "author": "hackins", "main": "index.js", "license": "ISC", "keywords": [ "nodejs", "express", "bootstrap" ], "dependencies": { "express": "^4.17.1" } } |
Comme vous pouvez le voir, ce fichier spécifie le nom du projet, la version, l'auteur et la licence sous laquelle le code de l'application sera partagé. Il est recommandé d'utiliser un nom court et descriptif pour votre projet afin d'éviter les doublons dans le registre npm. Nous avons spécifié la licence ISC pour le projet, ce qui permet de copier, modifier ou distribuer librement le code de l'application.
Plus important encore, vous devez noter les directives suivantes dans le fichier :
- “
main”: this directive specifies the entry point of the application, which we set as index.js. We will be creating this file shortly. - “
dependencies”: this directive specifies the application dependencies that will be pulled from the npm registry when we run thenpmcommand, in our case, we want Express version 4.17.1 and above.
Vous pouvez maintenant enregistrer le fichier en appuyant sur Ctrl + O. Ensuite, fermez le fichier en appuyant sur Ctrl + X. Ensuite, nous installerons les dépendances en exécutant la commande suivante :
|
1 |
npm install |
The command installs the application dependencies specified in the package.json file inside the node_modules directories. They have been auto-created when you first ran the command. With our application dependencies installed, you can now start adding the application code.
Étape 2 : Ajout des fichiers de code de votre application
Nous allons créer un site web de recettes de base, avec l'aimable autorisation de allrecipes. The main entry point for the application is the index.js file. We will add a views directory that will hold the various pages and static assets of the project. The website will have a landing page that will contain introductory information and links to some recipes.
Our landing page code will be placed in the home.html file. First, create the index.js file by entering the following command:
|
1 |
nano index.js |
Ajoutez le code suivant, qui importe et crée une application Express. Il spécifie également l'objet Router, le répertoire de base et le port sur lequel cette application sera servie :
|
1 2 3 4 5 6 |
const express = require('express'); const app = express(); const router = express.Router(); const path = __dirname + '/views/'; const port = 8090; |
require is a JavaScript function that loads a module. In this case, we are loading the express module. Then, we will use the imported module to create the express and router objects. The router object performs the routing functions of the app by responding to HTTP method calls that will add to this object as we go along with the tutorial.
We have also set path and port. The path constant defines the base directory for the code. In our case it’s the views subdirectory inside the project root directory. The port specifies the port on which the express app should listen on, in our example, we have set it to 8090.
Once we have the constants, we can specify some routes for the application using the router object. Add the following code to the index.js file to specify the routes:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
router.use(function (req,res,next) { console.log('/' + req.method); next(); }); router.get('/', function(req,res){ res.sendFile(path + 'home.html'); }); router.get('/lasagna', function(req,res){ res.sendFile(path + 'lasagna.html'); }); router.get('/guacamole', function(req,res){ res.sendFile(path + 'guacamole.html'); }); router.get('/banana-bread', function(req,res){ res.sendFile(path + 'banana_bread.html'); }); |
Vous pouvez ajouter du middleware to routes using the router.use function. In this case, we add a function that logs the router’s requests before passing them to the application routes. A GET request to the application’s base will return a home.html page. Then, we have added pages for three recipes that will also be retrieved using the GET request to the specific recipe page.
Finally, add the following code to mount the router middleware and the application static assets. In addition, tell the express application to listen on port 8090:
|
1 2 3 4 5 6 |
app.use(express.static(path)); app.use('/', router); app.listen(port, function () { console.log('Nodejs Express Example App listening on port ' + port) }) |
Your complete index.js file should look like this:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
const express = require('express'); const app = express(); const router = express.Router(); const path = __dirname + '/views/'; const port = 8090; router.use(function (req,res,next) { console.log('/' + req.method); next(); }); router.get('/', function(req,res){ res.sendFile(path + 'home.html'); }); router.get('/lasagna', function(req,res){ res.sendFile(path + 'lasagna.html'); }); router.get('/guacamole', function(req,res){ res.sendFile(path + 'guacamole.html'); }); router.get('/banana-bread', function(req,res){ res.sendFile(path + 'banana_bread.html'); }); app.use(express.static(path)); app.use('/', router); app.listen(port, function () { console.log('Nodejs Express Example App listening on port ' + port) }) |
You may save and close the file now. The next step is to add the static web pages to the views directory. Start by entering the following command to create the directory:
|
1 |
mkdir views |
Enter the following command to open the home.html landing page file:
|
1 |
nano views/home.html |
Ajoutez le code suivant au fichier. Le code importe Bootstrap et offre aux visiteurs du site des informations sur le but de ce site web :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors"> <meta name="generator" content="Hugo 0.80.0"> <title>Awesome Recipes</title> <!-- Bootstrap core CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous"> <link href="css/custom.css" rel="stylesheet"> </head> <body> <nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md"> <div class="container"> <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Basculer la navigation</span> </button> <a class="navbar-brand" href="#">Awesome Recipes</a> <div class="collapse navbar-collapse justify-content-center" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav justify-content-center"> <li class="active nav-item"> <a href="/" class="nav-link">Home</a> </li> <li class="nav-item"> <a href="/lasagna" class="nav-link">Lasagna</a> </li> <li class="nav-item"> <a href="/guacamole" class="nav-link">Guacamole</a> </li> <li class="nav-item"> <a href="/banana-bread" class="nav-link">Banana Bread</a> </li> </ul> </div> </div> </nav> <main> <section class="py-5 text-center container"> <div class="row py-lg-5"> <div class="col-lg-6 col-md-8 mx-auto"> <h1 class="fw-light">Awesome Recipe</h1> <p class="lead text-muted"> Find and share everyday cooking inspiration from these awesome recipes. Discover recipes, cooks, videos, and how-tos based on the food you love and the friends you follow. <br /> <em>(Nothing serious, this is just for our demo node-express-docker image app)</em> </p> </div> </div> </section> </main> </body> </html> |
En plus d'importer Bootstrap, la page ajoute également un menu de navigation de base pour nous aider à naviguer à travers les pages et à revenir à la page d'accueil. Nous avons également ajouté une ligne pour importer notre fichier CSS personnalisé :
|
1 |
<link href="css/custom.css" rel="stylesheet"> |
We will use this file to add custom styling to the application later on. Now, let’s create the three pages for the recipes. We first start by creating the lasagna page. Open the file with nano editor using the following command:
|
1 |
nano views/lasagna.html |
In the opened file, add the following code. This file will import Bootstrap, the custom.css file, specify a navigation menu and offer some Lasagna recipe information:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors"> <meta name="generator" content="Hugo 0.80.0"> <title>Lasagna Recipe</title> <!-- Bootstrap core CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous"> <link href="css/custom.css" rel="stylesheet"> </head> <body> <nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md"> <div class="container"> <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Basculer la navigation</span> </button> <a class="navbar-brand" href="#">Awesome Recipes</a> <div class="collapse navbar-collapse justify-content-center" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav justify-content-center"> <li class="active nav-item"> <a href="/" class="nav-link">Home</a> </li> <li class="nav-item"> <a href="/lasagna" class="nav-link">Lasagna</a> </li> <li class="nav-item"> <a href="/guacamole" class="nav-link">Guacamole</a> </li> <li class="nav-item"> <a href="/banana-bread" class="nav-link">Banana Bread</a> </li> </ul> </div> </div> </nav> <main> <section class="py-5 text-center container bg-light"> <div class="row py-lg-5"> <div class="col-lg-6 col-md-8 mx-auto"> <h1 class="fw-light">The Best Lasagna Recipe</h1> <p class="lead text-muted"> This is the best lasagna you will ever make. <br /> <em>(Nothing serious, this is just for our demo node-express-docker image app)</em> </p> <h3>Ingredients</h3> <ul class="list-group"> <li class="list-group-item">1 pound sweet Italian sausage</li> <li class="list-group-item">¾ pound lean ground beef</li> <li class="list-group-item">½ cup minced onion</li> <li class="list-group-item">2 cloves garlic, crushed</li> <li class="list-group-item">1 (28 ounce) can crushed tomatoes</li> <li class="list-group-item">2 (6 ounce) cans tomato paste</li> <li class="list-group-item">2 (6.5 ounce) cans canned tomato sauce</li> <li class="list-group-item">½ cup water</li> <li class="list-group-item">2 tablespoons white sugar</li> <li class="list-group-item">1 ½ teaspoons dried basil leaves</li> <li class="list-group-item">½ teaspoon fennel seeds</li> <li class="list-group-item">1 teaspoon Italian seasoning</li> <li class="list-group-item">1 ½ teaspoons salt, divided, or to taste</li> <li class="list-group-item">¼ teaspoon ground black pepper</li> <li class="list-group-item">4 tablespoons chopped fresh parsley</li> <li class="list-group-item">12 lasagna noodles</li> <li class="list-group-item">16 ounces ricotta cheese</li> <li class="list-group-item">1 egg</li> <li class="list-group-item">¾ pound mozzarella cheese, sliced</li> <li class="list-group-item">¾ cup grated Parmesan cheese</li> </ul> </div> </div> </section> </main> </body> </html> |
Let’s follow the same process to create a file for the guacamole recipe page. Open the file with nano by running the following command:
|
1 |
nano views/guacamole.html |
Ajoutez ensuite ce code au fichier :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors"> <meta name="generator" content="Hugo 0.80.0"> <title>Guacamole Recipe</title> <!-- Bootstrap core CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous"> <link href="css/custom.css" rel="stylesheet"> </head> <body> <nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md"> <div class="container"> <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Basculer la navigation</span> </button> <a class="navbar-brand" href="#">Awesome Recipes</a> <div class="collapse navbar-collapse justify-content-center" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav justify-content-center"> <li class="active nav-item"> <a href="/" class="nav-link">Home</a> </li> <li class="nav-item"> <a href="/lasagna" class="nav-link">Lasagna</a> </li> <li class="nav-item"> <a href="/guacamole" class="nav-link">Guacamole</a> </li> <li class="nav-item"> <a href="/banana-bread" class="nav-link">Banana Bread</a> </li> </ul> </div> </div> </nav> <main> <section class="py-5 text-center container bg-light"> <div class="row py-lg-5"> <div class="col-lg-6 col-md-8 mx-auto"> <h1 class="fw-light">The Best Guacamole Recipe</h1> <p class="lead text-muted"> You can make this avocado salad smooth or chunky depending on your tastes. <br /> <em>(Nothing serious, this is just for our demo node-express-docker image app)</em> </p> <h3>Ingredients</h3> <ul class="list-group"> <li class="list-group-item">3 avocados - peeled, pitted, and mashed</li> <li class="list-group-item">1 lime, juiced</li> <li class="list-group-item">1 teaspoon salt</li> <li class="list-group-item">½ cup diced onion</li> <li class="list-group-item">3 tablespoons chopped fresh cilantro</li> <li class="list-group-item">2 roma (plum) tomatoes, diced</li> <li class="list-group-item">1 teaspoon minced garlic</li> <li class="list-group-item">1 pinch ground cayenne pepper (Optional)</li> </ul> </div> </div> </section> </main> </body> </html> |
Finally, let’s create the banana_bread.html file by entering the command:
|
1 |
nano views/banana_bread.html |
Ensuite, ajoutez le code HTML suivant au fichier :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors"> <meta name="generator" content="Hugo 0.80.0"> <title>Banana Bread Recipe</title> <!-- Bootstrap core CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous"> <link href="css/custom.css" rel="stylesheet"> </head> <body> <nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md"> <div class="container"> <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Basculer la navigation</span> </button> <a class="navbar-brand" href="#">Awesome Recipes</a> <div class="collapse navbar-collapse justify-content-center" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav justify-content-center"> <li class="active nav-item"> <a href="/" class="nav-link">Home</a> </li> <li class="nav-item"> <a href="/lasagna" class="nav-link">Lasagna</a> </li> <li class="nav-item"> <a href="/guacamole" class="nav-link">Guacamole</a> </li> <li class="nav-item"> <a href="/banana-bread" class="nav-link">Banana Bread</a> </li> </ul> </div> </div> </nav> <main> <section class="py-5 text-center container bg-light"> <div class="row py-lg-5"> <div class="col-lg-6 col-md-8 mx-auto"> <h1 class="fw-light">The Best Banana Banana Bread Recipe</h1> <p class="lead text-muted"> Why compromise the banana flavor? This banana bread is moist and delicious with loads of banana flavor! Friends and family love my recipe and say it's by far the best! It's wonderful toasted!! Enjoy! <br /> <em>(Nothing serious, this is just for our demo node-express-docker image app)</em> </p> <h3>Ingredients</h3> <ul class="list-group"> <li class="list-group-item">2 cups all-purpose flour</li> <li class="list-group-item">1 teaspoon baking soda</li> <li class="list-group-item">¼ teaspoon salt</li> <li class="list-group-item">½ cup butter</li> <li class="list-group-item">¾ cup brown sugar</li> <li class="list-group-item">2 eggs, beaten</li> <li class="list-group-item">2⅓ cups mashed overripe bananas</li> </ul> </div> </div> </section> </main> </body> </html> |
Now, we have created all the pages. If you remember, we are to add the css/custom.css file. Enter the following command to create the directory:
|
1 |
mkdir views/css |
Créez ensuite et ouvrez le fichier dans l'éditeur nano avec la commande :
|
1 |
nano views/css/custom.css |
Vous pouvez ajouter d'autres codes CSS pour styliser votre site Web comme vous le souhaitez. Pour des raisons de concision, ajoutons l'extrait de code suivant au fichier :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
.bd-placeholder-img { font-size: 1.125rem; text-anchor: middle; -webkit-user-select: none; -moz-user-select: none; user-select: none; } @media (min-width: 768px) { .bd-placeholder-img-lg { font-size: 3.5rem; } } |
Enregistrez et fermez le fichier lorsque vous avez terminé.
Vous pouvez démarrer l'application puisque nous avons maintenant installé le code source de l'application et les dépendances du projet.
We had set the app to listen on a port 8090, run the following command to instruct the firewall to allow traffic through this port. If you had specified a different port, replace the port number in the command:
|
1 |
sudo ufw allow 8090 |
Maintenant, vous pouvez démarrer l'application. Mais d'abord, assurez-vous simplement que vous êtes dans le répertoire racine du projet en exécutant la commande suivante :
|
1 |
cd ~/node_express |
Démarrez l'application avec node index.js. Si vous avez spécifié un point d'entrée différent, remplacez-le par votre point d'entrée :
|
1 |
node index.js |
If you navigate your browser to http://your_public_server_ip:8090, you will see the Recipes landing page as defined:
You can see the links to the various recipes in the navigation. Let’s click on some. Below we have the Lasagna recipe page:
And here we have the Guacamole recipe page:
Jusqu'à présent, vous avez créé votre application et vérifié qu'elle fonctionne comme prévu. Vous pouvez quitter le serveur en appuyant sur Ctrl + C et passer à la création du Dockerfile. Les Dockerfiles facilitent l'évolutivité en permettant de recréer une instance d'application en cas de besoin.
Étape 3 : Création du Dockerfile
Docker lit les instructions spécifiées dans un Dockerfile lors de la construction d'images. Il spécifie l'environnement d'exécution d'une application. Par conséquent, il aide les développeurs à éviter les divergences avec les dépendances ou les changements de versions d'environnement d'exécution. Entrez la commande suivante pour créer le Dockerfile :
|
1 |
nano Dockerfile |
Une image Docker est créée à l'aide de plusieurs couches d'images qui se superposent les unes aux autres. Vous commencez par ajouter une image de base pour former le point de départ de l'application.
Since the application expects to run in a node.js environment, we will start by adding the image node:10-alpine for node.js. Currently, as we are writing this tutorial, this is the version LTS recommandée de Node.js. Nous avons choisi cette image spécifique car elle est dérivée du projet Alpine Linux. Par conséquent, cela aidera à maintenir la taille de notre image au minimum. Il existe plusieurs variantes d'images sous la page des images Node de Docker Hub parmi lesquelles vous pouvez choisir en fonction de vos besoins.
Add the following code to set the application’s base image using the FROM directive:
|
1 |
FROM node:10-alpine |
This image includes Node.js and npm. Every Dockerfile must begin with a FROM directive. The Docker node image comes with a non-root node user by default that you can use to run your application container as root. La sécurité Docker recommande de ne pas exécuter les conteneurs en tant que root et de restreindre les privilèges à ceux uniquement requis pour exécuter ses ressources.
In that case, we will be using the node user’s home directory as the working directory for the application as well as the user inside the container. You can check this guide des meilleures pratiques pour les images Docker Node pour plus d'informations.
We will create the node_modules subdirectory inside the /home/node along with the app directory to help streamline the permissions for the application code. Creating these directories ensures that they have the right permissions when we run the npm install command locally inside the containers. Once you have created the directories, you must set ownership on them to the node user. We will do this inside the Dockerfile by adding the following line:
|
1 |
mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app |
Ensuite, vous définirez le répertoire de travail en ajoutant la ligne suivante :
|
1 |
WORKDIR /home/node/app |
It’s a good idea to always set the WORKDIR so that Docker does not have to create one by default.
Add the following line to copy the package.json and package-lock.json files:
|
1 |
COPY package*.json ./ |
It’s recommended to add the COPY instruction before running npm install or copying application source code. It allows you to take advantage of Docker’s caching mechanism. During the build process, Docker checks whether it has a layer cached for every instruction. This means that if you have not changed the package.json file, then Docker will use the existing imager layer and avoid reinstalling node modules, hence faster build processes.
Before running npm install, add the following line to switch the user to node to ensure all the application files and node_modules directory are owned by the non-root node user:
|
1 |
USER node |
Notre conteneur est maintenant prêt à exécuter la commande npm install. Ajoutez la ligne suivante au Dockerfile :
|
1 |
RUN npm install |
Once node_modules have been installed, add the following line that will tell Docker to copy the application code into the application directory on the container with the right permissions and ownership, i.e. the non-root node user:
|
1 |
COPY --chown=node:node . . |
The last step is to expose the port 8090 on the container, as we had defined in our entry index.js file:
|
1 2 |
EXPOSE 8090 CMD [ "node", "index.js" ] |
EXPOSE sets which ports on the container will be open at runtime. CMD runs the command to start the application, in this case, node index.js.
Vous ne devriez avoir qu'une seule commande CMD dans le Dockerfile car seule la dernière prend effet. Veuillez consulter la documentation de référence du Dockerfile pour obtenir la liste de ce que vous pouvez faire avec Dockerfile.
Votre Dockerfile complet devrait ressembler à ceci :
|
1 2 3 4 5 6 7 8 9 |
FROM node:10-alpine RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app WORKDIR /home/node/app COPY package*.json ./ USER node RUN npm install COPY --chown=node:node . . EXPOSE 8090 CMD [ "node", "index.js" ] |
Vous pouvez maintenant sauvegarder et fermer le fichier.
La prochaine étape consiste à ajouter le fichier .dockerignore. Tout comme le fichier .gitignore file, the .dockerignore specifies which files and directories within the project directory should not be copied over to the container.
Ouvrez le fichier avec l'éditeur nano :
|
1 |
nano .dockerignore |
Ajoutez les lignes suivantes à l'intérieur du fichier :
|
1 2 3 4 |
node_modules npm-debug.log Dockerfile .dockerignore |
If working with a git repo, then you should also add the .git directory and the .gitignore file. Save and close the file.
Si tout s'est bien passé, il est temps de créer l'image de l'application en utilisant la commande docker build command. You can add the –t flag to the docker build command to tag the image with a memorable name as opposed to the random string that docker sets by default. We will also be pushing the image to Docker Hub so, it’s best to include your Docker Hub username in the tag.
We will use nodejs-express-image as the tag name. You are free to choose a tag name that you like. Here is the command to build the image:
|
1 |
sudo docker build -t your_dockerhub_username/nodejs-express-image . |
N'oubliez pas de remplacer your_dockerhub_username par votre véritable nom d'utilisateur Docker Hub. Le . (point) à la fin spécifie que le contexte de construction est le répertoire actuel.
Le processus de construction prend une minute ou deux. Une fois terminé, entrez la commande pour vérifier vos images :
|
1 |
sudo docker images |
Vous devriez voir quelque chose comme ceci :
Rappelez-vous, nous avons remplacé your_dockerhub_username par un véritable nom d'utilisateur.
Après avoir confirmé que votre image a été construite, vous pouvez maintenant créer un conteneur avec l'image en utilisant docker run. Les options suivantes seront incluses :
-p: publishes the port on the container and maps it to a port on the host system. We will use port 80 on the host system for demonstration purposes. However, if you have another process running on that port, feel free to modify this as necessary. Learn more about liaison de port à partir de la documentation Docker.-d: for detached mode. Allows the container to continue running in the background.--name: you can use this to set a memorable name instead of letting Docker assign a random string.
La commande pour construire le conteneur est la suivante. Remplacez votre nom d'utilisateur Docker Hub de manière appropriée :
|
1 |
sudo docker run --name nodejs-express-image -p 80:8090 -d your_dockerhub_username/nodejs-express-image |
Attendez que le conteneur soit construit et commence à s'exécuter. Vous pouvez utiliser cette commande pour inspecter tous les conteneurs en cours d'exécution :
|
1 |
sudo docker ps |
Vous devriez voir une sortie similaire à la suivante :
Comme on peut le voir dans la sortie, le conteneur est maintenant en cours d'exécution. Vous pouvez le visualiser dans le navigateur si vous visitez l'adresse IP publique de votre serveur sans le port dans le navigateur. Votre page d'accueil va se charger :
Vous avez déployé avec succès un site web statique Node Express avec Docker. Voyons comment nous pouvons pousser cette image vers Docker Hub pour une utilisation future et à des fins de mise à l'échelle.
Étape 4 : Travailler avec les dépôts d'images Docker
Vous pouvez pousser vos images vers des registres d'images comme Docker Hub et les sauvegarder pour une utilisation future, les partager avec d'autres développeurs ou permettre la mise à l'échelle de vos conteneurs. Nous pouvons pousser l'image que nous avons créée vers Docker Hub et l'utiliser pour recréer un conteneur.
Utilisez la commande suivante pour vous connecter à votre compte Docker Hub. Remplacez-le par votre véritable nom d'utilisateur Docker Hub :
|
1 |
sudo docker login -u your_dockerhub_username |
Enter your password when prompted. Once logged in, a ~/.docker/config.json file is created in your user’s home directory containing your Docker Hub credentials.
Une fois cela configuré, entrez la commande suivante pour pousser l'image vers Docker Hub, en spécifiant le tag que vous avez défini lors de la construction de l'image précédemment :
|
1 |
sudo docker push your_dockerhub_username/nodejs-express-image |
Cette commande pousse l'image Docker vers votre compte Docker Hub. Si vous visitez votre compte, vous pouvez voir votre image récemment poussée :
Nous pouvons tester l'utilité du dépôt d'images en détruisant le conteneur d'application actuel et en le reconstruisant à l'aide de l'image du dépôt.
Listez vos conteneurs actuels en saisissant la commande :
|
1 |
sudo docker ps |
Vous devriez voir une sortie similaire à ceci :
Note the CONTAINER ID listed in your output, copy it, and use it to stop your container with the command, replacing the ID with yours:
|
1 |
sudo docker stop 1bb2d65279bb |
Saisissez la commande suivante pour lister toutes les images Docker disponibles sur votre système :
|
1 |
sudo docker images –a |
La sortie affichera le nom de votre image, l'image node.js et d'autres images issues du processus de construction.
Saisissez la commande suivante pour supprimer les images, y compris les images inutilisées ou orphelines :
|
1 |
sudo docker system prune |
Type y to confirm. This removes the stopped containers and images. If you list them you will see an empty list in the output:
À présent, vous avez supprimé à la fois le conteneur exécutant l'application et l'image elle-même. Pour en savoir plus sur la suppression des conteneurs, images et volumes Docker, suivez notre tutoriel.
Nous pouvons maintenant recréer l'ensemble du processus en téléchargeant d'abord l'image depuis Docker Hub avec la commande suivante. Remplacez votre nom d'utilisateur Docker Hub de manière appropriée :
|
1 |
sudo docker pull your_dockerhub_username/nodejs-express-image |
Listez à nouveau vos images Docker avec la commande :
|
1 |
sudo docker images |
Vous devriez voir l'image dans la sortie :
Vous pouvez maintenant reconstruire votre conteneur à l'aide de la commande de l'Étape 3. Bien sûr, remplacez votre nom d'utilisateur Docker Hub là où c'est nécessaire :
|
1 |
sudo docker run --name nodejs-express-image -p 80:8090 -d your_dockerhub_username/nodejs-express-image |
Listez vos conteneurs pour confirmer qu'il a été reconstruit :
|
1 |
sudo docker ps |
Vous devriez voir une sortie similaire :
Dans votre navigateur, accédez à l'adresse IP publique de votre serveur et vous devriez voir votre application s'exécuter.
Conclusion
Si vous avez suivi le tutoriel jusqu'ici, vous disposez maintenant d'un site web statique créé avec Express et Bootstrap, et déployé avec Docker. Vous avez utilisé les fichiers du site web statique pour créer une image Docker et vous avez utilisé cette image pour créer un conteneur. Vous avez ensuite poussé l'image vers un registre d'images Docker, Docker Hub, la rendant disponible pour une utilisation future ou une mise à l'échelle. Pour tester l'utilisation du registre d'images, vous avez détruit les images et les conteneurs, récupéré les images depuis le registre et reconstruit les conteneurs.
Ce tutoriel a expliqué comment déployer une application Node.js. Si vous souhaitez apprendre à utiliser une pile de développement web différente, nous avons un tutoriel sur Déploiement d'une application Laravel avec Docker Compose sur Nginx.
Pour plus de ressources sur l'utilisation de Docker, consultez les tutoriels suivants :
- Comment installer et configurer Docker Compose sur Ubuntu 20.04
- Comment partager des données entre un conteneur Docker et un hôte
- Installation et configuration de Docker sur CentOS 7
Bonne informatique !











Commentaires
Aucun commentaire pour l'instant. Soyez le premier.