Docker Compose: promemoria con i comandi più utili ed esempi

A proposito, docker-compose è diverso da docker compose...

Indice

Ecco il Docker Compose cheatsheet con esempi annotati per aiutarti a padroneggiare rapidamente i file e i comandi di Compose.

Questa guida fa parte di Developer Tools: La guida completa ai flussi di lavoro di sviluppo moderni.

Prerequisiti

Docker Engine deve essere installato prima di usare Compose. Su Ubuntu, segui Installare Docker su Ubuntu per scegliere il metodo di installazione corretto e configurare il plugin docker compose.

docker-compose schema

Riferimento File Compose: docker-compose.yml

Struttura principale:

version: '3'       # Versione del formato del file Compose

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"   # Porta host 8080: Porta container 80
  db:
    image: postgres
    environment:            # Variabili d'ambiente
      POSTGRES_PASSWORD: example
    volumes:
      - db_data:/var/lib/postgresql/data

networks:          # Rete personalizzata
  appnet:
    driver: bridge

volumes:           # Volume con nome
  db_data:
  • services: Ogni container nella tua app multi-container. Nell’esempio sopra abbiamo due servizi: web e db. Per le operazioni individuali sui container, consulta la Cheatsheet Docker.
  • networks & volumes: Definisce reti isolate e archiviazione persistente - qui abbiamo la rete appnet e il volume db_data.

Esempi

Servizio singolo con mapping delle porte

services:
  app:
    build: .
    ports:
      - "8000:80"   # Porta host 8000: Porta container 80

Espone l’app sulla porta host 8000 e costruisce dal Dockerfile nella directory corrente.

Multi-servizio con volume condiviso e rete personalizzata

version: '3'
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - type: bind
        source: ./app
        target: /app
    networks:
      - mynet
  db:
    image: postgres
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - mynet

networks:
  mynet:

volumes:
  db_data:

Web e DB sulla stessa rete; DB utilizza un volume con nome persistente - db_data.

Uso del contesto di build e del percorso del Dockerfile

Puoi costruire un’immagine docker on demand dal Dockerfile specificato in docker-compose.yaml.

services:
  app:
    build:
      context: .
      dockerfile: docker/MyDockerfile

Condivisione dei dati tra i servizi

services:
  web:
    image: nginx
    volumes:
      - shared_data:/usr/share/nginx/html
  worker:
    image: myworker
    volumes:
      - shared_data:/usr/src/app/data

volumes:
  shared_data:

Sia il servizio web che quello worker accedono allo stesso volume (per file statici o scambi di dati) - shared_data.

Opzioni Avanzate per il File Compose

  • environment: Imposta le variabili ENV per i container.
  • depends_on: Controlla l’ordine di avvio dei servizi.
  • deploy.replicas: Scalare il servizio in modalità Swarm.

Esempio:

services:
  web:
    image: nginx
    deploy:
      replicas: 3
    depends_on:
      - db

Avvia 3 istanze web; controlla solo l’ordine di avvio (non la readiness).

Comandi Essenziali di Docker Compose

Comando Descrizione Utilizzo Esempio
docker-compose up Crea e avvia i container docker-compose up
docker-compose up -d Esegui in background docker-compose up -d
docker-compose exec Esegui un comando nel container in esecuzione docker-compose exec web bash
docker-compose build Costruisci/ricostruisci le immagini docker-compose build
docker-compose down Ferma e rimuovi container, reti, volumi e immagini docker-compose down
docker-compose logs -f Visualizza e segue i log docker-compose logs -f
docker-compose ps Elenca i container in esecuzione docker-compose ps
docker-compose run Esegui comandi one-off (aggira il comando nel file Compose) docker-compose run web python manage.py migrate
docker-compose stop Ferma i container in esecuzione (possibile riavvio con start) docker-compose stop
docker-compose restart Riavvia i servizi docker-compose restart web
docker-compose pull Scarica le immagini dei servizi docker-compose pull
docker-compose rm Rimuovi i container dei servizi fermati docker-compose rm web
docker-compose config Validazione e visualizzazione del file Compose docker-compose config
docker-compose up --scale web=3 Avvia più istanze di un servizio docker-compose up --scale web=3

