Skip to main content
  1. Concetti/

Docker Compose

·5 mins
Alessio Barnini
Author
Alessio Barnini
Table of Contents

Cosa fa
#

File YAML che descrive tutta l'infrastruttura di un'applicazione: servizi, reti, volumi, variabili d'ambiente. Con un solo comando (docker compose up) avvii tutto. Con un altro (docker compose down) spegni tutto.


Struttura del file
#

# docker-compose.yml — struttura generale
version: "3.8"

services:        # i container da avviare
  nome-servizio:
    image: ...
    ...

volumes:         # storage persistente
  nome-volume:

networks:        # reti virtuali
  nome-rete:

Nome fisso per volumi e reti
#

Docker usa il nome della cartella come prefisso per volumi e reti:

# cartella: infra-antonella/
# volume dichiarato: postgres_data
# risultato su Docker: infra-antonella_postgres_data
docker volume ls
# local  infra-antonella_postgres_data

Se sposti il compose in un'altra cartella, il prefisso cambia e Docker crea un nuovo volume vuoto — perdendo i dati del vecchio.

La soluzione e usare il campo name: per fissare il nome indipendentemente dalla cartella:

# Senza name — dipende dalla cartella (fragile)
volumes:
  postgres_data:

# Con name — nome fisso su Docker (portabile)
volumes:
  postgres_data:
    name: "n8n_postgres_data"   # questo e il nome che vedi in docker volume ls

networks:
  web:
    name: web                   # stesso pattern per le reti
    
    
#esempio
docker-compose.yml
─────────────────────────────────────
services:
  postgres-rag:
    volumes:
      - db-data:/var/lib/postgresql/data
        
        nome interno al compose
        (come una variabile)

volumes:
  db-data:              ← stesso nome interno
    name: postgres_rag_data
          
          nome fisico su Docker
          (quello che vedi in "docker volume ls")

Lo stesso vale per le reti. Il campo name: e il pattern corretto per qualsiasi servizio in produzione.

Important

Aggiungi sempre name: esplicito a volumi e reti quando crei un nuovo compose. Evita il problema del prefisso e rende il progetto portabile su qualsiasi server senza dover migrare i dati.


Esempio reale annotato — Chatwoot
#

services:
  # Ancora YAML — definisce configurazione comune riusabile
  base: &base
    image: chatwoot/chatwoot:v3.11.0  # versione fissa, non latest
    env_file: .env                    # variabili da file esterno
    volumes:
      - chatwoot_storage:/app/storage # volume named per i file upload

  postgres:
    image: pgvector/pgvector:pg16
    container_name: chatwoot_postgres  # nome fisso (invece di hash casuale)
    restart: always                    # riavvia se crasha
    ports:
      - "127.0.0.1:5434:5432"
      # 127.0.0.1 = solo localhost — non esposto a internet
      # 5434      = porta sull'host (evita conflitti con postgres locale)
      # 5432      = porta dentro il container
    environment:
      POSTGRES_DB: ${POSTGRES_DATABASE}   # legge da .env
      POSTGRES_USER: ${POSTGRES_USERNAME}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - chatwoot_db:/var/lib/postgresql/data  # dati persistenti
    networks:
      - internal  # solo rete interna — non raggiungibile da Traefik

  redis:
    image: redis:7-alpine  # alpine = immagine minima, piu' sicura
    container_name: chatwoot_redis
    restart: always
    networks:
      - internal

  rails:
    <<: *base    # copia tutto da &base
    container_name: chatwoot_rails
    command: ["bundle", "exec", "rails", "s", "-p", "3000", "-b", "0.0.0.0"]
    networks:
      - internal  # parla con postgres e redis
      - web       # raggiungibile da Traefik

  sidekiq:
    <<: *base    # stessa immagine di rails, comando diverso
    container_name: chatwoot_sidekiq
    command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"]
    networks:
      - internal  # non ha bisogno di Traefik — solo DB e Redis

volumes:
  chatwoot_storage:  # file caricati dagli utenti
  chatwoot_db:       # dati postgres

networks:
  internal:
    driver: bridge   # rete privata tra i container
  web:
    external: true   # gia' esiste — creata da Traefik

Flusso di una richiesta in questo stack
#

sequenceDiagram
    participant U as Utente
    participant T as Traefik
    participant R as Rails :3000
    participant PG as Postgres :5432
    participant RD as Redis :6379

    U->>T: GET https://chat.dominio.it
    T->>R: GET http://rails:3000 (rete web)
    R->>PG: SELECT * FROM conversations (rete internal)
    PG->>R: risultati
    R->>RD: cache lookup (rete internal)
    RD->>R: cache hit
    R->>T: 200 OK + HTML
    T->>U: 200 OK + HTML cifrato TLS

Anchor YAML — &base e <<: *base
#

L'anchor evita di ripetere la stessa configurazione:

# Senza anchor — ripetizione
rails:
  image: chatwoot/chatwoot:v3.11.0
  env_file: .env
  volumes:
    - chatwoot_storage:/app/storage

sidekiq:
  image: chatwoot/chatwoot:v3.11.0   # ripetuto
  env_file: .env                     # ripetuto
  volumes:
    - chatwoot_storage:/app/storage  # ripetuto

# Con anchor — DRY (Don't Repeat Yourself)
base: &base
  image: chatwoot/chatwoot:v3.11.0
  env_file: .env
  volumes:
    - chatwoot_storage:/app/storage

rails:
  <<: *base          # copia tutto da base
  command: [...]     # aggiunge solo quello che cambia

sidekiq:
  <<: *base          # stessa cosa
  command: [...]

Comandi essenziali
#

docker compose up -d              # avvia tutto in background
# -d = detached

docker compose down               # spegne tutto
docker compose down -v            # spegne e cancella volumi
# -v = volumes — DISTRUTTIVO

docker compose logs -f rails      # segue log di un servizio
# -f = follow

docker compose logs --tail 20     # ultime 20 righe di tutti i servizi
# --tail N = ultime N righe

docker compose restart rails      # riavvia un singolo servizio
docker compose exec rails bash    # entra nel container rails
# exec = esegui comando in container gia' avviato

docker compose run --rm rails bash
# run = avvia container temporaneo
# --rm = remove, elimina dopo l'uso

docker compose ps                 # stato di tutti i servizi
docker compose pull               # scarica versioni aggiornate delle immagini

docker compose config             # mostra il compose risolto: variabili .env sostituite,
                                  # nomi fisici di volumi e reti, path assoluti dei bind mount
                                  # utile per debuggare prima di avviare
Warning

docker compose down -v cancella i volumi — il database sparisce. Usalo solo se hai un backup o vuoi resettare completamente.

Tip

docker compose exec -it rails bash e' il modo per "entrare" in un container e girare come se fossi dentro un mini Linux. Da li' puoi ispezionare file, variabili d'ambiente, connessioni.


Collegato a
#

  • docker-image — le immagini usate nei servizi
  • docker-network-defense — le reti definite nel file
  • docker-security — volumi, porte, permessi
  • system — categoria

Related