Cheat sheet Docker Compose per server reali
Comandi Docker Compose V2 per gestire ogni giorno lifecycle, modifiche, log, shell, reti, volumi e pulizia sicura, con errori e differenze da evitare.
I comandi Compose che userai davvero
Docker Compose include più di quaranta sottocomandi. Nelle attività quotidiane su un server se ne usano circa una dozzina. Questa pagina li raggruppa in base all'operazione da eseguire, spiega in modo semplice lo scopo di ciascuno e rimanda agli approfondimenti per i comandi che nascondono insidie.
Tutto ciò che segue usa Compose V2: docker compose con uno spazio, non il vecchio script docker-compose. V2 è un plugin scritto in Go che viene installato insieme a Docker Engine. V1 non è più incluso nei pacchetti attuali, quindi trovare docker-compose: command not found su un'installazione Ubuntu appena configurata a luglio 2026 è un comportamento previsto e non indica un problema. Verifica con docker compose version. Se non restituisce nulla, installa il pacchetto docker-compose-plugin.
Ogni comando riportato di seguito deve essere eseguito dalla directory che contiene compose.yaml, perché Compose ricava il nome del progetto da quella directory e cerca il file in relazione a essa. Se esegui lo stesso comando un livello più in alto, Compose si interrompe con no configuration file provided: not found. Se il formato del file è nuovo per te, inizia da un primo file Compose su un VPS e torna qui per consultare i comandi.
Ciclo di vita: i quattro comandi che si usano e quello che rimuove i container
docker compose up -d
docker compose up -d --wait
docker compose stop
docker compose start
docker compose restart web
docker compose downup -d crea la rete, crea i container, li avvia e termina. Termina non appena i container sono creati. Per questo uno script di deploy che esegue subito dopo una verifica curl spesso fallisce al primo tentativo. up -d --wait attende che ogni servizio con un healthcheck dichiari lo stato healthy e termina con un codice diverso da zero se uno di essi non raggiunge mai questo stato. Il flag è efficace solo quanto il controllo che utilizza. Scrivi un healthcheck di cui Compose possa fidarsi prima di usarlo nell'automazione.
stop arresta i container e li conserva. Di conseguenza, start riavvia gli stessi container mantenendo lo stesso writable layer. down li arresta, quindi rimuove i container e la rete del progetto. Tutto ciò che è stato scritto all'interno del container e al di fuori di un volume viene eliminato insieme a essi. Questo è l'errore di comprensione più costoso in Compose. La differenza completa tra down e stop spiega in quali casi si verifica.
restart non esegue un reload. Arresta e riavvia lo stesso container usando la configurazione già presente. Di conseguenza, una variabile d'ambiente modificata, un nuovo image tag o una mappatura delle porte modificata non hanno alcun effetto. Per applicare una modifica al file, esegui di nuovo up -d. Compose confronta ogni servizio con il container in esecuzione e ricrea soltanto quelli la cui configurazione è cambiata.
Applicare una modifica: ricreare, scaricare o ricostruire
docker compose up -d --force-recreate
docker compose pull && docker compose up -d
docker compose build --no-cache web
docker compose up -d --build webup -d da solo non esegue alcuna operazione se non è cambiato nulla, quindi è sicuro da eseguire ripetutamente. --force-recreate forza il confronto e sostituisce ogni container anche quando la configurazione è identica, quindi è il modo più rapido per eliminare uno stato anomalo all'interno del container.
L'aggiornamento di un'immagine richiede due comandi perché svolgono funzioni diverse. pull scarica l'immagine corrente per ogni tag indicato nel file. up -d rileva quindi che l'ID dell'immagine del servizio non corrisponde più a quello del container in esecuzione e lo ricrea. Se si salta il pull, up -d continua a eseguire l'ultima latest del mese scorso senza segnalare errori. Il rischio opposto si presenta in uno stack con più servizi: scaricare latest per tutti i servizi contemporaneamente può interrompere un'applicazione che funzionava fino a dieci secondi prima. Per questo un workspace AFFiNE self-hosted blocca invece ciascuno dei suoi quattro tag di immagine.
build si applica ai servizi che dichiarano una sezione build: invece di una image:. up -d --build esegue build e avvio in un solo passaggio, che è il ciclo normale mentre si modifica il codice. Usa --no-cache solo quando un layer memorizzato nella cache è chiaramente obsoleto, perché ricostruisce ogni layer da zero.
Visualizzare i servizi in esecuzione
docker compose ps
docker compose ps -a
docker compose logs -f --tail=100
docker compose logs --since 15m --timestamps db
docker compose top
docker compose lsps elenca solo i container in esecuzione. Un servizio che si è arrestato durante l'avvio non è visibile finché non si aggiunge -a. Pertanto, quando un container non compare in ps ma ps -a lo mostra come Exited (1), si tratta del comportamento normale in caso di errore all'avvio. Leggere il codice di uscita, quindi consultare i log.
logs -f segue contemporaneamente ogni servizio e antepone a ogni riga il nome del servizio. È la visualizzazione corretta quando i servizi comunicano tra loro e l'ordine degli eventi è importante. Specificare il nome di un servizio per restringere l'output. --tail=100 è importante per un container attivo da un mese, perché il comportamento predefinito stampa l'intera cronologia e riempie il terminale. --since 15m risponde alla domanda più comune: che cosa è successo durante il riavvio appena eseguito.
top elenca i processi all'interno di ogni container e distingue tra "il container è in esecuzione" e "il processo al suo interno è in esecuzione". ls esce dalla directory corrente ed elenca tutti i progetti Compose presenti sull'host con il relativo stato, così è possibile individuare lo stack avviato tre mesi fa.
Ottenere una shell all'interno di un servizio
docker compose exec web sh
docker compose exec -u root web sh
docker compose run --rm web env
docker compose run --rm --no-deps web shexec esegue un comando all'interno di un container già avviato. run avvia un nuovo container dalla stessa definizione del servizio. Serve quando il servizio non rimane attivo abbastanza a lungo da consentire l'esecuzione del comando al suo interno. Abbina sempre run a --rm. Senza questa opzione, ogni invocazione lascia un container arrestato, che si accumula fino a rendere docker compose ps -a illeggibile.
Prova sh prima di bash. Le immagini basate su Alpine non includono bash e l'errore visualizzato è exec: "bash": executable file not found in $PATH. Aggiungere --no-deps a run ignora le dipendenze del servizio. In questo modo un rapido controllo della configurazione non avvia l'intero database.
run --rm web env è il modo più rapido per verificare l'ambiente effettivamente assegnato a un servizio, dopo l'unione di ogni file .env, blocco environment: e variabile della shell. Quando un valore è errato, la causa è spesso l'ordine di unione. come Compose risolve i file env e i secret spiega quale origine ha la precedenza.
Reti, porte e risoluzione dei nomi
docker compose port web 80
docker compose exec web getent hosts db
docker compose config --networksCompose inserisce ogni servizio in una rete del progetto e il nome di ogni servizio diventa un nome DNS su quella rete. L'esecuzione di getent hosts db all'interno di web stampa l'indirizzo IP del container quando la risoluzione funziona e non stampa nulla quando non funziona. In questo modo puoi verificare in due secondi se «questi container riescono a comunicare». Se il nome viene risolto ma la connessione viene rifiutata, il processo all'interno di db è associato a 127.0.0.1 invece che a 0.0.0.0. Di conseguenza non accetta mai pacchetti provenienti da un altro container. Il resto di questo modello è descritto in come funzionano le reti Compose e il DNS dei servizi.
port web 80 stampa l'indirizzo e la porta dell'host su cui è pubblicata una porta del container. Questo evita di dover ricostruire il mapping quando proviene da una variabile. La pubblicazione di una porta crea anche una regola firewall gestita direttamente da Docker. Questa regola viene applicata prima delle tue regole. Di conseguenza, un servizio che ritenevi privato può essere esposto a Internet. Il caso è descritto in perché le porte Docker pubblicate bypassano ufw. È più sicuro lasciare queste porte non pubblicate e inserire davanti ai servizi un unico proxy con autenticazione sulla rete del progetto. È questo il modello descritto in eseguire Authentik come livello di single sign-on.
Volumi e dati
docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -vconfig --volumes stampa i volumi denominati dichiarati dal progetto, uno per riga. È l’elenco di ciò che deve essere incluso nel backup. Quando i volumi contengono dati non sostituibili, il comando di backup esatto è importante quanto l’elenco. Per questo il confronto tra PhotoPrism e Immich riporta i comandi di dump e copia richiesti da ciascun server fotografico. cp copia un file dentro o fuori da un container senza aprire una shell, usando la sintassi service:path sul lato in cui si trova il container.
down -v rimuove i volumi denominati insieme ai container. È il comando corretto per rimuovere uno stack di test e quello sbagliato per qualsiasi stack che contenga dati importanti, perché non richiede conferma e non può essere annullato. I bind mount non vengono rimossi, perché risiedono nel filesystem dell’host. Questa differenza nell’impatto della rimozione è uno dei motivi per cui è necessario scegliere consapevolmente tra bind mount e volumi denominati.
Pulizia che libera spazio su disco senza perdere dati
docker compose down --remove-orphans
docker system df
docker image prune -a
docker builder prune--remove-orphans elimina i container appartenenti al progetto che non compaiono più nel file. È esattamente ciò che accade dopo la ridenominazione di un servizio. Senza questo comando, i container continuano a essere in esecuzione e restano invisibili a docker compose ps.
docker system df mostra come viene utilizzato lo spazio su disco prima di eliminare qualsiasi elemento. Suddivide lo spazio occupato da immagini, container, volumi locali e cache di build e indica per ciascuna categoria lo spazio recuperabile. image prune -a rimuove tutte le immagini a cui non punta alcun tag. Su un server che ha scaricato diverse versioni di un'immagine di grandi dimensioni, questo comando consente spesso di recuperare più spazio. builder prune cancella la cache di build, che cresce silenziosamente su qualsiasi server utilizzato per creare le proprie immagini.
Nessuno di questi comandi modifica un volume denominato. Solo docker volume prune e docker compose down -v lo fanno.
Controllare il file prima che causi problemi
docker compose config --quiet
docker compose config --services
docker compose --dry-run up -dconfig --quiet verifica il file e non produce output in caso di esito positivo, quindi è adatto a una fase di pre-deploy o a un hook Git. Il semplice comando config stampa il file completamente unito e interpolato. Questo consente di verificare che una variabile sia stata risolta e che un file di override sia stato applicato nell’ordine previsto. Una variabile non impostata viene visualizzata come valore vuoto, insieme all’avviso The "X" variable is not set. Defaulting to a blank string.
--dry-run è un’opzione globale, non un’opzione del sottocomando, quindi deve essere inserita prima di up. Stampa tutte le operazioni che Compose eseguirebbe senza apportare modifiche. Sono trenta secondi utili prima di un down su uno stack importante.
Gestire file, profili e progetti
docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose --profile debug up -d
docker compose -p staging up -dPiù flag -f vengono uniti nell’ordine indicato; i file successivi sovrascrivono quelli precedenti chiave per chiave. È il metodo standard per mantenere un file di base con un piccolo override per la produzione. Le regole differiscono però per liste e mappe, quindi prima di analizzare un comportamento imprevisto, consulta come Compose unisce più file.
--profile avvia i servizi associati a quel profilo insieme a quelli senza profilo. In questo modo gli strumenti di debug restano esclusi da una normale up. -p imposta il nome del progetto, consentendo di eseguire affiancate due copie dello stesso stack con reti e nomi dei volumi separati. Per ripristinare lo stack dopo un riavvio non devi digitare alcun comando: se ne occupa un’unità che viene eseguita automaticamente, descritta in avviare gli stack Compose all’avvio.
FAQ
Che cosa ha sostituito docker-compose con un trattino?
Compose V2, eseguito come docker compose con uno spazio. È un plugin incluso in Docker Engine e gli attuali pacchetti non installano più lo strumento Python V1. Se la forma con lo spazio non produce alcun output, installare il pacchetto docker-compose-plugin per la propria distribuzione. Aggiornare i vecchi script alla forma con lo spazio invece di aggiungere un alias, perché V2 supporta flag che V1 non aveva.
Perché docker compose restart non rileva la modifica alla configurazione?
restart arresta e riavvia il container esistente usando la configurazione con cui è stato creato e non rilegge mai compose.yaml. Qualsiasi modifica a variabili d'ambiente, porte, volumi o tag dell'immagine richiede docker compose up -d, che confronta ogni servizio con il container in esecuzione e ricrea quelli diversi. Aggiungere --force-recreate quando si vuole eseguire la sostituzione anche se il file non è cambiato.
Come si aggiorna un servizio a un'immagine più recente?
Eseguire docker compose pull, quindi docker compose up -d. Il pull scarica l'immagine corrente per ogni tag presente nel file e up -d ricrea ogni servizio il cui ID immagine non corrisponde più a quello del container. L'esecuzione autonoma di up -d riutilizza l'immagine già presente sul disco. Per questo uno stack vincolato a latest può restare su una build vecchia di mesi senza mostrare errori.
Quali comandi di pulizia sono sicuri su un server in produzione?
docker system df, docker image prune -a e docker builder prune rimuovono solo immagini e cache, quindi i servizi in esecuzione continuano a funzionare e i volumi denominati non vengono modificati. La coppia pericolosa è docker compose down -v e docker volume prune, che elimina i volumi denominati senza chiedere conferma. Eseguire prima docker compose config --volumes per sapere quali dati sono a rischio.
È possibile eseguire un solo comando senza avviare l'intero stack?
Sì. docker compose run --rm --no-deps web sh avvia un singolo container dalla definizione del servizio web, non avvia le relative dipendenze e rimuove il container al termine. Usare invece exec quando il container è già in esecuzione, perché exec si collega al processo attivo e mostra lo stato effettivo del servizio.