# Docker Compose nel 2026: Applicazioni Multi-Container, Networking e Domande per Colloqui DevOps > Tutorial Docker Compose per applicazioni multi-container con networking, volumi e deployment in produzione. Include domande frequenti nei colloqui DevOps. - Published: 2026-08-03 - Updated: 2026-08-03 - Author: SharpSkill - Reading time: 5 min --- Docker Compose rimane lo strumento preferito per definire ed eseguire applicazioni Docker multi-container nel 2026. Che si tratti di orchestrare uno stack di sviluppo locale o di prepararsi per un colloquio DevOps, la comprensione del networking di Compose, delle dipendenze tra servizi e dei pattern di produzione distingue gli sviluppatori junior dai professionisti senior. > **Concetto Chiave** > > Docker Compose utilizza un formato YAML dichiarativo per definire servizi, reti e volumi in un unico file. L'esecuzione di `docker compose up` avvia l'intero stack applicativo con networking isolato e storage persistente. ## Comprendere l'Architettura di Docker Compose Docker Compose opera secondo un principio semplice: definire i servizi dell'applicazione in un file `compose.yaml` (la convenzione moderna che sostituisce `docker-compose.yml`), e Compose gestisce la creazione dei container, il networking e la gestione del ciclo di vita. La [specifica Docker Compose](https://docs.docker.com/compose/compose-file/) definisce tre concetti fondamentali: - **Services**: Configurazioni dei container inclusi immagine, contesto di build, variabili d'ambiente e limiti di risorse - **Networks**: Canali di comunicazione isolati tra i servizi - **Volumes**: Storage persistente che sopravvive ai riavvii dei container ```yaml # compose.yaml services: api: build: ./api ports: - "3000:3000" environment: - DATABASE_URL=postgres://db:5432/app depends_on: db: condition: service_healthy networks: - backend db: image: postgres:16 volumes: - postgres_data:/var/lib/postgresql/data environment: - POSTGRES_DB=app - POSTGRES_PASSWORD_FILE=/run/secrets/db_password secrets: - db_password healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5 networks: - backend networks: backend: driver: bridge volumes: postgres_data: secrets: db_password: file: ./secrets/db_password.txt ``` Questa configurazione dimostra diversi pattern pronti per la produzione: health check per l'ordinamento delle dipendenze, Docker secrets per dati sensibili, volumi nominati per la persistenza e definizioni di rete esplicite. ## Approfondimento sul Networking di Docker Compose Per impostazione predefinita, Compose crea una singola rete per l'applicazione. Tutti i servizi si uniscono a questa rete e possono raggiungersi a vicenda utilizzando il nome del servizio come hostname. Comprendere questo modello di networking è fondamentale per una successiva [migrazione a Kubernetes](/blog/devops/kubernetes-deploying-first-application). ```yaml # compose.yaml services: frontend: build: ./frontend ports: - "80:80" networks: - frontend-net - backend-net api: build: ./api networks: - backend-net cache: image: redis:7-alpine networks: - backend-net db: image: postgres:16 networks: - backend-net networks: frontend-net: driver: bridge backend-net: driver: bridge internal: true ``` Il flag `internal: true` impedisce alla rete backend di accedere a Internet. Il servizio frontend collega entrambe le reti, fungendo da unico punto di ingresso. Questa segmentazione della rete rispecchia le pratiche di sicurezza in produzione. > **Risoluzione DNS** > > Il server DNS integrato di Docker risolve automaticamente i nomi dei servizi. Il servizio `api` raggiunge il database su `db:5432` senza alcuna configurazione manuale degli IP. ## Build Multi-Stage con Compose Le immagini di produzione dovrebbero essere minimali. Le build multi-stage combinate con i profili di Compose permettono configurazioni diverse per sviluppo e produzione. ```dockerfile # api/Dockerfile # Stage 1: Build FROM node:22-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Stage 2: Production FROM node:22-alpine AS production WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules COPY package*.json ./ USER node EXPOSE 3000 CMD ["node", "dist/index.js"] # Stage 3: Development FROM node:22-alpine AS development WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . USER node CMD ["npm", "run", "dev"] ``` ```yaml # compose.yaml services: api: build: context: ./api target: ${BUILD_TARGET:-production} volumes: - ${API_VOLUMES:-./api/dist:/app/dist:ro} profiles: - ${COMPOSE_PROFILES:-prod} ``` L'esecuzione di `BUILD_TARGET=development COMPOSE_PROFILES=dev docker compose up` avvia la configurazione di sviluppo con hot reload. ## Dipendenze dei Servizi e Health Check La direttiva `depends_on` controlla l'ordine di avvio, ma i container avviati non significano servizi pronti. Gli health check risolvono questo problema di timing, un pattern frequentemente richiesto nei [colloqui DevOps](/blog/devops/essential-devops-interview-questions). ```yaml # compose.yaml services: api: build: ./api depends_on: db: condition: service_healthy cache: condition: service_started migrations: condition: service_completed_successfully migrations: build: ./api command: npm run migrate depends_on: db: condition: service_healthy db: image: postgres:16 healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 3s retries: 5 start_period: 10s cache: image: redis:7-alpine healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 3 ``` Esistono tre condizioni di dipendenza: - `service_started`: Default, il container è stato avviato - `service_healthy`: L'health check è superato - `service_completed_successfully`: Il container termina con codice 0 (per container di inizializzazione) ## Docker Compose per lo Sviluppo Locale Gli ambienti di sviluppo beneficiano di bind mount, override di configurazione e strumenti di debug. Il file `compose.override.yaml` viene automaticamente unito a `compose.yaml`. ```yaml # compose.yaml (configurazione base) services: api: build: ./api environment: - NODE_ENV=production db: image: postgres:16 ``` ```yaml # compose.override.yaml (override di sviluppo) services: api: build: target: development volumes: - ./api:/app - /app/node_modules environment: - NODE_ENV=development - DEBUG=app:* ports: - "9229:9229" db: ports: - "5432:5432" ``` Il volume anonimo `/app/node_modules` impedisce ai node_modules dell'host di sovrascrivere le dipendenze installate nel container. ## Pattern di Deployment in Produzione Docker Compose funziona per deployment in produzione su singolo host. Per l'orchestrazione multi-host, [Kubernetes con Helm](/blog/devops/kubernetes-helm-charts-2026-packaging-deployment-interview-questions) offre una migliore scalabilità, ma Compose rimane valido per applicazioni più piccole. ```yaml # compose.prod.yaml services: api: image: registry.example.com/api:${VERSION:-latest} deploy: replicas: 3 resources: limits: cpus: "0.5" memory: 512M reservations: cpus: "0.25" memory: 256M restart_policy: condition: on-failure delay: 5s max_attempts: 3 logging: driver: json-file options: max-size: "10m" max-file: "3" nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./certs:/etc/nginx/certs:ro depends_on: - api ``` La chiave `deploy` configura limiti di risorse, numero di repliche e politiche di riavvio. L'esecuzione di `docker compose -f compose.prod.yaml up -d` avvia lo stack di produzione in modalità detached. ## Variabili d'Ambiente e Gestione dei Secrets Le configurazioni sensibili richiedono una gestione appropriata. Docker Compose supporta diversi approcci, dai file `.env` ai Docker secrets. ```bash # .env POSTGRES_PASSWORD=dev_password_only API_SECRET_KEY=local_dev_key ``` ```yaml # compose.yaml services: api: environment: - API_SECRET_KEY # Eredita dalla shell o da .env - DATABASE_URL=postgres://user:${POSTGRES_PASSWORD}@db:5432/app env_file: - ./config/api.env ``` Per la produzione, i Docker secrets offrono maggiore sicurezza montando i dati sensibili come file anziché variabili d'ambiente: ```yaml # compose.prod.yaml services: api: secrets: - api_key - db_password environment: - API_KEY_FILE=/run/secrets/api_key secrets: api_key: external: true db_password: file: ./secrets/db_password.txt ``` > **Nota sulla Sicurezza** > > Non committare mai file `.env` contenenti secrets di produzione nel controllo versione. Per i deployment in produzione, utilizzare gestori di secrets esterni come HashiCorp Vault o soluzioni dei cloud provider. ## Domande Frequenti nei Colloqui DevOps su Docker Compose Gli intervistatori testano la comprensione dei concetti di Compose attraverso scenari pratici. Queste domande appaiono frequentemente nei colloqui DevOps e platform engineering. **D: Come comunicano i container in una rete Compose?** Docker crea una rete bridge dedicata per ogni progetto Compose. I servizi comunicano usando i nomi dei servizi come hostname. Il server DNS integrato risolve questi nomi agli indirizzi IP dei container. Il traffico esterno raggiunge i servizi solo attraverso le porte esplicitamente pubblicate. **D: Cosa succede quando si esegue `docker compose up` con container esistenti?** Compose confronta la configurazione attuale con i container in esecuzione. I servizi invariati continuano a funzionare. I servizi modificati vengono ricreati con le nuove impostazioni. I nuovi servizi vengono avviati da zero. I servizi rimossi vengono fermati ed eliminati. **D: Come si gestiscono le migrazioni del database in Compose?** Esistono due pattern. Primo: utilizzare un container di inizializzazione con dipendenza `service_completed_successfully`: ```yaml services: migrate: image: api:latest command: npm run migrate depends_on: db: condition: service_healthy api: depends_on: migrate: condition: service_completed_successfully ``` Secondo: includere la logica di migrazione nello script di avvio dell'applicazione, verificando e applicando le migrazioni in sospeso prima di accettare il traffico. **D: Qual è la differenza tra volumi e bind mount?** I volumi nominati sono gestiti da Docker, memorizzati in `/var/lib/docker/volumes`, e sono portabili tra host. I bind mount mappano direttamente le directory dell'host nei container, utili per lo sviluppo ma dipendenti dall'ambiente. I volumi supportano driver per storage remoto come NFS o block storage cloud. **D: Qual è la differenza tra `docker-compose` e `docker compose`?** Il comando con trattino `docker-compose` era lo strumento standalone V1 basato su Python, ora deprecato. Il comando con spazio `docker compose` è l'implementazione V2 basata su Go integrata nella CLI di Docker. V2 è più veloce, supporta completamente la specifica Compose e riceve sviluppo attivo. ## Debug delle Applicazioni Compose La risoluzione dei problemi nelle applicazioni containerizzate richiede tecniche specifiche. Questi comandi rivelano cosa sta succedendo nello stack Compose: ```bash # Visualizzare i log di tutti i servizi docker compose logs -f # Log di un servizio specifico con timestamp docker compose logs -f --timestamps api # Eseguire comando in un container in esecuzione docker compose exec api sh # Eseguire comando one-off (avvia nuovo container) docker compose run --rm api npm test # Visualizzare utilizzo risorse docker compose top docker stats # Ispezionare configurazione di rete docker network inspect project_backend # Validare file compose docker compose config ``` Il comando `docker compose config` unisce tutti i file compose e mostra la configurazione finale: prezioso per il debug di problemi di interpolazione delle variabili. ## Conclusione - Docker Compose definisce applicazioni multi-container in un singolo file YAML con servizi, reti e volumi - I servizi comunicano via DNS usando i nomi dei servizi come hostname all'interno della rete bridge predefinita - Gli health check con condizioni `service_healthy` assicurano il corretto ordinamento all'avvio - Il file `compose.override.yaml` viene usato per impostazioni specifiche di sviluppo come bind mount e porte di debug - I deployment in produzione beneficiano di limiti di risorse, politiche di riavvio e Docker secrets per dati sensibili - La CLI `docker compose` (V2) sostituisce il deprecato `docker-compose` (V1) con migliori prestazioni e funzionalità --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/it/blog/devops/docker-compose-2026-multi-container-networking-devops-interview