Pattern Comuni di Compose

  • Database con dati persistenti

    services:
      mysql:
        image: mysql
        environment:
          MYSQL_ROOT_PASSWORD: password
        volumes:
          - mysql_data:/var/lib/mysql
    
    volumes:
      mysql_data:
    

    I dati del DB persistono nel volume mysql_data tra un riavvio del container e l’altro.

  • Bind mount del codice per lo sviluppo

    services:
      app:
        build: .
        volumes:
          - .:/app
    

    Modifica live del codice sull’host, riflessa automaticamente nel container.

Flag Utili

  • -d: Modalità detach (esecuzione in background).
  • --build: Forza la ricostruzione delle immagini prima dell’avvio.
  • --force-recreate: Ricrea i container anche se non modificati.
  • --remove-orphans: Rimuovi i container non definiti nel file Compose.

Definizione e Personalizzazione dei Servizi

Puoi definire e personalizzare servizi, reti e volumi in Docker Compose sfruttando il file docker-compose.yml, che centralizza tutte le esigenze di configurazione e orchestrazione della tua applicazione.

  • I Servizi sono definiti sotto la chiave services.
  • Ogni servizio rappresenta una configurazione del container, dove puoi impostare:
    • Image: Seleziona un’immagine da Docker Hub o da un altro registro.
    • Ports: Mappa le porte del container alle porte dell’host.
    • Variabili d’ambiente: Passa i valori di configurazione.
    • Volumes: Persiste dati o condivide file/cartelle con l’host o altri servizi.
    • Networks: Controlla a quali reti il servizio può accedere.

Esempio:

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"   # Porta host 8080: Porta container 80
    environment:
      - NGINX_HOST=localhost
    volumes:
      - web_data:/usr/share/nginx/html
    networks:
      - frontend

  db:
    image: postgres:13
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - backend
  • Qui, il servizio web usa l’immagine nginx, imposta una variabile d’ambiente, allega un volume, apre la porta 80 come 8080 sull’host e si connette alla rete frontend. Il servizio db fa qualcosa di simile per PostgreSQL.

Personalizzazione delle Reti

  • Le Reti controllano quali servizi possono comunicare. Compose crea una rete predefinita, ma puoi definirne altre, specificare driver personalizzati, impostare opzioni e determinare quale servizio si unisce a quale rete per un isolamento fine.
  • Definisci le reti a livello superiore sotto networks e elenca a quali reti un servizio deve collegarsi con la chiave di livello servizio networks.

Esempio:

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.host_binding_ipv4: "127.0.0.1"
  • Allega le reti ai servizi:
services:
  app:
    networks:
      - frontend
      - backend
  db:
    networks:
      - backend
  • Questa configurazione consente al servizio app di accedere sia agli utenti sulla rete frontend che a quella backend, mentre db è accessibile solo all’interno della backend.

Personalizzazione dei Volumi

  • I Volumi sono definiti sotto la chiave di livello superiore volumes. Montali nei container usando la chiave volumes sotto un servizio.
  • I volumi possono essere denominati, usare driver personalizzati e essere condivisi tra più servizi per la persistenza e la condivisione dei dati.

Esempio:

volumes:
  web_data:                # Volume denominato per il contenuto web
  db_data:                 # Volume denominato per il database

services:
  web:
    volumes:
      - web_data:/usr/share/nginx/html

  db:
    volumes:
      - db_data:/var/lib/postgresql/data
  • In questo esempio, web_data viene persistito ed è disponibile a qualsiasi container che lo monti. db_data garantisce che i dati del database non vadano mai persi in caso di ricreazione del container.
  • Puoi definire bind-mount con opzioni driver personalizzate per casi avanzati:
volumes:
  db_data:
    driver: local
    driver_opts:
      type: none
      device: /data/db_data
      o: bind
  • Questa configurazione imposta un bind-mount dal percorso host /data/db_data dentro il container.

