La containerizzazione consiste nel raggruppare un’applicazione, le sue dipendenze e le librerie insieme in modo che possano essere utilizzate come plug-and-play su qualsiasi tipo di infrastruttura. Ciascun raggruppamento è chiamato container.
Perché containerizzare un servizio Node.js?
Come discusso nella sezione precedente, containerizzare un servizio Node.js significherebbe raggruppare l’applicazione, le sue dipendenze, librerie e persino la configurazione in un unico container.La containerizzazione offre i seguenti vantaggi:
- Portabilità. Poiché abbiamo raggruppato tutti i requisiti dell’app in un container, le stesse immagini possono essere installate in sviluppo, staging e produzione.
- Veloce e leggero. I container tendono ad essere molto più veloci rispetto alle macchine virtuali (VM) o al metallo nudo poiché eseguono solo i requisiti dell’app, mentre storicamente le VM o il metallo nudo avvierebbero l’intera macchina e tutte le app.
- Scalabile. Con i due benefici sopra citati, la scalabilità diventa molto facile poiché i container sono veloci, efficienti e facili da distribuire.
In questo articolo, ci concentreremo specificamente su containerizzare un’app Node.js.
Prerequisiti
Strumenti e Software
Docker (Docker Engine e Docker CLI)
Dovremo installare Docker per gestire i nostri container. Docker Engine gestisce il runtime e la CLI può essere utilizzata per interagire tramite la riga di comando.
Node.js e npm/yarn Installati (Per lo Sviluppo/Test Iniziale)
Sarà necessario avere Node.js e npm installati per installare le dipendenze delle librerie e eseguire il servizio.
Kubernetes o Docker Compose per Gestire Più Container (Opzionale)
Sarà necessario Kubernetes o Docker Compose per gestire più container.
Fondamentali
Struttura dell’applicazione Node.js:
- Si presume che il lettore comprenda già il ruolo del file principale (
app.js
oindex.js
) nel progetto, insieme al ruolo di altri file comepackage.json
eyarn.lock
. - Questo articolo non approfondirà neanche altri aspetti del progetto, come controller, middleware e routes.
Comandi Docker di Base e Sintassi Dockerfile
Comandi Docker:
docker ps -> Lists all the containers running on the system
docker pull -> Pulls any image from the docker hub or official registry of Docker
docker build -> Creates an image from the docker file
docker run -> Starts a container from an exiting image
docker stop -> Stops a container if it has crashed or if you want to switch the container
Istruzioni principali del Dockerfile:
FROM -> Every DockerFile
WORKDIR -> Set the working directory inside the container
COPY (or ADD) -> Transfers the application's files to the image
RUN -> Executes commands during build time
CMD -> Sets the default command to be run when the container is started from the image
EXPOSE -> Specifies the port the container listens on
ENV -> Sets environment variables used during build and runtime
Sia le tabelle trattate che la struttura Node.js sono sufficienti per iniziare con la containerizzazione e per distribuire il servizio Node.js.
Configurazione del Servizio Node.js
Configurare l’ambiente Node.js è un processo semplice. Assicurati di avere Node.js installato sul tuo computer. Se hai dei dubbi, fai riferimento all’allegato (1). Una volta installato, apri il terminale e verifica l’installazione digitando.
node -v
npm -v
Crea una cartella di progetto e inizializza il tuo progetto come segue:
npm init -y
Installa il modulo express
npm install express
Crea un file server, chiamiamolo server.mjs, in cui possiamo aggiungere il percorso e la logica corrispondente al percorso. Poiché questo articolo tratta più della containerizzazione, manterremo la logica del punto finale molto semplice. Qualcosa del genere:
import express from "express";
const app = express();
const port = 8080;
app.get('/', (req, res) => {
res.send('Welcome to my demo service!');
});
app.listen(port, () => {
console.log(`Demo Service is running on port ${port}`);
});
Ora il servizio è pronto per essere avviato, navigare nella directory del progetto nel terminale e eseguire questo comando:
node server.mjs
Il servizio è attivo e in esecuzione; se visitiamo http://localhost:3000, vedremo:
“Benvenuti nel mio server”
Creazione del Dockerfile
Revisioniamo cosa è il Dockerfile, esso contiene le istruzioni per creare l’immagine di Docker. Creiamo un Dockerfile nella directory principale. Durante questo passaggio, come discusso nelle istruzioni del Dockerfile, dobbiamo fare le seguenti cose:
FROM node:18-alpine => Indicate the base image to use. Here we're using the official Nodejs 14 image.
WORKDIR /usr/src/app => Sets the working directory in the container.
COPY package*.json ./ => Duplicate the package.json and package-lock.json files to the working directory.
RUN npm install => Installs the app package dependencies.
COPY . . => Copies the remaining of the app to the working directory.
EXPOSE 8080 => Exposes the port our app is listening on.
CMD ["node", "app.js"] => Defines the command to start your Node.js application.
Creazione ed esecuzione dell’immagine di Docker
Dalla radice del terminale, naviga al tuo progetto e esegui il seguente comando:
docker build -t image-name .
Dove image-name
è il nome dell’immagine Docker. Il .
alla fine imposta il contesto sulla directory corrente.
Una volta che l’immagine è stata costruita, creeremo il contenitore e eseguiremo l’app Node.js con il seguente comando:
docker run --name container-name -p 8080:8080 image-name
Una volta che quanto sopra è avvenuto con successo, puoi verificare che il servizio stia funzionando eseguendo docker ps
, e quindi andando alla stessa URL di localhost di prima.
Caricamento delle immagini su un Registro
Ora che la tua immagine è pronta, è ora di caricarla in un registro. Per lo scopo di questo articolo, carichiamola solo su Docker Hub. Docker Hub è un servizio basato su cloud per memorizzare, condividere e gestire le immagini dei container Docker.
Crea un account su https://hub.docker.com/ e accedi con il tuo account.
docker login
Una volta effettuato l’accesso, le immagini create localmente possono essere aggiunte come segue:
docker tag image-name:tag dockerhub-username/repository-name:tag
Dove:
tag
è olatest
o un numero di versione.nome-del-repository
è il nome del repository desiderato.
Successivamente, carica l’immagine come segue:
docker push dockerhub-username/repository-name:tag
Conclusione
Come possiamo vedere, la containerizzazione rende i flussi di lavoro e i servizi complessi veloci, portabili e scalabili separando le dipendenze. Una volta implementata, ne beneficia l’intero team.Ti incoraggio a esplorare le funzionalità avanzate come le build a più fasi e la rete dei container. Inoltre, considera di apprendere gli strumenti di orchestrare (ad esempio, Kubernetes) e integrare i percorsi CI/CD per ottimizzare il tuo flusso di sviluppo.
Appendice
Source:
https://dzone.com/articles/containerization-of-a-nodejs-service