alltools.one
DevOps
2025-06-16
8 min
alltools.one Team
YAMLDockerDocker ComposeDevOpsContainers

YAML per Docker Compose: Pattern di Configurazione e Suggerimenti

Docker Compose usa YAML per definire applicazioni multi-container. Un docker-compose.yml ben strutturato fa la differenza tra un ambiente di sviluppo fluido e ore di debug dei problemi dei container. Questa guida copre i pattern essenziali e le insidie comuni.

Struttura di Base

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
    depends_on:
      - api

  api:
    build: ./api
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://db:5432/myapp
    depends_on:
      - db

  db:
    image: postgres:16
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: myapp
      POSTGRES_PASSWORD: secret

volumes:
  pgdata:

Variabili d'Ambiente

Inline

services:
  api:
    environment:
      NODE_ENV: production
      PORT: "3000"
      DEBUG: "false"

Da File

services:
  api:
    env_file:
      - .env
      - .env.local  # Sovrascrive i valori di .env

Sostituzione di Variabili

Referenzia variabili d'ambiente dell'host:

services:
  api:
    image: myapp:${TAG:-latest}  # Default a "latest"
    environment:
      API_KEY: ${API_KEY}  # Obbligatorio - fallisce se non impostato
      LOG_LEVEL: ${LOG_LEVEL:-info}  # Default a "info"

Rete

Reti Personalizzate

services:
  web:
    networks:
      - frontend
  api:
    networks:
      - frontend
      - backend
  db:
    networks:
      - backend

networks:
  frontend:
  backend:
    internal: true  # Nessun accesso esterno

I servizi sulla stessa rete possono raggiungersi tramite il nome del servizio. Il servizio db è raggiungibile solo da api, non da web.

Mappatura Porte

ports:
  - "8080:80"         # host:container
  - "443:443"
  - "127.0.0.1:3000:3000"  # Binding solo su localhost
  - "3000"            # Porta host casuale

Volumi

Volumi con Nome (Persistenti)

services:
  db:
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:
    driver: local

Bind Mount (Sviluppo)

services:
  api:
    volumes:
      - ./src:/app/src          # Codice sorgente
      - /app/node_modules       # Volume anonimo (previene sovrascrittura)

Il pattern del volume anonimo (/app/node_modules) impedisce che il bind mount dell'host sovrascriva le dipendenze installate nel container.

Controlli di Salute

services:
  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  api:
    depends_on:
      db:
        condition: service_healthy

Questo assicura che api si avvii solo dopo che db supera i controlli di salute — non solo quando il container si avvia.

Campi di Estensione (Pattern DRY)

Usa campi con prefisso x- con anchor YAML per ridurre la ripetizione:

x-common: &common
  restart: unless-stopped
  logging:
    driver: json-file
    options:
      max-size: "10m"
      max-file: "3"

x-env: &common-env
  TZ: UTC
  LOG_FORMAT: json

services:
  api:
    <<: *common
    build: ./api
    environment:
      <<: *common-env
      PORT: "3000"

  worker:
    <<: *common
    build: ./worker
    environment:
      <<: *common-env
      QUEUE: default

Per approfondimenti sugli anchor YAML, vedi la nostra guida ad anchor e alias YAML.

Compose Multi-Stage

Sviluppo vs Produzione

# docker-compose.yml (base)
services:
  api:
    build: ./api
    environment:
      DATABASE_URL: postgres://db:5432/myapp

# docker-compose.override.yml (dev - caricato automaticamente)
services:
  api:
    volumes:
      - ./api/src:/app/src
    environment:
      NODE_ENV: development
      DEBUG: "true"
    ports:
      - "3000:3000"
      - "9229:9229"  # Porta debug

# docker-compose.prod.yml
services:
  api:
    environment:
      NODE_ENV: production
    deploy:
      replicas: 3
# Sviluppo (carica automaticamente l'override)
docker compose up

# Produzione
docker compose -f docker-compose.yml -f docker-compose.prod.yml up

Insidie Comuni

1. Numeri di Porta Non Quotati

# RISCHIOSO - YAML interpreta 80:80 come un numero in base 60
ports:
  - 80:80

# SICURO - usa sempre le virgolette
ports:
  - "80:80"

2. Variabili d'Ambiente Booleane

# SBAGLIATO - YAML converte in booleano
environment:
  DEBUG: true  # Diventa Python True, non la stringa "true"

# CORRETTO - quota tutti i valori env
environment:
  DEBUG: "true"

3. Tempistica depends_on

depends_on aspetta solo l'avvio del container, non la prontezza:

# Il container si avvia ma il DB potrebbe non essere pronto
depends_on:
  - db

# Attendi il controllo di salute
depends_on:
  db:
    condition: service_healthy

Valida i tuoi file Docker Compose con il nostro Validatore YAML.

FAQ

Qual è la differenza tra docker-compose.yml e compose.yml?

Entrambi i nomi di file funzionano. compose.yml è la convenzione più recente raccomandata da Docker. docker-compose.yml è il nome legacy. Docker Compose v2+ cerca entrambi, preferendo compose.yml se entrambi esistono. Per i nuovi progetti, usa compose.yml.

Devo usare Docker Compose in produzione?

Docker Compose è eccellente per lo sviluppo e i deploy semplici. Per la produzione su scala, considera Docker Swarm (usa nativamente i file Compose) o Kubernetes. Il vantaggio di Compose è che la tua configurazione di sviluppo informa direttamente la produzione, riducendo le differenze tra ambienti.

Risorse Correlate

Published on 2025-06-16
YAML for Docker Compose: Configuration Patterns and Tips | alltools.one