Installare Docker su VPS Ubuntu 24.04/22.04: metodo ufficiale
- 3 ottobre 2026
- 09:00
- Di Adrien Roche
- Tutorial

Prima di iniziare: un VPS KVM, una Ubuntu supportata e un utente sudo
Docker Engine non porta con sé un proprio kernel. Ogni container condivide il kernel dell'host e si affida a namespace Linux, cgroup e netfilter: il daemon ha quindi bisogno di un VPS in cui il kernel sia tuo. È esattamente ciò che offre un VPS KVM (virtualizzazione completa). Sui piani basati su container costruiti su OpenVZ o LXC il kernel appartiene al provider e Docker o si rifiuta di partire, o funziona solo se l'host ha abilitato il nesting. Verifica prima di installare qualsiasi cosa:
systemd-detect-virt # expect: kvm
. /etc/os-release && echo "$VERSION_CODENAME" # noble (24.04) or jammy (22.04)
uname -m # x86_64 or aarch64
Docker pubblica pacchetti per Ubuntu 24.04 LTS (noble) e 22.04 LTS (jammy) a 64 bit, su x86_64 e arm64. Serve inoltre un utente con diritti sudo: le sezioni sul gruppo docker e sulla modalità rootless presuppongono un account normale e non root.
Installare Docker Engine dal repository apt ufficiale
Ci sono quattro modi diffusi per installare Docker su Ubuntu, ma uno solo è il metodo che Docker documenta e supporta sui server:
| Metodo | Pacchetto | Verdetto |
|---|---|---|
| Repository apt di Docker | docker-ce da download.docker.com | Consigliato: release aggiornate, aggiornamenti tramite apt upgrade, plugin Compose e Buildx inclusi. |
| Universe di Ubuntu | docker.io | Funziona, ma la build di Ubuntu è in ritardo rispetto a upstream e non include i plugin. |
| Snap | snap install docker | Installazione confinata con percorsi propri: fonte frequente di sorprese "permission denied". Da evitare sui server. |
| Script di convenienza | get.docker.com | Stessi pacchetti, ma passati senza revisione a una shell di root. Solo per macchine usa e getta. |
Passo 1: rimuovere i pacchetti in conflitto
Se l'immagine del VPS contiene già docker.io di Ubuntu, un vecchio docker-compose o podman-docker, rimuovili affinché le due build non si contendano /usr/bin/docker. Questo ciclo viene dalla documentazione di Docker ed è innocuo su un sistema pulito: lascia /var/lib/docker intatto:
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
sudo apt-get remove $pkg
done
Passo 2: aggiungere la chiave GPG e la sorgente apt di Docker
La chiave va in /etc/apt/keyrings/ ed è referenziata con signed-by=, che la limita a questo singolo repository invece di considerarla attendibile a livello globale tramite il deprecato apt-key. Il codename viene letto da /etc/os-release, quindi lo stesso blocco funziona su 24.04 e 22.04:
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
Un errore di firma sull'ultimo apt-get update significa quasi sempre che il file della chiave non è leggibile: riesegui la riga chmod.
Passo 3: installare l'engine e i suoi plugin
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
docker-ce è il daemon, docker-ce-cli il client, containerd.io il runtime sottostante, e i due plugin forniscono docker buildx e docker compose. Su Ubuntu lo script di post-installazione del pacchetto avvia subito docker.service e lo abilita all'avvio.
Passo 4: verificare con hello-world
sudo docker run hello-world
docker --version
sudo docker info | head -n 20
hello-world è il test definitivo: il client parla con il daemon, il daemon scarica una piccola immagine da Docker Hub, crea un container, lo esegue e ne restituisce l'output. Se vedi "Hello from Docker!", ogni livello funziona. Su un'installazione sana di 24.04 o 22.04, docker info riporta Storage Driver: overlay2 e Cgroup Version: 2.
Usare Docker senza sudo: il gruppo docker
Il daemon ascolta sul socket Unix /var/run/docker.sock, di proprietà di root:docker: i membri del gruppo docker possono quindi usare la CLI senza sudo:
sudo groupadd docker # usually exists already; harmless if it does
sudo usermod -aG docker $USER
newgrp docker # or log out and back in
docker run hello-world
Renditi conto di cosa hai appena concesso. Chiunque raggiunga quel socket può eseguire docker run -v /:/host --privileged ... e leggere o riscrivere qualsiasi file sul VPS: l'appartenenza al gruppo docker è quindi equivalente a root, senza richiesta di password e senza traccia nei log di sudo. Trattala esattamente come un accesso sudo; la nostra guida su cambiare utente e l'escalation dei privilegi su Ubuntu spiega perché questa distinzione conta su una macchina multiutente.
Il plugin Docker Compose
Il pacchetto docker-compose-plugin fornisce Compose v2 come sottocomando docker compose (con uno spazio). Il vecchio binario Python docker-compose è a fine vita e non va installato accanto ad esso. Controlla la versione, poi prova con un compose.yaml minimale:
docker compose version
mkdir -p ~/web && cd ~/web
cat > compose.yaml <<'EOF'
services:
web:
image: nginx:alpine
ports:
- "127.0.0.1:8080:80"
restart: unless-stopped
EOF
docker compose up -d
docker compose ps
curl -I http://127.0.0.1:8080
docker compose down
Due dettagli sono voluti: restart: unless-stopped fa ripartire il container dopo un riavvio, e la porta è legata a 127.0.0.1 invece che a tutte le interfacce, per i motivi spiegati nella sezione sul firewall.
Modalità rootless: un daemon che non è root
La modalità rootless esegue il daemon e i container dentro un user namespace: un'evasione dal container finisce in un account non privilegiato invece che in root. È la scelta giusta quando più persone condividono un VPS. I prerequisiti sono gli intervalli UID/GID subordinati (Ubuntu li crea per gli utenti normali in /etc/subuid e /etc/subgid), gli strumenti uidmap, una sessione D-Bus utente e gli extra rootless di Docker:
sudo apt-get install -y uidmap dbus-user-session docker-ce-rootless-extras
grep "^$USER:" /etc/subuid /etc/subgid # each should show a range of 65536 IDs
# optional: stop the system-wide daemon if you only want rootless
sudo systemctl disable --now docker.service docker.socket
dockerd-rootless-setuptool.sh install
Lo strumento di setup crea una unit systemd per utente e stampa le due variabili di cui la tua shell ha bisogno. Aggiungile a ~/.bashrc, poi fai in modo che il daemon utente parta all'avvio senza login:
export PATH=/usr/bin:$PATH
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
systemctl --user enable docker
sudo loginctl enable-linger $(whoami)
La modalità rootless ha limiti reali: le porte sotto la 1024 non possono essere pubblicate se non esegui sudo setcap cap_net_bind_service=ep $(which rootlesskit) e riavvii il daemon utente, le reti overlay non sono disponibili e i dati risiedono in ~/.local/share/docker. Su Ubuntu 24.04 AppArmor limita gli user namespace non privilegiati: i pacchetti deb includono il profilo di cui rootlesskit ha bisogno, mentre un'installazione da binario statico richiede di aggiungerlo a mano come descritto nella documentazione rootless.
Avvio al boot, storage e rotazione dei log
Due elementi distinti decidono se i tuoi container sono attivi dopo un riavvio: il daemon deve essere abilitato e ogni container deve avere una restart policy. I pacchetti Ubuntu abilitano il servizio per te; verificalo, e se gli stati delle unit ti sembrano poco familiari, il nostro riferimento su elencare i servizi con systemctl spiega ogni colonna:
systemctl is-enabled docker.service containerd.service
sudo systemctl enable docker.service containerd.service # only if the line above said disabled
I container avviati senza --restart restano spenti dopo un riavvio: usa --restart unless-stopped da riga di comando o restart: unless-stopped in Compose per tutto ciò che deve essere permanente.
Tutto ciò che Docker memorizza (layer delle immagini, filesystem dei container, volumi, log) risiede in /var/lib/docker, e su un VPS piccolo è questa la directory che riempie il disco. Tienila d'occhio con docker system df, recupera i layer orfani con docker system prune e leggi il prompt prima di aggiungere -a, che elimina anche ogni immagine non usata da un container in esecuzione. Se il VPS ha un secondo disco, punta data-root su di esso in /etc/docker/daemon.json prima di scaricare qualcosa di grande.
I log meritano un avviso specifico. Il driver predefinito json-file scrive ogni riga dello stdout del container in /var/lib/docker/containers/<id>/<id>-json.log e non esegue alcuna rotazione se non la configuri. Un container loquace può divorare l'intero disco in una settimana. Imposta limiti a livello di daemon fin dal primo giorno:
sudo tee /etc/docker/daemon.json > /dev/null <<'EOF'
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" },
"live-restore": true
}
EOF
sudo systemctl restart docker
Le opzioni di log si applicano ai container creati dopo il riavvio: ricrea una volta quelli di lunga durata. live-restore permette al daemon di riavviarsi per gli aggiornamenti senza terminare i container in esecuzione.
Docker e ufw: le porte pubblicate aggirano il firewall
È la parte che coglie impreparata la maggior parte delle persone su un VPS pubblico. Docker gestisce regole iptables proprie: quando pubblichi una porta con -p 8080:80, il daemon inserisce una regola DNAT nella catena PREROUTING della tabella nat e una regola di accettazione in FORWARD. Le regole di ufw vivono in INPUT, che il traffico inoltrato non attraversa mai. Perciò ufw deny 8080 non ha alcun effetto, e un container di database pubblicato su 0.0.0.0:5432 è raggiungibile da tutta Internet mentre ufw segnala la porta come bloccata. Cerca 0.0.0.0: nella colonna PORTS di docker ps, oppure esegui ss -tlnp; la nostra guida su come verificare le porte aperte su Linux mostra come leggere quell'output e confermare l'esposizione dall'esterno.
Due soluzioni pulite, in ordine di preferenza:
- Lega le porte pubblicate al loopback.
-p 127.0.0.1:8080:80mantiene il servizio raggiungibile solo dal VPS stesso, tipicamente dietro un reverse proxy come nginx o Caddy che esponi deliberatamente. I container che parlano solo tra loro non hanno bisogno di alcun-p. - Filtra nella catena
DOCKER-USER. Docker valuta questa catena prima delle proprie regoleFORWARDe non la riscrive mai. Poiché il DNAT è già avvenuto quando il pacchetto vi arriva, individua la porta originale con conntrack:
sudo iptables -I DOCKER-USER -i eth0 ! -s 203.0.113.10 -p tcp \
-m conntrack --ctorigdstport 8080 --ctdir ORIGINAL -j DROP
Sostituisci eth0 con la tua interfaccia pubblica e 203.0.113.10 con l'indirizzo autorizzato. Queste regole non sono persistenti: salvale con il pacchetto iptables-persistent. Impostare "iptables": false in daemon.json rompe la rete dei container in modi difficili da diagnosticare: non toccarlo.
Disinstallare Docker completamente
Prima elimina i pacchetti con purge, poi cancella le directory dei dati, che apt lascia al loro posto di proposito:
sudo apt-get purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
sudo rm -rf /var/lib/docker /var/lib/containerd
sudo rm -f /etc/apt/sources.list.d/docker.list /etc/apt/keyrings/docker.asc
sudo apt-get autoremove -y
Per un'installazione rootless, esegui prima dockerd-rootless-setuptool.sh uninstall come utente e poi cancella ~/.local/share/docker.
Tutto questo presuppone un server su cui hai root, controlli il kernel e puoi riscrivere iptables senza chiedere il permesso a nessuno. Se ti serve una macchina così, il VPS Linux KVM con accesso root completo di rdp.monster include Ubuntu 24.04 o 22.04 con CPU e RAM dedicate, banda illimitata (fair-use), nessun KYC, pagamenti in criptovaluta, a partire da $8.99/mese, e viene consegnato circa 10 secondi dopo la conferma del pagamento: potrai eseguire il test hello-world qui sopra sul tuo server subito dopo l'ordine.
Domande frequenti
Quale versione di Docker installa apt su Ubuntu e come si aggiorna?
apt-get install docker-ce installa la versione stabile più recente disponibile per il codename della tua Ubuntu, e ogni successivo sudo apt-get update && sudo apt-get upgrade ti porta avanti. Esegui docker version per vedere le versioni di client e server. Per fissare una release specifica, elenca i candidati con apt-cache madison docker-ce e installa docker-ce=<version> insieme al corrispondente docker-ce-cli, poi esegui apt-mark hold su entrambi i pacchetti.Perché ricevo "permission denied while trying to connect to the Docker daemon socket"?
root:docker, quindi un utente normale ottiene permission denied. Puoi anteporre sudo ai comandi oppure aggiungerti con sudo usermod -aG docker $USER e aprire poi una nuova sessione di login (o eseguire newgrp docker), perché le modifiche ai gruppi valgono solo per le nuove sessioni. Se l'errore persiste, controlla groups per confermare l'appartenenza, verifica che il daemon sia attivo con systemctl status docker e assicurati che DOCKER_HOST non punti a un socket rootless inesistente.Meglio installare Docker con snap o con apt su Ubuntu Server?
daemon.json e per i dati, e la cadenza degli aggiornamenti è decisa da snapd e non da te. Queste stranezze si manifestano come misteriosi permission denied e come fallimenti dei bind mount. I pacchetti apt seguono le convenzioni standard di Ubuntu, si integrano normalmente con systemd e ricevono gli aggiornamenti upstream con lo stesso apt upgrade che già esegui.Quanta RAM e quanto disco servono a un VPS con Docker?
/var/lib/docker, e 20 GB si riempiono in fretta senza docker system prune e rotazione dei log. Preferisci CPU e RAM dedicate alle quote burstable, perché le build creano picchi forti e i container non gestiscono bene lo swap.Adrien Roche, Editor infrastruttura e hosting
Ingegnere di sistemi con oltre 10 anni di esperienza nella gestione di flotte Windows Server e Linux. Adrien cura la documentazione dell'infrastruttura di rdp.monster e scrive le nostre guide su RDP, hosting VPS, amministrazione server, networking e strumenti per la privacy.




