Modulo 04

Docker

Dopo Git per il codice e GitHub Actions per l'automazione, Docker si occupa dell'ultimo problema: far girare l'applicazione allo stesso modo ovunque.

Introduzione a Docker

Docker è una piattaforma che permette di creare, eseguire e gestire applicazioni all'interno di container. Un container è un ambiente isolato che contiene tutto il necessario per eseguire un'applicazione: codice, librerie, dipendenze, configurazioni e sistema operativo di base. Grazie ai container è possibile eseguire lo stesso progetto su computer diversi senza problemi di compatibilità.

In questo modulo useremo Docker con l'immagine di Ubuntu e poi creeremo immagini personalizzate con Node.js e React.

L'immagine Ubuntu

Dopo aver installato Docker Desktop, scarichiamo l'immagine ufficiale di Ubuntu dal Docker Hub:

docker pull ubuntu

Per verificare che l'immagine sia stata scaricata, e vedere tutte le immagini presenti sul computer:

docker images

Creare un container Ubuntu

docker run -it ubuntu

-i mantiene attiva l'interazione con il terminale, -t crea un terminale virtuale: insieme permettono di usare Ubuntu direttamente dentro Docker.

exit

La prima immagine Docker

Creiamo una cartella hello-docker con un file hello.js:

console.log("Hello Docker!");

Nella stessa cartella creiamo un Dockerfile:

FROM node:20-alpine

WORKDIR /app

COPY . .

CMD ["node", "hello.js"]

Spiegazione del Dockerfile

Costruire e avviare

docker build -t hello-docker .
docker images
docker run hello-docker

Il risultato sarà: Hello Docker!

Per entrare dentro il container come se fosse un sistema operativo:

docker run -it hello-docker sh
node hello.js

Un'app React con Docker

Creiamo un nuovo progetto con Vite, scegliendo React e TypeScript:

npm create vite@latest react-docker
cd react-docker
ls

Dockerfile per React

FROM node:20-alpine

RUN addgroup app && adduser -S -G app app

USER app

WORKDIR /app

COPY package*.json ./

USER root

RUN chown -R app:app .

USER app

RUN npm install

COPY . .

EXPOSE 5173

CMD npm run dev

Spiegazione, riga per riga

Creiamo anche un file .dockerignore per evitare di copiare node_modules dentro l'immagine:

node_modules/

Costruire e avviare il container React

docker build -t react-docker .
docker run react-docker

L'app parte, ma non è ancora raggiungibile dal browser: serve mappare la porta.

docker run -p 5173:5173 react-docker

-p porta_computer:porta_container collega la porta del computer a quella del container. A questo punto il sito è su http://localhost:5173/.

Se il sito non è raggiungibile, in package.json cambia "dev": "vite" in "dev": "vite --host", così il server accetta connessioni da fuori il container.

Gestire i container

docker ps              # container attivi
docker ps -a           # tutti i container creati
docker stop ID_CONTAINER
docker rm ID_CONTAINER
docker container prune # elimina tutti i container fermi

Aggiornamento automatico con i volumi

Normalmente ogni modifica al codice richiede una nuova build. Con i volumi, la cartella del progetto si sincronizza automaticamente col container:

docker run -p 5173:5173 -v "$(pwd):/app" -v /app/node_modules react-docker

-v collega una cartella del computer a una del container: ogni modifica al codice si riflette subito, senza rebuild.

Docker Init

Docker può generare automaticamente una configurazione iniziale:

mkdir vite-project
cd vite-project
docker init

Durante la configurazione: scegli Node.js come linguaggio, la versione consigliata, npm come package manager, No a npm run build, npm run dev come comando di avvio e 5173 come porta.

Docker Compose

Nel file compose.yaml generato, rinomina il servizio in server: web, rimuovi la sezione environment: NODE_ENV: production e aggiungi i volumi sotto le porte:

volumes:
  - .:/app
  - /app/node_modules

Per avviare tutto:

docker compose up

Su Linux, in caso di problemi di permessi:

sudo docker compose up

Cosa abbiamo imparato

Installare e usare immagini Docker, creare container, scrivere Dockerfile personalizzati, containerizzare un'app React, gestire porte e volumi e orchestrare tutto con Docker Compose. Docker è lo strumento che rende un'applicazione facilmente distribuibile e replicabile in qualsiasi ambiente — l'ultimo tassello di una pipeline DevOps completa.