Docker è una piattaforma per creare, distribuire ed eseguire applicazioni dentro container. Il vantaggio principale è semplice da capire: puoi impacchettare applicazione, runtime e dipendenze in un ambiente riproducibile, riducendo le differenze tra il computer dello sviluppatore, il server di test e l’ambiente di produzione.
Il punto, però, è distinguere bene i pezzi. La piattaforma non coincide con il container stesso, un’immagine non è un container in pausa e Compose non sostituisce Kubernetes. Quando queste differenze sono chiare, anche i comandi iniziano ad avere molto più senso.
In questa guida vedremo il percorso completo Dockerfile → immagine → registry → container, come gestire dati e rete, quando la containerizzazione è realmente utile e quali limiti bisogna considerare.
Cos’è Docker e quale problema risolve
Senza container, eseguire la stessa applicazione su ambienti differenti può significare ricostruire manualmente dipendenze, versioni del runtime, librerie, configurazioni e servizi collegati.
È il classico problema del “sul mio computer funziona”.
La containerizzazione affronta questo problema creando un processo più standardizzato per distribuire il software. L’applicazione viene preparata in un’immagine insieme a ciò che le serve per funzionare; da quell’immagine possono poi essere create una o più istanze isolate.
La documentazione ufficiale descrive un’architettura client-server nella quale il client comunica con il daemon responsabile delle operazioni di build, esecuzione e gestione dei container.
Questa standardizzazione non significa che l’infrastruttura scompaia. Viene astratta una parte dell’ambiente applicativo, mentre sistema operativo, CPU, memoria, storage e rete continuano a esistere sotto il workload.
Docker, Docker Engine e Docker Desktop non sono la stessa cosa
Nel linguaggio comune diciamo semplicemente “Docker”, ma dietro questo nome convivono componenti differenti.
Docker Engine è la tecnologia open source che esegue e gestisce immagini, container, reti e volumi. Comprende il daemon dockerd, le API e la CLI docker.
Docker Desktop è invece un’applicazione pensata soprattutto per l’ambiente di sviluppo. Riunisce Engine e altri strumenti dell’ecosistema in un’esperienza più semplice da configurare e utilizzare su Windows, macOS e Linux.
Docker Hub è un registry: un servizio nel quale le immagini possono essere pubblicate, distribuite e recuperate.
Docker Compose serve a descrivere e gestire applicazioni composte da più container.
Quindi non sono sinonimi:
Docker → ecosistema
Docker Engine → motore di containerizzazione
Docker Desktop → ambiente desktop e tooling
Docker Hub → registry di immagini
Docker Compose → definizione ed esecuzione di applicazioni multi-container
È una distinzione apparentemente piccola, ma evita molta confusione quando si passa dalla teoria ai comandi.
Cos’è la containerizzazione
La containerizzazione consiste nel confezionare un’applicazione con le sue dipendenze in un’unità eseguibile isolata dal resto del sistema.
Un container dispone del proprio filesystem, processi, configurazione di rete e variabili di ambiente, ma normalmente non porta con sé un intero sistema operativo guest come accade con una macchina virtuale.
Nel caso dei container Linux, più istanze possono condividere il kernel dell’host mantenendo separati i rispettivi ambienti di esecuzione.
Questo riduce l’overhead, ma porta anche a una conseguenza importante: container e macchine virtuali non offrono lo stesso modello di isolamento. È uno dei motivi per cui il confronto “Docker sostituisce le VM” è troppo semplicistico.
Dall’applicazione al container: come funziona il processo
Il modo più utile per capire il meccanismo è seguirne il flusso.
Supponiamo di avere un’applicazione web.
Prima descrivi come costruire il suo ambiente. Da quelle istruzioni viene prodotta un’immagine. L’immagine può essere conservata localmente oppure pubblicata in un registry. Quando la esegui, Engine crea un container.
Il modello è questo:
codice → Dockerfile → docker build → image → registry → docker run → container
Non tutti i progetti devono compiere ogni passaggio manualmente, ma questa sequenza chiarisce cosa succede dietro molti workflow basati sui container.

