RDP Monster

Installare Docker su VPS Ubuntu 24.04/22.04: metodo ufficiale

Installare Docker su VPS Ubuntu 24.04/22.04: metodo ufficiale

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:

MetodoPacchettoVerdetto
Repository apt di Dockerdocker-ce da download.docker.comConsigliato: release aggiornate, aggiornamenti tramite apt upgrade, plugin Compose e Buildx inclusi.
Universe di Ubuntudocker.ioFunziona, ma la build di Ubuntu è in ritardo rispetto a upstream e non include i plugin.
Snapsnap install dockerInstallazione confinata con percorsi propri: fonte frequente di sorprese "permission denied". Da evitare sui server.
Script di convenienzaget.docker.comStessi 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:

  1. Lega le porte pubblicate al loopback. -p 127.0.0.1:8080:80 mantiene 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.
  2. Filtra nella catena DOCKER-USER. Docker valuta questa catena prima delle proprie regole FORWARD e 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?

Il repository installa l'ultima versione stabile di Docker Engine e apt upgrade la mantiene aggiornata.
Con il repository apt di Docker configurato, 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"?

Il tuo utente non può leggere /var/run/docker.sock: entra nel gruppo docker o usa sudo.
Il socket del daemon appartiene a 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?

Usa apt con il repository di Docker: lo snap aggiunge stranezze di confinamento senza vantaggi su un server.
Preferisci apt dal repository ufficiale di Docker. Lo snap è strettamente confinato: non può leggere file fuori dalla tua home senza connessioni di interfaccia aggiuntive, usa percorsi diversi per 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?

L'engine in sé è leggero: dimensiona il VPS in base ai container e alle loro immagini.
A riposo Docker Engine occupa poche decine di megabyte di RAM, quindi il budget reale dipende dal tuo carico di lavoro. Una singola piccola web app con database gira comodamente in 2 GB; stack più pesanti o più progetti richiedono 4 GB o più. Il disco conta più di quanto si pensi: immagini, cache di build e log finiscono tutti in /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.

Iscriviti al nostro programma rivenditori

I tuoi dati

Nome completo(Obbligatorio)
Inserisci il tuo indirizzo email, devi avere un account su manager.rdp.monster !

La tua azienda

Inserisci l'indirizzo del tuo sito web, se ne hai uno
Spiega brevemente come venderai i servizi ai tuoi clienti. Per esempio, parlandone con le persone sui forum.

Usiamo i cookie !

Utilizziamo i cookie per migliorare la tua esperienza di navigazione, proporre annunci o contenuti personalizzati e analizzare il nostro traffico. Cliccando su «Accetta», acconsenti al nostro uso dei cookie.