feat(lab-02): complete Phase 3 - Network & VPC lab

Implement Lab 02 with Docker bridge networks simulating VPC/Subnets.

Test Infrastructure (RED phase):
- 6 bash test scripts for network creation, isolation, INF-02 compliance
- Fail-fast orchestration with run-all-tests.sh
- Quick validation script for development

Documentation (Diátaxis framework):
- 3 tutorials: VPC creation, container deployment, isolation verification
- 4 how-to guides: create network, inspect config, test isolation, cleanup
- 3 reference docs: Docker network commands, Compose syntax, VPC mapping
- 1 explanation: Docker ↔ VPC parallels (PARA-01/02/03/04)

Infrastructure (GREEN phase):
- docker-compose.yml with VPC networks (10.0.1.0/24, 10.0.2.0/24)
- 5 services: web, app, db, test-public, test-private
- INF-02 compliant: 127.0.0.1 bindings only, no 0.0.0.0
- Private network with --internal flag
- Multi-homed app container (public + private networks)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Luca Sacchi Ricciardi
2026-03-25 17:26:35 +01:00
parent d4c4f7d717
commit 5b2c8c37aa
22 changed files with 3988 additions and 12 deletions

View File

@@ -0,0 +1,327 @@
# 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](./01-create-vpc-networks.md)
- Docker Compose V2 installato
---
## Passo 1: Creare la Directory del Lab
Esegui:
```bash
cd ~/laboratori-cloud/labs/lab-02-network
```
---
## Passo 2: Creare docker-compose.yml
Crea il file `docker-compose.yml` con la configurazione multi-tier:
```yaml
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.
---
## Passo 3: Verificare la Configurazione
Verifica che il file YAML sia valido.
Esegui:
```bash
docker compose config
```
Se valido, vedrai la configurazione completa. Se ci sono errori, verranno mostrati qui.
---
## Passo 4: Avviare i Servizi
Esegui:
```bash
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:
```bash
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:
```bash
# Verifica container web nella rete pubblica
docker inspect lab02-web --format '{{range .NetworkSettings.Networks}}{{.IPAddress}} in {{.NetworkID}}{{end}}'
```
Atteso (IP nella subnet pubblica):
```
10.0.1.10 in lab02-vpc-public
```
Esegui:
```bash
# Verifica database nella rete privata
docker inspect lab02-db --format '{{range .NetworkSettings.Networks}}{{.IPAddress}} in {{.NetworkID}}{{end}}'
```
Atteso (IP nella subnet privata):
```
10.0.2.10 in lab02-vpc-private
```
Esegui:
```bash
# Verifica app in entrambe le reti (multi-homed)
docker inspect lab02-app --format '{{range .NetworkSettings.Networks}}{{.IPAddress}} in {{.NetworkID}} | {{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:
```bash
# Test web server
curl http://127.0.0.1:8080
```
Atteso: HTML response da nginx
Esegui:
```bash
# 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:
```bash
# Container web NON puo raggiungere database (reti diverse)
docker exec lab02-web ping -c 2 lab02-db
```
Atteso: FALLISCE (isolamento funzionante)
Esegui:
```bash
# 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](./03-verify-network-isolation.md) imparerai a verificare e testare l'isolamento tra le reti.
---
## Troubleshooting
**Problema: Porta 8080 gia in uso**
Soluzione:
```bash
# Cambia porta nel compose
ports:
- "127.0.0.1:9090:80" # Usa 9090 invece di 8080
```
**Problema: Database non ottiene IP**
Soluzione:
```bash
# 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:
```bash
# Pulisci volumi e ricrea
docker compose down -v
docker compose up -d
```
**Problema: Container non comunicano**
Soluzione:
```bash
# 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
```