Dockerfile: le istruzioni per costruire l’immagine
Un Dockerfile è un file di testo contenente le istruzioni necessarie a costruire un’immagine.
Può specificare, per esempio:
- l’immagine di partenza;
- i file da copiare;
- i pacchetti da installare;
- la directory di lavoro;
- il comando da avviare;
- variabili e configurazioni necessarie all’applicazione.
Un Dockerfile minimale per pubblicare file statici tramite Nginx potrebbe essere:
FROM nginx:alpine COPY ./site /usr/share/nginx/html
La prima istruzione usa un’immagine Nginx come base. La seconda copia i file del progetto nella directory servita dal web server.
Ogni istruzione contribuisce alla costruzione dell’immagine. I layer consentono di riutilizzare parti già disponibili, così una modifica non obbliga necessariamente a ricostruire da zero tutto ciò che non è cambiato.
Docker Build: come nasce un’immagine
Salvato il Dockerfile, puoi costruire l’immagine:
docker build -t mio-sito .
docker build avvia il processo di build.
-t mio-sito assegna un nome, o tag, all’immagine.
Il punto finale . indica il contesto di build corrente.
Il risultato non è ancora il sito “in esecuzione”. Hai costruito l’immagine da cui potranno essere creati i container.
Questa separazione tra build ed esecuzione è fondamentale. Una stessa immagine può generare più istanze senza dover ricostruire ogni volta l’applicazione.
docker run: quando l’immagine diventa un container
Per avviare l’immagine:
docker run --name mio-sito -d -p 8080:80 mio-sito
Qui succedono diverse cose.
--name mio-sito assegna un nome leggibile al container.
-d lo esegue in background.
-p 8080:80 pubblica la porta 80 del container sulla porta 8080 dell’host.
L’ultimo mio-sito indica l’immagine da utilizzare.
A questo punto l’immagine è il modello; il container è una sua istanza in esecuzione.
Dalla stessa immagine puoi avviare più istanze e assegnare loro configurazioni, porte o volumi differenti.
Registry e Docker Hub: dove vengono distribuite le immagini
Un registry conserva e distribuisce immagini container.
Quando esegui:
docker run nginx
e l’immagine nginx non è già disponibile localmente, il motore può recuperarla dal registry configurato.
Docker Hub è il registry più noto dell’ecosistema, ma non è l’unica possibilità. Le organizzazioni possono utilizzare registry privati o servizi analoghi messi a disposizione dalle piattaforme cloud.
Il passaggio attraverso un registry consente di separare anche il processo di build dal deployment:
build → push → pull → run
Questo è uno dei meccanismi che rende le immagini container particolarmente utili nelle pipeline CI/CD e nei deployment automatizzati.
Immagine e container: qual è la differenza
Confondere immagine e container è probabilmente l’errore concettuale più comune quando si inizia.
Un’immagine è il pacchetto a partire dal quale viene creato un container.
Un container è un’istanza di quell’immagine con un proprio stato di esecuzione.
Possiamo riassumerli così:
| Caratteristica | Immagine | Container |
|---|---|---|
| Funzione | Modello per creare ambienti | Istanza eseguibile |
| Stato | Non è un processo in esecuzione | Può essere avviato, fermato o eliminato |
| Layer | Layer dell’immagine | Layer dell’immagine + layer scrivibile |
| Riutilizzo | Può generare molti container | Rappresenta una singola istanza |
| Distribuzione | Può essere pubblicata in un registry | Normalmente viene ricreato dall’immagine |
Perché un’immagine è composta da layer
Le immagini vengono costruite per layer.
Se un Dockerfile installa una dipendenza, copia un gruppo di file e aggiunge successivamente altri contenuti, queste trasformazioni possono essere organizzate in livelli distinti.
L’architettura a layer permette di riutilizzare parti già disponibili e rende più efficiente la gestione delle build.
Non significa però che convenga creare Dockerfile enormi o accumulare dipendenze senza criterio. Immagini inutilmente pesanti richiedono più spazio, più traffico durante il trasferimento e una superficie software più ampia da mantenere e aggiornare.
Cosa cambia quando parte un container
Quando viene creata un’istanza da un’immagine, sopra i layer di base viene aggiunto uno strato scrivibile.
Il processo in esecuzione può quindi creare o modificare file nel proprio filesystem.
Il problema arriva quando quei dati devono sopravvivere all’istanza.
Un database, per esempio, non dovrebbe dipendere soltanto dal layer scrivibile di uno specifico container. Se l’istanza viene sostituita, i dati devono poter essere conservati indipendentemente dalla sua vita operativa.
Ed è qui che entrano in gioco i volumi.
Cosa succede ai dati quando il container viene eliminato
Un container dovrebbe essere considerato sostituibile.
Se i dati importanti esistono soltanto nel filesystem scrivibile di quell’istanza, eliminarla significa perdere quello stato.
Per i dati che devono persistere, sono disponibili i volumi, archivi persistenti gestiti dal motore e indipendenti dal ciclo di vita di uno specifico container.
Questo porta a una regola pratica utile:
container sostituibile, dati persistenti fuori dal ciclo di vita del container.
Docker Engine: client, daemon e oggetti Docker
Docker Engine usa un’architettura client-server.
Quando digiti:
docker ps
la CLI non sta gestendo direttamente i container. Invia una richiesta al daemon attraverso le API.
È il daemon a gestire gli oggetti del motore.
Cosa fa dockerd
dockerd è il processo persistente che svolge gran parte del lavoro operativo.
Fra le sue responsabilità rientrano:
- immagini;
- container;
- reti;
- volumi;
- operazioni di build;
- gestione del ciclo di vita delle istanze.
Questa architettura permette anche a strumenti diversi dalla CLI di interagire con Engine tramite API.
CLI e Docker API
La CLI docker è l’interfaccia che normalmente utilizzi dal terminale.
Un comando come:
docker stop web-demo
viene tradotto in un’operazione verso il daemon.
Le API rendono possibile integrare il motore anche in script, strumenti di sviluppo e sistemi di automazione.
Questa separazione è importante anche dal punto di vista della sicurezza: chi può controllare il daemon dispone di capacità molto ampie sull’ambiente che quel daemon gestisce.
Container, immagini, reti e volumi
Questi quattro oggetti formano una buona base mentale:
immagine → descrive ciò che verrà eseguito;
container → istanza eseguibile;
rete → permette alle istanze di comunicare;
volume → conserva dati indipendentemente dalla singola istanza.
L’ecosistema comprende molto altro, ma se questi quattro concetti sono chiari puoi già comprendere gran parte dei workflow quotidiani.
Docker Compose e applicazioni con più container
Un’applicazione reale raramente è composta da un unico processo isolato.
Potresti avere:
applicazione web + database + cache
Avviare e configurare manualmente ogni servizio diventa rapidamente scomodo.
Docker Compose permette di descrivere servizi, reti e volumi in un file YAML e gestire l’applicazione come un insieme coordinato.
Dockerfile e Compose file fanno lavori diversi
Dockerfile e Compose non sono alternativi.
Il Dockerfile descrive principalmente come costruire un’immagine.
Il file Compose descrive invece come devono essere eseguiti e collegati i servizi che compongono l’applicazione.
Per esempio:
Dockerfile → costruisce l'immagine dell'app
compose.yaml → esegue app + database + altri servizi
Questa distinzione evita di trasformare il Compose file in un contenitore indiscriminato di logica che dovrebbe appartenere al processo di build.
Perché oggi si usa docker compose
La sintassi corrente del comando è:
docker compose up -d
La vecchia installazione standalone di Compose viene mantenuta per retrocompatibilità ed è classificata dalla documentazione ufficiale sull’installazione di Compose come legacy.
Questo è uno dei dettagli da controllare con attenzione quando leggi tutorial datati: trovare docker-compose non significa automaticamente che tutto il contenuto sia inutilizzabile, ma è un segnale che installazione, sintassi ed esempi meritano una verifica.
Quando Compose basta e quando serve un orchestratore
Compose è molto efficace quando devi gestire localmente o in scenari relativamente semplici più servizi correlati.
La situazione cambia quando devi coordinare workload su più nodi, gestire replica, scheduling, rollout, self-healing e altre esigenze di orchestrazione distribuita.
In quel contesto entrano strumenti come Kubernetes.
Il salto non va però automatizzato.
Avere tre container non significa aver bisogno di Kubernetes.
L’orchestrazione distribuita introduce una propria complessità operativa e deve risolvere un problema reale, non essere aggiunta soltanto perché l’applicazione usa container.
Volumi, porte e reti: come gestire dati e comunicazioni
Un container completamente isolato servirebbe a poco.
Le applicazioni devono ricevere traffico, comunicare con altri servizi e, spesso, conservare dati.
Per storage e networking sono quindi disponibili primitive dedicate.
Volumi e bind mount
Un volume è gestito dal motore e vive indipendentemente dal ciclo di vita di uno specifico container.
Un bind mount collega invece un file o una directory del filesystem host a un percorso interno all’istanza.
La differenza è pratica.
Per dati applicativi persistenti, soprattutto quando non serve lavorare direttamente sui file dall’host, i volumi offrono un modello più separato dal filesystem della macchina.
I bind mount sono invece molto utili durante lo sviluppo quando, per esempio, vuoi modificare file sorgenti sull’host e renderli immediatamente disponibili dentro il container.
Creano però anche un legame più stretto con struttura e permessi della macchina host.
Mapping delle porte
Un’applicazione dentro un container può ascoltare su una porta senza essere automaticamente raggiungibile attraverso la stessa porta dell’host.
Con:
docker run -p 8080:80 nginx
viene creato il collegamento:
porta 8080 dell'host → porta 80 del container
Se apri il servizio dall’host utilizzerai quindi la porta 8080.
Questa distinzione aiuta anche a capire perché più istanze possono eseguire lo stesso servizio interno senza necessariamente entrare in conflitto: a ciascuna puoi associare una porta host differente oppure mantenerla raggiungibile soltanto attraverso una rete interna.
Come comunicano più container
I container possono comunicare attraverso reti dedicate.
In un’applicazione Compose, per esempio, il servizio web può raggiungere il database utilizzando il nome assegnato al servizio sulla rete dell’applicazione.
Questo evita di codificare IP temporanei nella configurazione.
È un modello molto più robusto:
nome logico del servizio → risoluzione sulla rete
piuttosto che:
IP corrente del container → configurazione hard-coded
Primo esempio pratico: avviare un container
Per capire il funzionamento non serve iniziare installando un cluster o costruendo un’applicazione complessa.
Bastano pochi comandi.
Docker Desktop o Docker Engine?
Su un computer personale, Desktop offre normalmente il percorso più semplice per iniziare perché riunisce Engine, CLI e Compose in un ambiente configurato.
Su un server Linux è comune installare direttamente Engine quando non serve un’interfaccia desktop.
Se stai scegliendo il percorso di installazione, conviene distinguere il contesto:
workstation di sviluppo → Desktop può semplificare il setup
server Linux → Engine può essere sufficiente
L’importante è non confondere l’interfaccia Desktop con la tecnologia di containerizzazione sottostante.
Eseguire hello-world
Dopo aver configurato l’ambiente puoi controllarne il funzionamento con:
docker run hello-world
Se l’immagine non è disponibile localmente, viene recuperata dal registry e utilizzata per creare un container.
Il test verifica, in forma molto semplice, il percorso:
CLI → daemon → image → container
Avviare Nginx in un container
Un esempio più concreto:
docker run --name web-demo -d -p 8080:80 nginx
Ora hai un server Nginx eseguito in un container.
Puoi vedere le istanze attive con:
docker ps
e consultare i log con:
docker logs web-demo
Per fermarlo:
docker stop web-demo
e, una volta fermato, eliminarlo:
docker rm web-demo
Hai appena attraversato il ciclo essenziale di un container senza installare Nginx direttamente nel sistema host.
Ed è proprio questo uno dei vantaggi pratici della containerizzazione: puoi creare un ambiente, usarlo e rimuoverlo mantenendo il sistema host più separato dal software eseguito.
Quando la containerizzazione porta un vantaggio reale
I container non sono utili perché “sono moderni”. Sono utili quando risolvono problemi concreti di ambiente, distribuzione e gestione del software.
Ambienti di sviluppo riproducibili
Immagina un progetto che richiede una determinata versione di un runtime, un database e un servizio cache.
Senza container, ogni sviluppatore deve ricostruire quell’ambiente sulla propria macchina.
Con una configurazione containerizzata puoi descriverne una parte consistente come codice e distribuire un ambiente più riproducibile.
Questo non elimina tutte le differenze tra sistemi, ma riduce il numero di dipendenze installate e configurate manualmente sull’host.
CI/CD e testing
Le immagini container sono particolarmente comode nelle pipeline automatizzate.
Puoi costruire un’immagine, eseguire test su quella build e distribuire lo stesso artefatto negli ambienti successivi.
Il vantaggio non è soltanto la velocità: riduce anche il rischio che test e produzione eseguano pacchetti costruiti in modo differente.
Applicazioni web e microservizi
Un’applicazione può essere suddivisa in più componenti e distribuire ciascun servizio come container.
La containerizzazione non obbliga però a progettare microservizi.
Un backend monolitico ben progettato può essere containerizzato esattamente come un insieme di servizi separati.
Questo è un punto importante perché containerizzazione e architettura applicativa rispondono a domande diverse:
i container riguardano come impacchetti ed esegui il workload.
I microservizi riguardano come suddividi responsabilità e componenti dell’applicazione.
Passare ai microservizi aggiunge rete, osservabilità, deployment multipli e gestione della consistenza; introdurre container non elimina automaticamente quella complessità.
Cloud e deployment
I container vengono usati spesso nel cloud computing, ma le due cose non coincidono.
Puoi eseguire workload containerizzati su:
- un computer locale;
- un server fisico;
- una macchina virtuale;
- un’istanza cloud;
- una piattaforma che accetta immagini container;
- un cluster orchestrato.
Anche in questo scenario, sotto l’applicazione continuano a esistere compute, memoria, rete e storage.
Se gestisci direttamente queste risorse sei ancora vicino al modello IaaS; se una piattaforma si occupa di gran parte dell’operatività e tu consegni soprattutto codice o immagini, puoi avvicinarti a un modello PaaS.
Servizi locali, database e tool self-hosted
I container sono comodi anche per avviare rapidamente software di supporto.
Puoi usarli per database, code, cache, tool di sviluppo o applicazioni self-hosted senza installare direttamente ogni componente nel sistema operativo dell’host.
La comodità non deve però far dimenticare persistenza, backup e sicurezza. Avviare un database dentro un container è facile; gestirne correttamente dati, aggiornamenti e recovery resta un problema operativo reale.
Docker vs macchina virtuale: differenze e quando scegliere l’una o l’altra
Container e macchine virtuali isolano workload in modi differenti.
Una macchina virtuale normalmente esegue un sistema operativo guest sopra un hypervisor. Un container Linux condivide invece il kernel dell’ambiente Linux che lo ospita, mantenendo separati processi e risorse attraverso i meccanismi di isolamento del sistema operativo.
| Aspetto | Docker container | Macchina virtuale |
|---|---|---|
| Sistema operativo guest | Non richiede un OS guest completo per container | Ogni VM può avere un proprio OS guest |
| Kernel | Condiviso con l’ambiente Linux host | Il guest dispone del proprio kernel |
| Avvio | Generalmente rapido | Richiede l’avvio del sistema guest |
| Overhead | Più contenuto | Generalmente maggiore |
| Packaging applicativo | Punto centrale del modello | Non è lo scopo principale |
| Isolamento | A livello di sistema operativo | Confine di virtualizzazione più forte |
| Portabilità | Utile per workload containerizzati compatibili | Utile per ambienti OS completi |
| Caso tipico | Applicazioni e servizi | Sistemi completi e workload che richiedono un OS separato |
Dire quindi che Docker è “meglio delle VM” non è una conclusione utile.
Un’architettura molto comune esegue container dentro macchine virtuali.
La VM separa e virtualizza l’infrastruttura. Il container standardizza l’ambiente applicativo all’interno di quella infrastruttura.
Sono due livelli che possono convivere perfettamente.
Docker, Kubernetes e CaaS: cosa cambia
Un altro errore frequente è trattare Docker e Kubernetes come concorrenti diretti.
Non risolvono lo stesso problema.
Docker costruisce ed esegue container
Engine e gli strumenti dell’ecosistema permettono di costruire immagini, distribuirle e avviare container.
Su una singola macchina puoi già fare moltissimo con Engine e Compose.
Il problema cambia quando devi gestire numerosi workload distribuiti su più macchine.
Kubernetes orchestra workload containerizzati
Kubernetes gestisce workload containerizzati attraverso risorse come i Pod e utilizza container runtime compatibili per eseguire i container sui nodi.
La sua responsabilità si sposta verso scheduling, replica, rollout, disponibilità e gestione del cluster.
Quindi:
Docker → build e workflow dei container
Kubernetes → orchestrazione di workload containerizzati
Tra i due esiste una relazione, ma Kubernetes non richiede che Docker Engine sia il runtime dei nodi: supporta runtime compatibili con la Container Runtime Interface, tra cui containerd e CRI-O.
CaaS aggiunge un livello di servizio gestito
Con Containers as a Service il provider astrae parte dell’infrastruttura necessaria a eseguire e gestire workload containerizzati.
Il grado di astrazione varia molto da servizio a servizio.
Una piattaforma può gestire il control plane Kubernetes, il provisioning dei nodi o perfino gran parte del runtime sottostante lasciandoti soprattutto la responsabilità dell’immagine e della configurazione del workload.
Per questo non conviene ragionare soltanto per etichette. La domanda utile è:
quali componenti devo ancora amministrare io?
È lo stesso principio che separa IaaS e PaaS: l’etichetta conta meno della divisione concreta delle responsabilità.
Vantaggi e limiti di Docker
La containerizzazione offre vantaggi importanti, ma una valutazione utile deve includere anche il prezzo operativo di ogni vantaggio.
| Vantaggio | Perché è utile | Trade-off |
|---|---|---|
| Ambienti riproducibili | Riduce differenze di setup | Richiede immagini e configurazione mantenute bene |
| Portabilità | Il workload viaggia come immagine | Non elimina differenze di architettura, kernel e infrastruttura |
| Isolamento | Separa processi e dipendenze | Non equivale automaticamente all’isolamento di una VM |
| Avvio rapido | Facilita ambienti temporanei e scaling | Avviare container velocemente non rende scalabile l’applicazione |
| Automazione | Si integra bene con CI/CD | Aumenta la superficie di tooling |
| Immagini versionabili | Migliora ripetibilità del deployment | Registry e lifecycle delle immagini vanno gestiti |
| Composizione dei servizi | Compose semplifica stack locali | Gli stack distribuiti possono richiedere orchestrazione più complessa |
Il limite più importante da ricordare è questo:
la containerizzazione standardizza parte della complessità; non la cancella.
Se un’applicazione dipende da rete, storage persistente, secret, monitoring e backup, quei problemi continueranno a esistere anche dopo averla containerizzata.
Quando Docker può essere complessità inutile
Non ogni progetto deve essere containerizzato.
Per un piccolo script eseguito su una sola macchina, un sito molto semplice o un ambiente completamente gestito nel quale non controlli il runtime, introdurre Dockerfile, immagini, registry e procedure può aggiungere lavoro senza produrre un beneficio proporzionato.
Lo prenderei in considerazione soprattutto quando almeno uno di questi problemi è reale:
- devi riprodurre lo stesso ambiente in più contesti;
- hai dipendenze difficili da standardizzare;
- vuoi distribuire un artefatto containerizzato;
- devi isolare più servizi;
- la tua pipeline o piattaforma di deployment lavora naturalmente con immagini container.
Se nessuno di questi problemi esiste, partire senza container può essere una scelta perfettamente razionale.
Sicurezza Docker: cosa controllare davvero
“Il container è isolato” non significa “il container è sicuro”.
La sicurezza dipende dall’immagine, dalla configurazione, dai privilegi concessi, dal daemon, dalla rete e dal software eseguito.
Usa immagini affidabili e mantienile aggiornate
Un’immagine contiene librerie e pacchetti che possono avere vulnerabilità esattamente come qualsiasi altro software.
Meglio sapere:
- da dove proviene;
- quale tag o versione stai distribuendo;
- quando è stata aggiornata;
- quali dipendenze include;
- se il processo di build è riproducibile.
Usare sempre latest senza una strategia di versioning può rendere più difficile sapere esattamente cosa hai distribuito.
Evita privilegi inutili
Un processo nel container dovrebbe ricevere soltanto i privilegi che gli servono.
Engine supporta anche una modalità rootless, nella quale daemon e container possono funzionare come utente non root per ridurre alcuni rischi legati al runtime.
Non è una soluzione universale a ogni problema di sicurezza, ma mostra bene il principio: ridurre i privilegi disponibili.
Non inserire secret nell’immagine
Password, token e chiavi non dovrebbero essere incorporati nel Dockerfile o nell’immagine.
Questo vale in particolare durante la build.
La documentazione sui build secret avverte che build argument e variabili d’ambiente non sono il meccanismo adatto per trasferire secret durante il processo perché possono persistere nell’immagine; per questi casi sono disponibili secret mount e SSH mount.
Proteggi il Docker daemon e il socket
L’accesso al daemon è sensibile.
Non trattare /var/run/docker.sock come un normale file da montare indiscriminatamente nei container.
Un’applicazione che può controllare il daemon può ottenere capacità molto più ampie rispetto a quelle di un normale processo applicativo.
Prima di esporlo via rete o concedere accesso al socket, devi quindi capire esattamente quali privilegi stai trasferendo.
Considera anche la supply chain
La sicurezza non inizia quando il container parte.
Comprende:
base image → dipendenze → build → registry → deployment → runtime
Un’immagine proveniente da una fonte dubbia o contenente dipendenze vulnerabili trasporta quel rischio negli ambienti nei quali viene eseguita.
Per questo la sicurezza dei container è anche sicurezza della software supply chain.
Docker è gratis? Engine, Desktop e licenze
Qui è importante evitare una risposta troppo generica.
Docker Engine è una tecnologia open source.
Docker Desktop è invece distribuito secondo condizioni proprie. Il suo utilizzo è gratuito negli scenari coperti dai termini del piano gratuito, mentre per alcuni usi professionali e organizzativi è richiesta una sottoscrizione a pagamento.
Le condizioni possono cambiare, quindi per una decisione aziendale conviene verificare direttamente i piani Docker.
La distinzione pratica è:
open source Docker Engine ≠ qualunque utilizzo di Docker Desktop automaticamente gratuito.
Non baserei quindi una scelta aziendale su vecchi articoli che dicono semplicemente “Docker è gratis” senza distinguere prodotto e licenza.
Alternative a Docker: quando considerare altre tecnologie
“Alternativa a Docker” può significare cose molto diverse, perché l’ecosistema copre più livelli del workflow.
Podman e containerd, per esempio, non sono intercambiabili fra loro.
Podman
Podman è un container engine daemonless con una CLI deliberatamente simile a quella Docker e permette di eseguire molti comandi come utente normale.
Può essere interessante quando vuoi un workflow container orientato agli standard OCI senza adottare l’architettura con daemon persistente tipica di Engine.
Non significa però che passare da una piattaforma all’altra sia sempre un miglioramento: tooling, compatibilità del progetto, ambiente del team e deployment finale devono giustificare il cambio.
containerd
containerd è un container runtime orientato alla gestione del ciclo di vita dei container e progettato soprattutto per essere integrato in sistemi più ampi, non come esperienza completa destinata direttamente allo sviluppatore finale.
Per questo dire “containerd è un’alternativa a Docker” senza spiegazioni è fuorviante.
L’ecosistema Docker offre un’esperienza di sviluppo, build e distribuzione molto più ampia; containerd occupa un livello più basso dello stack.
La domanda corretta non è quindi soltanto “quale tool sostituisce Docker?”, ma:
quale parte del workflow sto cercando di sostituire?
Domande frequenti su Docker
Docker funziona solo su Linux?
I container sono strettamente legati alle funzionalità del sistema operativo. Docker è disponibile anche su Windows e macOS, ma i container Linux richiedono un ambiente con kernel Linux. Desktop gestisce questa complessità attraverso la propria architettura di virtualizzazione.
Quindi usare container Linux su Windows o macOS non significa che stiano improvvisamente utilizzando il kernel nativo di quei sistemi.
Docker può sostituire una macchina virtuale?
Non in senso generale.
Un container può sostituire una VM in alcuni workflow nei quali la macchina virtuale veniva utilizzata semplicemente per isolare un’applicazione e le sue dipendenze.
Se invece hai bisogno di un sistema operativo guest indipendente o di un confine di virtualizzazione diverso, una VM continua ad avere una funzione propria.
Molte infrastrutture usano entrambi: VM per l’infrastruttura, container per i workload applicativi.
Docker e Kubernetes sono la stessa cosa?
No.
Docker offre strumenti per costruire immagini ed eseguire container.
Kubernetes è una piattaforma di orchestrazione che gestisce workload containerizzati distribuiti su un cluster.
Puoi imparare e utilizzare i container senza Kubernetes. Per molti ambienti di sviluppo e applicazioni semplici, Engine e Compose sono già sufficienti.
Si può usare Docker con WordPress?
Sì. WordPress, web server e database possono essere eseguiti come servizi containerizzati, spesso coordinati tramite Compose.
È particolarmente utile per ambienti di sviluppo riproducibili, laboratori e test.
Per un sito WordPress in produzione, però, questa architettura non è automaticamente migliore di un hosting WordPress gestito, una VM o altre soluzioni. Bisogna considerare backup, persistenza, aggiornamenti, networking, osservabilità e competenze operative.
Conclusione
Docker vale la pena quando ti serve controllare e riprodurre l’ambiente in cui gira un’applicazione, non semplicemente perché la containerizzazione è diffusa.
Il modello da ricordare è relativamente semplice:
Dockerfile → image → registry → container
A questo si aggiungono volumi quando i dati devono persistere, reti quando più servizi devono comunicare e Compose quando vuoi descrivere uno stack multi-container.
Da lì puoi arrivare a infrastrutture molto più complesse, Kubernetes compreso. Ma non è obbligatorio.
Per un progetto piccolo, un solo server e un ambiente già gestito in modo affidabile, introdurre un layer container può essere più complessità da mantenere. Quando invece devi rendere sviluppo, test e deployment riproducibili, distribuire applicazioni come immagini o coordinare più servizi isolati, il vantaggio diventa concreto.
La scelta corretta non è quindi “usare Docker sempre”.
È sapere quale problema vuoi risolvere prima di containerizzare l’applicazione.