In questo sito avete visto più volte alcune soluzioni che si rifanno a parti di “agile development“. Quella oggetto di questo post si prefigge di creare una sorta di metodologia di sviluppo in Node Js, adattabile comunque ad altri framework o linguaggi di programmazione, all’interno di Docker.
Non nego che ho faticato più di quello che mi sarei aspettato per giungere ai risultati voluti. Le documentazioni sono spesso criptiche, talvolta saltano o pasticciano passaggi non proprio secondari. Motivo per cui ho deciso di scriverne una mia.
Quali sono i goal da raggiungere?
Innanzitutto voglio avere un ambiente di sviluppo in Node.JS dinamico, non vincolato ad una specifica versione, cioè questa deve essere possibile cambiarla alla bisogna. Non voglio avere installato sul laptop Node.Js, questo deve essere disponibile solo nell’ambiente Container di Docker.
Cosa è necessario?
Avere installato Docker, Visual Studio Code (o un editor a vostra preferenza), accesso ad un terminale (preferibilmente Bash o Zsh).
Procedura.
Partiamo con il decidere il nome della nostra applicazione, in questo esempio la chiameremo “mynode“. Quindi per prima cosa dobbiamo creare una cartella con questo nome.
Ho scelto di utilizzare l’ultima versione disponibile di Node. Quello che abbiamo bisogno per partire è creare un file package.json che andrà ad istruire cosa necessita Node per essere avviato.
{
"name": "mynode",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "nodemon index.js"
},
"license": "MIT",
"dependencies": {
},
"devDependencies": {
"nodemon": "latest"
}
}
Come possiamo vedere abbiamo inserito come dipendenze di sviluppo Nodemon che ci servirà poi successivamente a sviluppare senza dover riavviare ad ogni modifica che facciamo.
Fatto questo andiamo ad istruire Docker su come creare un file immagine. Sempre con il nostro editor creiamo un file che si chiama “Dockerfile” (attenzione alla prima lettera che deve essere maiuscola).
FROM node:latest
WORKDIR /srv/app
COPY package*.json /srv/app
ENV PORT 3000
EXPOSE 3000
RUN npm install -g nodemon
COPY . /srv/app
CMD ["nodemon", "bin/www"]
In sostanza stiamo dicendo a Docker che vogliamo utilizzare l’ultima versione di Node, e che all’interno del contenitore la cartella operativa sarà /srv/app. Successivamente ho indicato di copiare dal nostro sistema locale il file package.json creato in precedenza. Quindi viene creata ed esposta la porta 3000 ed installato/attivato Nodemon in modalità “global”.
Dobbiamo quindi creare il file YML che “pilota” il contenitore, ovvero sempre via editor creiamo un file che si chiamerà “docker-compose.yml“. Tutto in minuscolo, è importante che i nomi file siano quelli, perché Docker li andrà a cercare per default.
version: "3"
services:
app:
build: .
container_name: mynode
ports:
- 80:3000
volumes:
- ./:/srv/app
In questo caso abbiamo fissato il nome del nostro contenitore a “mynode”, mappato la porta del cotainer (la 3000) con la nostra locale 80. Allo stesso modo accoppiato la nostra cartella con quella del contenitore.
In precedenza nel file package.json abbiamo indicato il file di partenza, ovvero index.js. Lo dobbiamo dichiarare anch’esso preventivamente, si tratta del file di esempio di partenza di NodeJS e lo potremo poi modificare successivamente come meglio crediamo.
const http = require('http');
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World by Tosolini');
});
server.listen(port, () => {
console.log(`Server running at ${port}`);
});
Abbiamo sostanzialmente finito, poiché abbiamo creato le parti infrastrutturali di base. Non ci resta che lanciare il nostro primo avvio su Docker con il comando:
docker-compose up --build
Segue una fase di scarico di Node:latest (se non l’avevate già scaricato in precedenza), quindi si procede alla creazione di una immagine che si chiamerà mynode_app che deriva dal container che avevamo dichiarato, e dal nome del service indicati nel file YML. Contestualmente viene creato e lanciato il container vero e proprio.
Se infatti apriamo il browser alla pagina http://localhost vedremo la scritta “Hello World by Tosolini”.
Se apriamo il Docker Dashboard, vedremo il nostro contenitore in funzione.
Da qui in poi possiamo proseguire con lo sviluppo, attraverso Visual Studio Code che tramite i moduli integrati ci permette di scrivere e interagire con il contenitore come fosse un server reale.
Se vogliamo modificare la versione di Node, sarà sufficiente manipolare il Dockerfile sostituendo al posto di node:latest la versione, ad esempio node:14 per la versione 14.
In realtà questo è un livello basico di manipolazione sia di Dockerfile che docker-compose.yml. Ad esempio potremo creare un ambiente di sviluppo e uno di produzione, o installare e istanziare un database.