Files
laboratori-cloud/labs/lab-02-network/tutorial/02-deploy-containers-networks.md
Luca Sacchi Ricciardi 5b2c8c37aa 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>
2026-03-25 17:26:35 +01:00

7.1 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


Passo 1: Creare la Directory del Lab

Esegui:

cd ~/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.


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

Esegui:

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 .NetworkSettings.Networks}}{{.IPAddress}} in {{.NetworkID}}{{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 .NetworkSettings.Networks}}{{.IPAddress}} in {{.NetworkID}}{{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 .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:

# 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