Cos'è Docker e perché gli sviluppatori dovrebbero impararlo?
Un'analisi pratica di Docker per sviluppatori: container vs VM, comandi fondamentali, Dockerfile e come iniziare a usarlo in progetti reali.
Docker continua a comparire negli annunci di lavoro e nelle guide di configurazione, e se non hai mai toccato i container può sembrare un muro che devi scavalcare prima di poter scrivere codice vero. Non è complicato una volta che superi la terminologia.
Cos'è davvero un container
Un container racchiude la tua applicazione con tutto ciò che le serve per funzionare: il codice, il runtime, le librerie di sistema e i file di configurazione. Non è una macchina virtuale. Una VM virtualizza un intero sistema operativo, kernel incluso, il che significa che avviarla può richiedere un minuto e consumare alcuni gigabyte di RAM. Un container condivide il kernel della macchina host e isola solo il processo, quindi si avvia in meno di un secondo e di solito usa decine di megabyte invece di gigabyte.
Questa differenza è il motivo per cui Docker ha conquistato così rapidamente lo sviluppo locale e le pipeline CI. Puoi avviare un database Postgres, una cache Redis e il tuo app server su un laptop senza installarli direttamente sul tuo OS.
I pezzi fondamentali che devi conoscere
Ci sono quattro termini che coprono la maggior parte di ciò con cui avrai a che fare quotidianamente:
- Image: un template di sola lettura costruito da un Dockerfile. Pensalo come una foto di un filesystem più i metadati su come eseguirlo.
- Container: un'istanza in esecuzione di un'image. Puoi avviare, fermare ed eliminare container senza toccare l'image da cui provengono.
- Dockerfile: un file di testo con istruzioni per costruire un'image, riga per riga.
- Registry: dove le image sono archiviate e scaricate, più comunemente Docker Hub.
Un Dockerfile minimo per un'app Node.js si presenta così:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Costruiscilo con docker build -t my-app . e eseguilo con docker run -p 3000:3000 my-app. Il flag -p mappa una porta sulla tua macchina a una porta dentro il container, che è il modo in cui raggiungi effettivamente l'app dal tuo browser.
Comandi che userai costantemente
Una manciata di comandi copre la maggior parte del lavoro quotidiano:
docker ps— elenca i container in esecuzionedocker ps -a— elenca tutti i container, inclusi quelli fermidocker images— elenca le image sulla tua macchinadocker logs <container>— controlla l'output di un container in esecuzione o bloccatodocker exec -it <container> sh— apri una shell dentro un container in esecuzionedocker rm/docker rmi— pulisci container e image di cui non hai più bisogno
Quest'ultima coppia è più importante di quanto la gente si aspetti. Docker lascerà volentieri che lo spazio su disco scompaia in vecchie image e container fermi. Eseguire docker system prune ogni tanto recupera una quantità sorprendente di spazio.
Perché docker-compose cambia il flusso di lavoro
La maggior parte dei progetti reali ha bisogno di più di un container: un app server, un database, magari una cache. Scrivere comandi docker run per ciascuno diventa noioso velocemente. docker-compose.yml ti permette di definire l'intero stack in un file:
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: devpassword
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Esegui docker compose up e entrambi i servizi si avviano insieme, collegati in rete in modo che web possa raggiungere db per nome di servizio. Questo è il setup che vedrai nel README di quasi tutti i repo open-source, e capirlo significa che puoi clonare un progetto e averlo in esecuzione in pochi minuti invece di installare manualmente Postgres, Redis e tutto il resto di cui l'app ha bisogno.
Dove la gente inciampa all'inizio
I volume confondono quasi tutti all'inizio. Senza un volume, tutto ciò che viene scritto dentro un container scompare quando il container viene rimosso, il che è un problema per i database. La sezione volumes nel file compose sopra mappa un volume nominato a un percorso dentro il container in modo che i dati sopravvivono ai riavvii.
Un altro errore comune è copiare node_modules o .git nell'image perché non esiste un file .dockerignore. Aggiungine uno proprio come un .gitignore:
node_modules
.git
.env
Qesto mantiene le build più veloci e le image più piccole, il che importa quando inizi a spingere le image a un registry o a distribuire a Kubernetes.
Dove andare dopo le basi
Una volta che costruire ed eseguire container sembra normale, le competenze successivamente utili sono i multi-stage build per image di produzione più piccole, capire le modalità di networking di Docker e leggere un output docker inspect quando qualcosa non si connette nel modo giusto. Niente di tutto ciò è difficile, è solo non familiare la prima volta.
Per ulteriori informazioni su containerizzare applicazioni reali e connetterle a pipeline di distribuzione nel cloud, consulta i segmenti DevOps e Cloud su Korra Studio.
Scritto con assistenza AI, revisionato e pubblicato da Michal Pilch (CISSP), Korra Studio.
Questa è una nota dalla knowledge base di Korra Studio — la piattaforma abbina ogni argomento a mentoring 1-to-1.
Inizia gratisarrow_forward