7.6 KiB
Tutorial: Distribuire Container in Reti VPC
In questo tutorial imparerai a distribuire container multi-tier usando docker-compose.yml, posizionando i servizi nelle reti VPC appropriate seguendo il principio della sicurezza a livelli.
Obiettivo
Creare un'architettura multi-tier con docker-compose:
- Web Server: nella rete pubblica (accessibile da localhost)
- Database: nella rete privata (isolato)
Prerequisiti
- Completato Tutorial 1: Creare Reti VPC
- Docker Compose V2 installato
Passo 1: Creare la Directory del Lab
Esegui:
cd /home/luca/laboratori-cloud/labs/lab-02-network
Passo 2: Creare docker-compose.yml
Crea il file docker-compose.yml con la configurazione multi-tier:
services:
# Web server - rete pubblica
web:
image: nginx:alpine
container_name: lab02-web
networks:
vpc-public:
ipv4_address: 10.0.1.10
ports:
- "127.0.0.1:8080:80" # INF-02 compliant: solo localhost
restart: unless-stopped
# Database - rete privata
db:
image: postgres:16-alpine
container_name: lab02-db
environment:
POSTGRES_PASSWORD: lab02_password
POSTGRES_DB: lab02_db
networks:
vpc-private:
ipv4_address: 10.0.2.10
# Nessuna porta esposta - privato
volumes:
- db-data:/var/lib/postgresql/data
restart: unless-stopped
# Application - entrambe le reti
app:
image: nginx:alpine
container_name: lab02-app
networks:
vpc-public:
ipv4_address: 10.0.1.20
vpc-private:
ipv4_address: 10.0.2.20
ports:
- "127.0.0.1:8081:80"
restart: unless-stopped
networks:
vpc-public:
driver: bridge
name: lab02-vpc-public
ipam:
driver: default
config:
- subnet: 10.0.1.0/24
gateway: 10.0.1.1
vpc-private:
driver: bridge
name: lab02-vpc-private
internal: true
ipam:
driver: default
config:
- subnet: 10.0.2.0/24
gateway: 10.0.2.1
volumes:
db-data:
Salva il file.
Nota: in questo repository il file docker-compose.yml esiste gia. Puoi confrontare il tuo file con quello presente oppure usare direttamente quello del lab.
Passo 3: Verificare la Configurazione
Verifica che il file YAML sia valido.
Esegui:
docker compose config
Se valido, vedrai la configurazione completa. Se ci sono errori, verranno mostrati qui.
Passo 4: Avviare i Servizi
Se nel tutorial 1 hai creato le reti manualmente con gli stessi nomi, rimuovile prima di questo comando. Altrimenti docker compose up -d fallisce per conflitto di ownership/label delle reti.
Esegui:
docker network rm lab02-vpc-public lab02-vpc-private 2>/dev/null || true
docker compose up -d
Atteso:
[+] Running 4/4
✔ Network lab02-vpc-public Created
✔ Network lab02-vpc-private Created
✔ Container lab02-db Started
✔ Container lab02-web Started
✔ Container lab02-app Started
Passo 5: Verificare lo Stato dei Servizi
Esegui:
docker compose ps
Atteso:
NAME IMAGE STATUS
lab02-app nginx:alpine Up
lab02-db postgres:16-alpine Up
lab02-web nginx:alpine Up
Passo 6: Verificare il Posizionamento nelle Reti
Esegui:
# Verifica container web nella rete pubblica
docker inspect lab02-web --format '{{range $k, $v := .NetworkSettings.Networks}}{{$v.IPAddress}} in {{$k}}{{end}}'
Atteso (IP nella subnet pubblica):
10.0.1.10 in lab02-vpc-public
Esegui:
# Verifica database nella rete privata
docker inspect lab02-db --format '{{range $k, $v := .NetworkSettings.Networks}}{{$v.IPAddress}} in {{$k}}{{end}}'
Atteso (IP nella subnet privata):
10.0.2.10 in lab02-vpc-private
Esegui:
# Verifica app in entrambe le reti (multi-homed)
docker inspect lab02-app --format '{{range $k, $v := .NetworkSettings.Networks}}{{$v.IPAddress}} in {{$k}} | {{end}}'
Atteso:
10.0.1.20 in lab02-vpc-public | 10.0.2.20 in lab02-vpc-private
Passo 7: Testare l'Accesso
Il web server e l'app sono accessibili da localhost (INF-02 compliant).
Esegui:
# Test web server
curl http://127.0.0.1:8080
Atteso: HTML response da nginx
Esegui:
# Test app
curl http://127.0.0.1:8081
Il database NON e accessibile dall'host (corretto - privato).
Passo 8: Verificare l'Isolamento
Verifica che il database sia davvero isolato.
Esegui:
# Container web NON puo raggiungere database (reti diverse)
docker exec lab02-web ping -c 2 lab02-db
Atteso: FALLISCE (isolamento funzionante)
Esegui:
# Container app PUO raggiungere il database (connesso a entrambe)
docker exec lab02-app ping -c 2 lab02-db
Atteso: SUCCESSO (app fa da ponte)
Architettura Multi-Tier
┌─────────────────┐
│ Host (127.0.0.1) │
└────────┬────────┘
│ 8080, 8081
┌────────▼────────┐
│ vpc-public │
│ 10.0.1.0/24 │
└────────┬────────┘
│
┌──────────────┼──────────────┐
│ │ │
┌─────▼─────┐ ┌────▼────┐ ┌──────▼──────┐
│ web │ │ app │ │ (isolated) │
│ 10.0.1.10 │ │10.0.1.20│ │ │
└───────────┘ └────┬────┘ └──────────────┘
│
┌──────▼────────┐
│ vpc-private │
│ 10.0.2.0/24 │
└──────┬────────┘
│
┌──────▼─────┐
│ db │
│ 10.0.2.10 │
└────────────┘
Verifica
Hai completato questo tutorial quando:
- docker-compose.yml creato con 3 servizi
- Tutti i container sono in esecuzione
- Web e app sono accessibili da localhost
- Database e nella rete privata (non accessibile dall'host)
- App e connessa a entrambe le reti (multi-homed)
Prossimo Passo
Nel prossimo tutorial imparerai a verificare e testare l'isolamento tra le reti.
Troubleshooting
Problema: Porta 8080 gia in uso
Soluzione:
# Cambia porta nel compose
ports:
- "127.0.0.1:9090:80" # Usa 9090 invece di 8080
Problema: Database non ottiene IP
Soluzione:
# Verifica configurazione IPAM
docker compose down
docker compose up -d
docker inspect lab02-db --format '{{json .NetworkSettings.Networks}}'
Problema: ERROR: for lab02-db Cannot create container
Soluzione:
# Pulisci volumi e ricrea
docker compose down -v
docker compose up -d
Problema: Container non comunicano
Soluzione:
# Verifica che siano nella stessa rete
docker inspect lab02-web --format '{{json .NetworkSettings.Networks}}'
docker inspect lab02-db --format '{{json .NetworkSettings.Networks}}'
# Devono condividere almeno una rete