Docker – Création d’une image avec une app code.js

1 février 2023

1 – Tester l’application node.js dans un conteneur Ubuntu

$ sudo apt update && sudo apt install npm
$ npm install socket.io socket.io-client express --save. // Attention, il ne faut pas être dans le dossier /

# Express --> is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
# Socket.IO --> enables real-time bidirectional event-based communication between a client and a server.
# --save --> ajout des dépendances dans le fichier '~/package.json'.  Note: Plus requis depuis npm 5

2 – Fichier ‘package.json’

{
  "dependencies": {
    "express": "^4.18.2",
    "socket.io": "^4.6.0",
    "socket.io-client": "^4.6.0"
  },
   "scripts": {
       "start": "node serveur.js"
   }
}

3 – Application serveur.js

// Fichier: serveur.js
// Auteur: Alain Boudreault
// Date:   2023.02.07
// ----------------------------------------------------------------------------
// Description: Petit serveur web en node.js qui sera utilisé pour construire
//              une image Docker perso.
// ----------------------------------------------------------------------------

var http = require('http'); // Importation d'un module des plus important! ;-)
let PORT = 8080;
let AUTEUR = "Alain Boudreault";

var server = http.createServer(function (req, res) {   //Création d'un serveur Web
    if (req.url == '/') { //Vérification de l'URL    
        // Renseigner le 'header'
        res.writeHead(200, { 'Content-Type': 'text/html' }); 
       // Renseigner le contenu de la réponse    
        res.write('<html><head><meta charset=\"UTF-8\"></head><body><p>Cette page est complètement dénuée d\'information pertinente ...</p>');
    }
    else if (req.url == "/etudiant") {
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.write('<html><head><meta charset=\'UTF-8\'></head><body><p>Voici les réponses à l\'examen: ...</p></body></html>');    
    }
    else if (req.url == "/api") {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.write(JSON.stringify({ version_api: "1.01", citation: "Ici la voix des mistérons"})); 
        // res.write('{"version_api":"1.0"}');
    }
    else {
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.write('<html><head><meta charset=\"UTF-8\"></head><body><hr/><center><h1 style="color:red">NON, pas une erreur 404, tu fais dur!!!</h1></center><hr/>');
        res.write('<h2 style="color:blue">Requête = ' + req.url + '</h2>');
    }
    res.end();  // Fermer la requête
});

server.listen(PORT); //Écoutons ce que les clients ont à demander ...

console.log('Exemple par ' + AUTEUR);
console.log('----------------------------------');
console.log('Mon petit serveur web Node.js vous écoute sur le port ' + PORT + ' ... cé pas ti fin ca!');

4 – Démarrage de l’application node.js

$ npm start &

# Tester l'application:

$ curl localhost:8080
$ curl localhost:8080/api
...

Section B – Bâtir l’image de l’application

5 – Le Dockerfile

# À partir de l'image de base:
FROM node:alpine

#Installer les dépendances npm
# NOTE:  Il ne faut pas être la racine sinon l'opération va échouer!
WORKDIR /usr/app
COPY ./ /usr/app
RUN npm install

# Exposer le port IP du serveur Web.js
EXPOSE 8080

# Renseigner la commande de départ
CMD [ "npm","start" ]

6 – Produire l’image de notre application web serveur

$ docker build -t notre_serveur_web .

6 – Lancer l’application

$ docker run -d --rm -it --name yo -p 80:8080 notre_serveur_web

7 – Tester l’application



8 – Version du serveur avec le module Express.js

// Fichier: serveur02.js
// Auteur: Alain Boudreault
// Date:   2023.02.09
// ----------------------------------------------------------------------------
// Description: Petit serveur web en node.js qui sera utilisé pour construire
//              une image Docker perso.
//              Note: Utilisation du module Express.js
// ----------------------------------------------------------------------------

var express = require('express');
var app = express();

let PORT = 8080;
let AUTEUR = "Alain Boudreault";

app.get('/', function (req, res) {
    res.send(`
    <html><body>Ceci est un requête de type: GET<hr/>
    <h1>Bonjour 420-4D4</h1></body></html>
    `);
});

app.get('/api', function (req, res) {
    res.send("<html><body>Requête sur l'API maison<hr/>" +
    JSON.stringify({ version_api: "1.01", citation: "Ici la voix des mistérons"}) +
    "</body></html>"
    );
});

app.post('/submit-data', function (req, res) {
    res.send('Ceci est un requête de type: POST');
});

app.put('/update-data', function (req, res) {
    res.send('Ceci est un requête de type: PUT');
});

app.delete('/delete-data', function (req, res) {
    res.send('Ceci est un requête de type: DELETE');
});

// Traiter une route non définie:
app.use((req, res, next) => {
    res.status(404).send(`<html>
        <head><meta charset=\"UTF-8\"></head>
        <body><hr/><center>
        <h1 style="color:red">NON, pas une erreur 404, tu fais dur!!!</h1>
        </center><hr/>` +
        '<h2 style="color:blue">Requête = ' + req.url + '</h2></body></html>'
        );
  });

// Afficher un message sur la console
// Note: Via Docker, il est possible d'afficher les messages de la console avec l'option logs:
// $ docker logs id_CONTENEUR  
var server = app.listen(PORT, function () {
    console.log('Exemple par ' + AUTEUR);
    console.log('----------------------------------');
    console.log('Mon petit serveur web Node.js vous écoute sur le port ' + PORT + ' ... cé pas ti fin ca!');
});

Section 3 – arguments perso

# Specify a base image
FROM node:alpine

#Définir un argument à utiliser avec docker build --build-arg numero_port=
#Par exemple,
# docker build -f Dockerfile.srv03 -t web_express --build-arg numero_port=99 .
ARG numero_port

#Définir une variable d'environnement qui sera disponible dans le conteneur
#Pour la lire en node.js: const PORT = parseInt(process.env.PORT) || 8080;
ENV PORT=$numero_port
# Ou: ENV PORT=${numero_port}

WORKDIR /usr/app
COPY ./ /usr/app
RUN npm install

EXPOSE $numero_port

CMD [ "npm","start" ]

// Fichier: serveur02.js
// Auteur: Alain Boudreault
// Date:   2023.02.09
// ----------------------------------------------------------------------------
// Description: Utilisation d'une variable d'environnement pour le port TCP
// ----------------------------------------------------------------------------

var express = require('express');
var app = express();

const PORT = parseInt(process.env.PORT) || 8080;
const AUTEUR = "Alain Boudreault";

app.get('/', function (req, res) {
    res.send("</body></html><h1>Le serveur écoute sur le port: " + PORT + "</h1></body></html>");
});

// Afficher un message sur la console
// Note: Via Docker, il est possible d'afficher les messages de la console avec l'option logs:
// $ docker logs id_CONTENEUR  
var server = app.listen(PORT, function () {
    console.log('Exemple par ' + AUTEUR);
    console.log('----------------------------------');
    console.log('Mon petit serveur web Node.js vous écoute sur le port ' + PORT + ' ... cé pas ti fin ca!');
    console.log("parseInt(process.env.PORT) = " + parseInt(process.env.PORT));
});

{
    "dependencies": {
      "express": "^4.18.2",
      "socket.io": "^4.6.0",
      "socket.io-client": "^4.6.0"
    },
    "scripts": {
         "start": "node serveur03.js"
     }
  }

Référence pour la syntaxe Dockerfile