Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Distribuire applicazione Node.js: usare Docker o pkg

Eseguire un'app Node.js richiede l'installazione del framework, ma possiamo distribuirla ed evitare questo onere di installazione sfruttando Docker o pkg.
Eseguire un'app Node.js richiede l'installazione del framework, ma possiamo distribuirla ed evitare questo onere di installazione sfruttando Docker o pkg.
Link copiato negli appunti

Realizzare applicazioni con Node.js è facile e divertente. La potenza di questa piattaforma, una vasta raccolta di librerie e la relativa semplicità d'uso ne hanno incoraggiato la rapida diffusione.

Tuttavia, dato che un'applicazione sviluppata con Node.js è composta da codice JavaScript che viene eseguito a runtime da Node (o più precisamente, dal motore V8 di Chrome), è necessario disporre dell'intero ambiente per poterla eseguire correttamente. Tale caratteristica può complicare la distribuzione dell'applicazione. Non si può infatti pretendere che ogni macchina target disponga di Node.js e di tutte le librerie usate dall'applicazione.

Una soluzione al problema, estremamente diffusa in ambito backend, consiste nel distribuire l'applicazione sotto forma di immagine Docker.

Creare un'immagine Docker per la nostra applicazione

Si supponga di aver sviluppato una semplice applicazione con il framework Express, app.js, il cui codice è riportato sotto:

var express = require('express');
var app = express();
app.get('/', function (req, res) {
	res.send('Ciao Mondo!');
});
app.listen(3000, function () {
	console.log('Applicazione in ascolto sulla porta 3000!');
});

Si tratta ovviamente della classica applicazione Hello World che risponde alle richieste HTTP pervenute sulla porta 3000 con la stringa "Ciao Mondo". Per brevità, supponiamo che la directory corrente contenga già i moduli node necessari e tutte le librerie richieste per un corretto funzionamento dell'applicazione, oltre ad un file package.json correttamente compilato.

Per realizzare un'immagine Docker in grado di eseguire questa applicazione, bisogna prima di tutto creare un file che la descriva: il Dockerfile. Esso è un semplice file di testo che indica a Docker quale immagine di base utilizzare, quali file copiare nell'immagine, quali porte esporre e quale processo eseguire all'interno del container.

Un tipico Dockerfile per l'applicazione di cui sopra è il seguente:

FROM node:10-alpine
MAINTAINER vostro nome 
RUN mkdir -p /home/node/app/node_modules
RUN chown -R node:node /home/node/app
WORKDIR /home/node/app
COPY package*.json ./
RUN npm install
COPY . .
RUN chown -R node:node /home/node/app	
USER node
EXPOSE 3000
CMD [ "node", "app.js" ]

L'immagine che verrà generata sarà basata sulla node:10-alpine: si tratta di un'immagine ufficiale di Node.js, basata sulla distribuzione Linux Alpine e contenente Node.js alla versione stabile (la 10 appunto, al momento in cui scriviamo).

Le istruzioni seguenti copiano il contenuto della directory di lavoro nell'immagine, inclusi i moduli richiesti e assegnano all'utente "node" la proprietà della directory contenente l'applicazione.

Infine, l'istruzione CMD indica l'entrypoint del container, ovvero il comando da eseguire. In questo caso ovviamente, verrà eseguito il comando node app.js.

Esistono altre immagini di base che si possono utilizzare laddove, ad esempio, l'applicazione dipenda da librerie native non disponibili in Alpine. Il vantaggio di questa immagine di base rispetto ad altre è che è molto più "snella", e questo permette di creare immagini leggere. L'immagine descritta nel Dockerfile dell'esempio occuperà poche decine di MB.

Per creare l'immagine, sarà sufficiente utilizzare il comando docker build, seguito dal tag da assegnare all'immagine. Ad esempio:

# docker build -t miaapp:latest

Eseguibili standalone

Sebbene i container Docker siano la soluzione preferibile nel caso di applicazioni di backend essi non sono utili nel caso di applicazioni standalone, come ad esempio una utility da riga di comando.

In questo caso, sarebbe preferibile disporre di un file eseguibile, come quelli prodotti dal processo di compilazione tipico di altri linguaggi. Esistono diversi strumenti che aggiungono questa funzionalità a Node.js, tra i quali citiamo: nexe, pkg, encloseJS ed altri.

Per creare un file eseguibile per la nostra applicazione, installiamo l'utility pkg con il comando:

# npm install -g pkg

Ovviamente questo passaggio va effettuato una volta sola, dato che pkg è installato in modo globale (flag -g).

A questo punto, è sufficiente assicurarsi che il file package.json contenga la proprietà bin e che essa riporti al file .js principale. Ad esempio:

{
	"name": "miaapp",
	"version": "1.0.0",
	"description": "Una fantastica applicazione dimostrativa",
	"main": "app.js",
	"bin": "app.js",
	"scripts": {
		"test": "echo \"Error: no test specified\" && exit 1"
	},
	"author": "Sergio Monteleone",
	"license": "",
	"dependencies": {
		"express": "^4.16.4"
	}
}

Per generare gli eseguibili basterà invocare il comando pkg, indicando il percorso della directory dei sorgenti. Ad esempio:

# pkg .

Per default il programma crea tre eseguibili distinti: uno per Windows, uno per Linux ed uno per macOS. Si può specificare l'elenco delle piattaforme target usando lo switch da riga di comando -t (targets). Ad esempio, per compilare soltanto l'eseguibile per Windows usare il comando:

# pkg -t node10-win-x64 .

Più target possono essere specificati separandoli da virgola. Ad esempio, per crare gli esegubili per Windows e macOS scriveremmo:

# pkg -t node10-win-x64,node10-macos-x64 .

Come si evince, la specifica dei target è composta da tre parti separate da un trattino. La prima indica la versione di Node.js da utilizzare (nell'esempio node10). La seconda indica il sistema operativo (win, linux, macos, alpine) e la terza indica l'architettura da supportare (x64, x86, armv6, armv7). Ovviamente, non tutte le possibili combinazioni sono disponibili. Ad esempio, node10-win-armv6 produrrà un errore poiché non esiste una versione di Windows disponibile per architettura armv6.

La compilazione dell'applicazione in un unico file eseguibile semplifica notevolmente il processo di distribuzione ed installazione, e rende più difficoltoso il reverse engineering, dato che i sorgenti dell'applicazione non vengono distribuiti.

Per ulteriori informazioni sull'uso di pkg, si rimanda alla pagina ufficiale del progetto.

Ti consigliamo anche