Cos’è Docker: la piattaforma che ha reso i container famosi
Da "a me funziona" a "Configure once... run everywhere". Capiamo come funziona Docker, i suoi componenti e tutti i comandi che dovete sapere per l'esame e per il laboratorio.
1. Cos’è Docker
E’ una piattaforma open source, realizzata in linguaggio Go, che consente di automatizzare il deployment, la gestione e l’esecuzione di applicazioni all’interno di container portabili, leggeri, autosufficienti.
Il motto di Docker è:
Configure once… run everywhere
Cioè una volta configurato un container contenente file, librerie e dipendenze sono certo che possa funzionare ovunque indipendentemente dall’hardware sottostante.
Ragazzi, vi chiederanno perché Docker è scritto in Go e non in Python o Java. Go è stato creato da Google proprio per fare programmi che gestiscono migliaia di processi in parallelo con pochissima RAM. Perfetto per gestire container. Se in sede d'esame dite questa cosa, fate vedere che non avete solo imparato a memoria.
In un’architettura a microservizi, Docker consente di isolare ciascun microservizio all’interno di un proprio container, facilitando il rilascio, la scalabilità e la manutenzione delle singole componenti in modo indipendente. Inoltre, grazie alla sua portabilità, Docker assicura che lo stesso container possa essere eseguito identicamente su diverse piattaforme: dal computer di sviluppo al server di produzione o al cloud.
Ricordate la lezione sui microservizi dell'E-commerce? Ecco dove si applica: User Service in un container, Product Service in un altro, Payment Service in un altro ancora. Docker è lo strumento che rende reale quella teoria. Senza Docker, i microservizi sarebbero solo un bel disegno alla lavagna.
2. Benefici di Docker
- Deployment semplificato: impacchettando un’applicazione in un singolo componente distribuibile e configurabile da riga di comando, Docker permette di semplificare il deployment senza doversi preoccupare della configurazione dell’ambiente
- Disponibilità rapida: virtualizzando solo il kernel del sistema operativo e le componenti necessarie all’esecuzione dell’applicazione e non l’intera macchina, il container si avvia in pochi secondi rispetto ai lunghi tempi di avvio di una macchina virtuale
- Controllo granulare: consente di suddividere ulteriormente le risorse computazionali in microservizi garantendo un maggiore controllo sull’esecuzione delle applicazioni e un miglioramento complessivo dell’intero sistema
- Cicli di rilascio semplificati: basta pubblicare la nuova immagine Docker e ricaricare il container per avere tutto aggiornato
- Testing semplificato: testare un’applicazione in un container è più semplice poiché l’ambiente di testing è identico a quello di produzione
Un'azienda deve rilasciare un aggiornamento del sito E-commerce il venerdì alle 18:00. Senza Docker: spegni tutto, spera che le librerie sul server siano uguali, incrocia le dita. Con Docker: fai docker pull mario/ecommerce:v2 e docker-compose up -d. Se qualcosa va storto, torni alla versione v1 in 3 secondi. Questa è la differenza tra dormire tranquilli e passare il weekend al telefono.
3. Componenti di Docker
Docker è composto da diversi elementi fondamentali:
Docker Engine
Il cuore della piattaforma, è il motore che gestisce la creazione, l’esecuzione e l’interazione con i container. È lui che parla direttamente con il kernel Linux per creare l'isolamento.
Pensate a Docker Engine come al motore di un'auto. Voi non lo vedete, ma è lui che fa muovere tutto. Senza Engine, immagini e container sono solo file fermi sul disco.
4. Docker Image - Il concetto più importante
Un’immagine immutabile che rappresenta l’applicazione e il suo ambiente di esecuzione. Da questa immagine è possibile generare uno o più container.
Un’immagine Docker rappresenta la definizione di un container, la specifica di tutto ciò che serve al container per essere eseguito.
Per fare una analogia, così come nel mondo della programmazione orientata agli oggetti:
- Una classe è una definizione astratta, un modello che descrive le proprietà e i comportamenti di un insieme di oggetti.
- Un oggetto è un’istanza concreta della classe, ovvero un’entità che esiste in memoria e che si comporta secondo la struttura definita dalla classe.
Analogamente, in Docker:
- Docker Image = Classe: Un modello statico e immutabile che definisce un ambiente di esecuzione completo: include il sistema operativo base, il software da eseguire, le dipendenze e tutte le configurazioni necessarie.
- Docker Container = Oggetto: Un container è un’istanza in esecuzione di quell’immagine. È l’oggetto concreto derivato dall’immagine, dotato di uno spazio isolato, risorse proprie (rete, file system, memoria) e capace di interagire con il mondo esterno.
Le immagini Docker sono costruite a partire da un’immagine di partenza e arricchite via via da metadati. Ogni modifica apportata ad un’immagine è contenuta in un layer ed è identificata da un ID e salvata sull’host. Se modifico un’immagine (aggiungo layer), per caricarla nel Docker registry non dovrò ricaricarla tutta ma caricherò solo i layer che rappresentano la modifica.
Questa cosa dei layer è fondamentale per capire perché Docker è così veloce. Immaginate un'immagine come una torta a strati. Se cambiate solo la glassa in cima (ultimo layer), non dovete rifare tutta la torta, ma solo quello strato. Per questo quando fate docker pull la seconda volta è quasi istantaneo: scarica solo ciò che è cambiato. Le aziende risparmiano terabyte di banda così.
5. Docker Container, Volumes, Dockerfile
Docker Container
Un’istanza in esecuzione di una Docker Image. I container Docker contengono software, librerie e dipendenze, condividono il Kernel del S.O. host ma sono ambienti isolati tra loro.
Docker Volumes
Per loro natura i Container sono effimeri cioè non mantengono i propri dati e, una volta fermati, perdono tutte le modifiche. Allora come fare per garantire la persistenza dei dati? Esempio: se avessi un database che lavora in un container come faccio a mantenere i dati salvati all’interno di esso quando fermo l’esecuzione del mio container?
Utilizzo i VOLUMI: un volume Docker è uno spazio di archiviazione gestito da Docker e utilizzato per conservare dati permanenti, separati dal ciclo di vita del container. I volumi possono essere condivisi tra più container e sono la soluzione consigliata per mantenere i dati persistenti.
Mettete MySQL in un container, create il database del vostro E-commerce, spegnete il PC. Il giorno dopo riavviate e... il database è vuoto! Perché? Perché non avete usato i volumi. È l'errore classico che vedo in laboratorio ogni anno. Sempre usare -v o volumes: in docker-compose per i database.
Dockerfile
Un file di configurazione che definisce l’ambiente del container, includendo istruzioni su come costruirlo (ad esempio, quale sistema operativo base usare, quali pacchetti installare, ecc.).
Il Dockerfile è un file di testo contenente una serie di istruzioni che permettono di costruire un’immagine Docker personalizzata in modo automatico e ripetibile.
In altre parole, è lo script che definisce come dev’essere costruita l’immagine: quali software installare, quali file copiare, quale comando eseguire all’avvio, ecc.
Le istruzioni scritte nel Dockerfile vengono interpretate dal comando docker build per generare un’immagine.
Sintassi di base:
FROM è come dire "parto da". WORKDIR è "dove mi metto a lavorare". COPY copia il vostro codice dentro. RUN esegue comandi durante la costruzione. EXPOSE è un post-it che dice "userò la porta 3000". CMD è cosa deve fare quando parte. Se sapete spiegare questo all'orale, avete già mezza prova pratica fatta.
6. Docker Hub
Un registry pubblico (o privato) dove è possibile trovare, condividere e pubblicare immagini Docker.
Sono presenti immagini di Sistemi operativi, Web Server, Database. Oltre alle immagini ufficiali sono presenti immagini di utenti che possono caricare liberamente le proprie creazioni e condividerle con la community.
È come il Play Store per sviluppatori. Cercate mysql, nginx, node, python e trovate immagini ufficiali già pronte, verificate e sicure. Non dovete più installare nulla a mano. Per il nostro E-commerce useremo mysql:8 e node:18 direttamente da lì.
7. Comandi Docker - Per le Immagini
Questa è la parte che dovete provare in laboratorio. Nessuno impara Docker leggendo, solo digitando.
Visualizzare tutte le immagini presenti:
Scaricare un’immagine da un registry:
Rimuovere un’immagine:
Rimuovere tutte le immagini non utilizzate:
Assegnare un tag ad una immagine:
Esempio pratico: Supponiamo di aver creato un’immagine localmente:
Vogliamo assegnarle il nome mario/ecommerce-backend con la tag v1.0:
Visualizzare la storia di un’immagine (layer):
Visualizzare configurazione immagine:
8. Comandi per i Container
Visualizzare i container attivi:
Visualizzare tutti i container:
Start / Stop:
Creare ed eseguire un container a partire da un'immagine:
Il file docker run è il comando con cui si lancia un’applicazione containerizzata. È quello che userete di più in assoluto.
Ragazzi, ricordatevi docker ps è il vostro migliore amico. Ogni volta che qualcosa non funziona, prima cosa: docker ps per vedere se il container è vivo. Seconda cosa: docker logs nome_container per vedere perché è morto. Con questi due comandi risolvete il 90% dei problemi in laboratorio.
9. Il file docker-compose.yml
Il file docker-compose.yml è un file di configurazione scritto in formato YAML (YAML acronimo di “YAML Ain’t Markup Language” è un linguaggio di serializzazione dei dati utilizzato per scrivere file di configurazione per il deployment dell’infrastruttura) che consente di definire, gestire e avviare più container Docker in maniera coordinata, come se fossero un’unica applicazione multi-servizio.
È uno strumento centrale per i progetti basati su architettura a microservizi, in cui ogni servizio (es. database, backend, frontend, API gateway) viene eseguito in un container separato.
Serve a:
- Definire più servizi Docker (contenitori) in un unico file.
- Specificare reti, volumi, variabili d’ambiente, porte esposte, dipendenze tra container.
- Lanciare l’intera applicazione con un solo comando:
docker-compose up
Struttura di base
Ecco un esempio semplificato:
In questo esempio:
- Sono definiti due servizi: web (che viene costruito localmente) e db (basato sull’immagine ufficiale MySQL).
- Vengono esposte le porte e impostate le variabili d’ambiente.
I principali elementi del file docker-compose.yml:
| Elemento | Descrizione |
|---|---|
| version | Specifica la versione del formato del file (es. '3.8') |
| services | Elenco dei container/servizi da avviare |
| build | Indica la directory da cui costruire l’immagine (richiede un Dockerfile) |
| image | Specifica un’immagine da scaricare dal Docker Hub |
| ports | Mappa le porte tra host e container (host:container) |
| volumes | Mappa volumi per la persistenza dei dati |
| environment | Imposta variabili d’ambiente per il container |
| depends_on | Specifica le dipendenze tra i servizi |
| networks | Definisce le reti private tra container |
| command | Sovrascrive il comando predefinito |
Per il nostro E-commerce, il file docker-compose.yml finale avrà 3 servizi: frontend (porta 3000), backend (porta 5000), db (porta 3306). Con un solo comando docker-compose up alzerete tutta l'applicazione. Senza questo file dovreste lanciare 3 comandi docker run lunghissimi, ricordandovi reti e volumi a mano. Ecco perché il compose è obbligatorio quando si passa a più di un container.
YAML è sensibilissimo agli spazi! Non usa le tabulazioni, solo 2 spazi per indentare. Se il vostro docker-compose.yml non parte e vi dice "mapping values are not allowed", al 99% avete sbagliato un'indentazione. Copiate il mio esempio e modificate solo i nomi.
Vuoi consultare il video relativo a questa lezione? Accedi cliccando il pulsante qui sotto.
🎬 Video DockerVuoi consultare la sezione video? Accedi cliccando il pulsante qui sotto.
🎬 Video Playlist📚 Per la prossima volta
Installate Docker Desktop sul vostro PC. Provate i comandi docker pull nginx e docker run -p 8080:80 nginx e poi aprite localhost:8080. Se vedete "Welcome to nginx!" avete fatto il vostro primo container. Nella prossima lezione lo colleghiamo al nostro E-commerce.
