“Installa una macchina virtuale Linux e ricrea esattamente lo stesso ambiente.”
Tre mesi dopo il mio ingresso in azienda, l’atmosfera in ufficio era strana. L’unico senior del team era stato assegnato a un altro progetto e, più che pensare al passaggio di consegne, era occupato a preparare le proprie cose. Il team leader, invece, si era staccato da tempo dal lavoro di sviluppo pratico ed era piuttosto lontano dalle tendenze tecniche più recenti.
Un giorno il team leader mi chiamò. “Quando il tuo senior se ne andrà, l’unica persona che potrà gestire i server sarai tu. Anche se il server va giù, devi essere in grado di ripristinarlo da solo. Installa Linux come macchina virtuale, VM, sul tuo attuale portatile di sviluppo, Windows, e prova a ricostruire esattamente lo stesso ambiente del server di produzione.”
Da quel giorno iniziò la mia fatica. Installai VMware, scaricai il file ISO di Ubuntu, e solo l’installazione mi portò via mezza giornata. Frugando nel wiki aziendale installai Java, Node.js e PostgreSQL. Pensai: “Più nuovo sarà meglio”, quindi installai Java 17, ma poi scoprii che il codice legacy si basava su Java 8 e non compilava nemmeno. Dovetti eliminare tutto e reinstallare. Ogni volta che cambiavo una sola riga di codice, dovevo lanciare mvn build, spostare il file jar nella VM ed eseguirlo lì. Era una sofferenza pura.
A un certo punto mi venne un dubbio. “Aspetta un attimo. L’ultima volta che abbiamo fatto deploy sul server di produzione, non era bastato scrivere una sola volta docker service update?”
La mia macchina virtuale locale era così pesante e richiedeva una montagna di configurazioni. Allora che cos’era esattamente quel ‘Docker’ sul server di produzione, capace di aggiornare tutto con un solo comando?

La soluzione pesante: la macchina virtuale
Il metodo che mi aveva indicato il team leader, cioè installare Linux sopra Windows, è esattamente ciò che chiamiamo macchina virtuale, VM. È come costruire un’intera ‘casa virtuale’, un guest OS, sopra un computer fisico, l’host.
- Come funziona: su un solo computer si fanno girare più OS. (Linux sopra Windows, e sopra ancora un altro Linux…)
- Il problema: per costruire una casa bisogna rifare da zero tutto, dai pilastri alle pareti fino al bagno (il kernel).
- Per far girare una sola app devi installare per intero un OS da diversi gigabyte.
- L’avvio richiede un’eternità. (Ecco perché il mio portatile era diventato così lento)
- Le risorse vengono usate in modo inefficiente. (Anche quando non fa nulla, divora memoria solo per tenere in vita l’OS)
Alla fine una VM garantisce davvero l’isolamento dell’ambiente, ma per sviluppo o deploy è semplicemente troppo pesante e troppo lenta da scambiarsi continuamente.
La rivoluzione leggera: Docker
Per questo è arrivato Docker, cioè la tecnologia dei container. Docker non costruisce un’intera casa come fa una VM. Al contrario, pianta una tenda.
- Come funziona: condivide il cortile (il kernel) di una casa già costruita (Host OS – Linux). Si pianta soltanto una tenda isolata (Container).
- Caratteristiche:
- Condivide l’OS (il kernel): dentro la tenda non c’è nessun OS pesante. Ci sono solo la mia app e le sue librerie.
- È leggero: le dimensioni si misurano in megabyte (MB).
- È veloce: l’avvio? Non esiste. Si accende alla stessa velocità con cui parte un singolo processo (millisecondi).
Il comando update che avevo eseguito sul server di produzione non stava reinstallando un pesante sistema operativo. Stava solo “smontando la vecchia tenda e rimontandone una nuova contenente la nuova versione del codice”. Per forza doveva finire in un attimo.

[Code Verification] Docker è davvero così leggero?
Non limitiamoci a dire che Docker è leggero: verifichiamolo davvero. Se l’obiettivo è eseguire un ambiente Linux, Ubuntu, la differenza tra una VM e Docker è netta.
- Ubuntu con una VM: download del file ISO (2GB) -> installazione (20 minuti) -> avvio (1 minuto).
- Ubuntu con Docker:
# Avvia Ubuntu con il comando Docker (scarica limmagine se mancante)
$ docker run -it ubuntu:latest /bin/bash
Risultato:
- Download: circa 30MB (un’image ridotta all’osso, con solo il nucleo essenziale di Ubuntu)
- Tempo di avvio: circa 0,5 secondi
Nel momento stesso in cui ho premuto Enter, ero già dentro un ambiente Ubuntu. Questo è possibile perché un container Docker non è un vero sistema operativo. È soltanto “uno spazio isolato che prende in prestito il kernel dell’host OS, cioè il mio computer, facendo finta di essere un OS separato”.
Consiglio pratico: il vero motivo per usare Docker
Da quando abbiamo introdotto Docker sul lavoro, la mia vita è cambiata completamente.
- Addio a “Configura l’ambiente”: un tempo, quando arrivava un nuovo assunto, gli consegnavamo un documento di 10 pagine A4 dicendo “Installa Java, imposta le variabili d’ambiente, installa il DB…”. Oggi gli diciamo soltanto: “Installa Docker e lancia
docker-compose up.” - Fuga dall’inferno delle versioni: e se il progetto A richiede Java 8 e il progetto B Java 17? Se li installi entrambi in locale, vanno in conflitto e si crea un groviglio. Con Docker puoi mettere Java 8 nel container A e Java 17 nel container B e avviarli contemporaneamente senza alcun problema, perché sono perfettamente ‘isolati’ (Isolation).
In chiusura: non consegniamo un eseguibile, ma un ambiente
Con l’arrivo di Docker è cambiato il paradigma dello sviluppo. Non inviamo più al server soltanto il codice sorgente, .java. Congeliamo in un’‘image’ anche la configurazione dell’OS, le librerie e le variabili d’ambiente necessarie al codice, e spediamo l’intero pacchetto.
Allora come viene davvero costruita questa magica ‘Docker image’? È solo un file compresso? Sorprendentemente, si dice che una Docker image sia composta da più layer sovrapposti, come una torta.
La prossima volta esploriamo il segreto dietro l’efficienza di Docker: le image e la loro struttura a layer.