Riepilogo delle Best Practice:

  • Usa il nome del servizio come hostname DNS per la comunicazione tra servizi.
  • Collega i servizi a più reti secondo necessità per controllare l’accesso.
  • Usa volumi con nome per lo storage persistente e la condivisione dei dati.
  • Definisci tutto usando YAML, abilitando il version control e script di deployment facili.
  • Per la gestione e la visualizzazione dei container, valuta Installare Portainer su Linux.

Più file compose

Per organizzare configurazioni complesse multi-servizio in Docker Compose, puoi usare più file compose e file di override, consentendo configurazioni modulari, specifiche per ambiente e scalabili. Ecco come funziona:

  1. Struttura del File Base e di Override
  • Crea un file base (compose.yaml o docker-compose.yml) contenente tutte le definizioni di servizio comuni e predefinite.
  • Aggiungi file di override specifici per l’ambiente (es., docker-compose.override.yml, docker-compose.dev.yml, docker-compose.prod.yml).

Esempio di struttura dei file:

/directory-progetto
|-- docker-compose.yml           # Configurazione base
|-- docker-compose.override.yml  # Override locali/dev (applicati automaticamente)
|-- docker-compose.prod.yml      # Override di produzione
|-- docker-compose.test.yml      # Override di test (se necessari)

La configurazione base definisce i servizi principali, mentre ogni override personalizza le impostazioni per un ambiente o un caso specifico.

  1. Come Funzionano gli Override dei File
  • Merging: Quando esegui docker compose up, Docker Compose unisce il base con eventuali override in ordine; i file successivi sovrascrivono, estendono o aggiungono impostazioni ai file precedenti.
  • Sovrascrittura dei Campi: Se un servizio o un campo è definito in più file, viene usato il valore del file specificato per ultimo. I nuovi campi vengono aggiunti.

Esempio di merge:

  • docker-compose.yml:
    services:
      web:
        image: myapp
        ports:
          - "8000:80"
    
  • docker-compose.override.yml:
    services:
      web:
        environment:
          - DEBUG=true
    
  • Risultato: Il servizio web usa sia l’immagine e la porta di base, sia la variabile d’ambiente DEBUG sovrascritta.
  1. Utilizzo dei Comandi per Più File
  • Comportamento predefinito: Se presente, Docker Compose carica automaticamente docker-compose.override.yml insieme a docker-compose.yml quando esegui qualsiasi comando.
  • Specificazione manuale dei file: Usa i flag -f per controllare quali file vengono uniti e in quale ordine:
    docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
    
    • Questo ignora l’override predefinito e usa le impostazioni specifiche per la produzione.
  1. Strategie Pratiche di Organizzazione
  • Separazione degli ambienti: Usa un override per ogni ambiente: dev, test, prod, ecc.
  • Microservizi e team: Spezza la configurazione in file separati per diversi servizi o team e combinali secondo necessità.
  • Feature toggles: File aggiuntivi possono introdurre o rimuovere servizi o configurazioni opzionali per esigenze temporanee (es., un compose.debug.yml per log extra).
  1. Vantaggi
  • Chiarezza: Mantiene i singoli file piccoli e focalizzati.
  • Scalabilità: Aggiungi facilmente nuovi servizi, ambienti o impostazioni.
  • Manutenibilità: Modifica o revisiona solo le sezioni rilevanti per un dato deployment.
  1. Esempio: Cambio di Ambiente

Sviluppo:

docker compose -f docker-compose.yml -f docker-compose.dev.yml up

Produzione:

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Ogni ambiente riceve solo la configurazione necessaria per esso, con tutta la configurazione condivisa nel file base.

Organizzare configurazioni Compose complesse con più file - e sfruttare il sistema di override/merge - garantisce modularità, personalizzazione specifica per ambiente e facile scalabilità per grandi applicazioni Docker multi-servizio.

Per il deployment in produzione su un host Linux singolo — avvio all’accensione, spegnimento pulito, aggiornamenti e rotazione dei log — consulta Eseguire Docker Compose come Servizio Linux con systemd. Per un confronto con Podman Quadlet, consulta Podman Quadlet vs Docker Compose per Servizi Linux.

Iscriviti

Ricevi nuovi articoli su sistemi, infrastruttura e ingegneria AI.