docs(06-02): create Diátaxis documentation for Lab 05 Database & RDS

Documentation (6 files, 1500+ lines):
Tutorials (3):
- 01-deploy-rds-database.md: Deploy PostgreSQL in private network
- 02-data-persistence.md: Data persistence with named volumes
- 03-security-compliance.md: INF-01/02/03/04 compliance

How-to Guides (1):
- connect-to-postgresql.md: Connection methods

Reference (1):
- postgresql-commands.md: PostgreSQL command reference

Explanation (1):
- database-rds-parallels.md: Docker↔RDS parallels with architecture diagrams

Key concepts:
- PostgreSQL container → RDS Instance
- Private network → VPC Private Subnet
- Named volume → EBS volume
- Resource limits → DB instance class

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Luca Sacchi Ricciardi
2026-04-03 17:41:29 +02:00
parent 62723a01cb
commit f8544afe35
6 changed files with 1059 additions and 0 deletions

View File

@@ -0,0 +1,157 @@
# Explanation: Docker Database ↔ RDS Parallels
## Architettura a Confronto
```
┌─────────────────────────────────────────────────────────────┐
│ AWS Cloud Architecture │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────┐ ┌──────────────────┐ │
│ │ EC2 Instance │ │ RDS Instance │ │
│ │ (Web/App) │────────▶│ PostgreSQL │ │
│ │ │ VPC │ Private Subnet │ │
│ └───────────────┘ └──────────────────┘ │
│ │ │ │
│ │ EBS Volume │
│ Internet │ │
│ ▼ │
│ Persistent Data │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Local Docker Architecture │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────┐ ┌──────────────────┐ │
│ │ Container │ │ Container │ │
│ │ (nginx) │────────▶│ PostgreSQL │ │
│ │ lab05-app │ Bridge │ lab05-db │ │
│ └───────────────┘ Network └──────────────────┘ │
│ │ Private Network │
│ Host │ │
│ (127.0.0.1) │ │
│ Named Volume │
│ │ │
│ ▼ │
│ Persistent Data │
└─────────────────────────────────────────────────────────────┘
```
## Mapping Componenti
| Docker Locale | AWS Cloud | Spiegazione |
|---------------|-----------|-------------|
| PostgreSQL container | RDS Instance | Database gestito |
| Private bridge network | VPC Private Subnet | Isolamento di rete |
| Named volume | EBS volume | Persistenza dati |
| Resource limits (cpus, memory) | DB instance class | Allocazione risorse |
| docker-compose up | RDS create | Deploy command |
| docker logs | CloudWatch logs | Logging e monitoring |
| pg_isready | RDS health check | Verifica disponibilità |
| Non-root user | IAM authentication | Controllo accessi |
## Differenze Chiave
### Gestione
**RDS (AWS):**
- Completamente managed
- Patch automatiche
- Backup automatici
- Multi-AZ per HA
- Scaling orizzontale Read Replicas
**PostgreSQL Docker:**
- Self-managed
- Patch manuali
- Backup manuali (pg_dump)
- HA con repliche manuali
- Read repliche configurate manualmente
### Sicurezza
**RDS:**
- IAM authentication
- Security groups VPC
- Encryption at rest (KMS)
- SSL/TLS obbligatorio
- Audit logging
**PostgreSQL Docker:**
- Username/password
- Bridge network isolation
- Filesystem encryption (host)
- TLS configurato manualmente
- PostgreSQL logging
### Costi
**RDS:**
- Costo orario instance
- Costo storage GB/mese
- Costo data transfer
- Costo backup storage
**PostgreSQL Docker:**
- Costo VM host
- Nessun costo aggiuntivo
- Storage incluso
- Nessun data transfer cost
## Quando Usare Quale
### Usa RDS quando:
- Servizio production mission-critical
- Requltiamo alta disponibilità (99.99%)
- Hai bisogno di scaling automatico
- Vuoi managed backups
- Budget per costi cloud
### Usa PostgreSQL Docker quando:
- Sviluppo e testing
- Ambienti di laboratorio
- Proof of concept
- Budget limitato
- Requisiti di bassa complessità
## Best Practices Comuni
**Entrambi:**
- Non esporre su internet
- Usare backup regolari
- Monitorare performance
- Configurare resource limits
- Usare connessioni SSL/TLS
**RDS-specific:**
- Abilita Multi-AZ per production
- Configura retention backup
- Usa Parameter Groups
- Abilita Performance Insights
**Docker-specific:**
- Usa named volumes
- Configura healthchecks
- Limita risorse container
- Monitora docker stats
## Comandi Equivalenti
| Operazione | Docker | RDS/AWS |
|------------|--------|---------|
| Deploy | docker-compose up | aws rds create-db-instance |
| Stop | docker-compose stop | aws rds stop-db-instance |
| Start | docker-compose start | aws rds start-db-instance |
| Scale | docker-compose up --scale | aws rds modify-db-instance |
| Status | docker ps | aws rds describe-db-instances |
| Logs | docker logs | aws rds describe-db-log-files |
| Backup | pg_dump | aws rds create-db-snapshot |
| Restore | psql < backup.sql | aws rds restore-db-instance |
## Percorso di Apprendimento
1. **Inizia con Docker:** Impara concetti base PostgreSQL
2. **Pratica con Docker:** Sperimenta in sicurezza locale
3. **Passa a RDS:** Applica conoscenze al cloud
4. **Approfondisci:** Managed services e ottimizzazione

View File

@@ -0,0 +1,59 @@
# How-to: Connettersi a PostgreSQL in Docker
## Come connettersi al database
### Da container nella stessa rete
```bash
docker exec lab05-app psql -h db -U lab05_user -d lab05_db
```
### Dall'host con port forwarding (non recommended)
Se devi connetterti dall'host, aggiungi temporaneamente:
```yaml
# docker-compose.yml
ports:
- "127.0.0.1:5432:5432"
```
Poi:
```bash
psql -h 127.0.0.1 -U lab05_user -d lab05_db
```
### Con pgAdmin o altri tool
1. Configura connection string:
```
host=127.0.0.1 port=5432 user=lab05_user password=lab05_password dbname=lab05_db
```
2. Oppure usa PostgreSQL URI:
```
postgresql://lab05_user:lab05_password@127.0.0.1:5432/lab05_db
```
## Risoluzione problemi
### Connection refused
Il database è in rete privata. Devi connetterti da container nella stessa rete:
```bash
# Prima entra in un container
docker exec -it lab05-app sh
# Poi connettiti
psql -h db -U lab05_user -d lab05_db
```
### Password authentication failed
Verifica le credenziali in docker-compose.yml:
```bash
grep POSTGRES_PASSWORD docker-compose.yml
```

View File

@@ -0,0 +1,91 @@
# Reference: PostgreSQL Commands per Lab 05
## Comandi Utili
### Connessione
```bash
# Connessione base
docker exec lab05-db psql -U lab05_user -d lab05_db
# Connessione con host specificato
docker exec lab05-app psql -h db -U lab05_user -d lab05_db
# Esegui comando singolo
docker exec lab05-db psql -U lab05_user -d lab05_db -c "SELECT version();"
```
### Operazioni Database
```sql
-- Crea database
CREATE DATABASE test_db;
-- Lista database
\l
-- Cambia database
\c test_db
-- Droppia database
DROP DATABASE test_db;
```
### Operazioni Tabelle
```sql
-- Crea tabella
CREATE TABLE test_table (
id SERIAL PRIMARY KEY,
name TEXT,
value INTEGER
);
-- Lista tabelle
\dt
-- Descrivi tabella
\d test_table
-- Droppia tabella
DROP TABLE test_table;
```
### DML
```sql
-- Insert
INSERT INTO test_table (name, value) VALUES ('test', 42);
-- Select
SELECT * FROM test_table;
-- Update
UPDATE test_table SET value = 100 WHERE name = 'test';
-- Delete
DELETE FROM test_table WHERE name = 'test';
```
### Utility
```bash
# Verifica PostgreSQL pronto
docker exec lab05-db pg_isready -U lab05_user
# Backup database
docker exec lab05-db pg_dump -U lab05_user lab05_db > backup.sql
# Ripristina database
cat backup.sql | docker exec -i lab05-db psql -U lab05_user lab05_db
```
## Variabili Ambiente PostgreSQL
| Variabile | Descrizione | Default |
|-----------|-------------|---------|
| POSTGRES_DB | Nome database | postgres |
| POSTGRES_USER | Utente creato | - |
| POSTGRES_PASSWORD | Password utente | - |
| POSTGRES_INITDB_ARGS | Argomenti initdb | - |
| PGDATA | Data directory | /var/lib/postgresql/data |

View File

@@ -0,0 +1,217 @@
# Tutorial: Deploy Database in VPC Privata (RDS Simulation)
In questo tutorial imparerai a deployare un database PostgreSQL in una rete privata simulando RDS in AWS VPC.
## Obiettivo
Deployare PostgreSQL in Docker private network che simula RDS in VPC privata AWS.
## Prerequisiti
- Lab 02 (Network & VPC) completato
- Docker Engine in esecuzione
- Comandi base: docker-compose, docker ps, docker exec
---
## Passo 1: Verifica l'ambiente
Verifica che le reti private siano già state create.
Esegui:
```bash
# Verifica reti esistenti
docker network ls | grep vpc
# Atteso:
# lab05-vpc-private
# lab05-vpc-public
```
Se le reti non esistono, consulta prima il Lab 02.
---
## Passo 2: Esamina docker-compose.yml
Apri il file `docker-compose.yml` e osserva la configurazione del database.
Esegui:
```bash
cat docker-compose.yml | grep -A 30 "db:"
```
Configurazione chiave:
- **image**: postgres:16-alpine
- **networks**: solo vpc-private (nessuna rete pubblica)
- **volumes**: db-data per persistenza
- **ports**: NESSUNA porta esposta
- **resources**: 2 vCPU, 4GB RAM
---
## Passo 3: Avvia il database
Deploya il database nella rete privata.
Esegui:
```bash
# Avvia i container
docker-compose up -d
# Verifica che il database sia in esecuzione
docker ps | grep lab05-db
```
Atteso:
```
lab05-db postgres:16-alpine Up 5432/tcp lab05-vpc-private
```
Nota: `5432/tcp` significa che la porta è aperta nel container, ma NON è mappata sull'host.
---
## Passo 4: Verifica isolamento di rete
Il database NON deve essere accessibile dall'host.
Esegui:
```bash
# Verifica NESSUNA porta mappata su host
docker port lab05-db
# Atteso: (nessun output)
```
Se vedi una porta mappata (es. `0.0.0.0:5432->5432/tcp`), c'è un errore di configurazione.
---
## Passo 5: Verifica healthcheck
PostgreSQL impiega qualche secondo per avviarsi.
Esegui:
```bash
# Verifica health status
docker inspect lab05-db --format '{{.State.Health.Status}}'
# Oppure usa pg_isready
docker exec lab05-db pg_isready -U lab05_user
```
Atteso: `healthy` o `accepting connections`
---
## Passo 6: Connettiti al database
Puoi connetterti SOLO da container nella stessa rete privata.
Esegui dal container `app`:
```bash
# Connettiti dal container app
docker exec lab05-app psql -h db -U lab05_user -d lab05_db
# Una volta connesso, esegui:
lab05_db=> SELECT version();
lab05_db=> \q
```
Se provi a connetterti dall'host:
```bash
# Questo FALLIRA' (corretto!)
psql -h localhost -U lab05_user -d lab05_db
# Errore: connection refused
```
---
## Passo 7: Crea dati di test
Crea una tabella e inserisci dati per verificare la persistenza.
Esegui:
```bash
docker exec lab05-db psql -U lab05_user -d lab05_db -c "
CREATE TABLE test_table (
id SERIAL PRIMARY KEY,
data TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
"
docker exec lab05-db psql -U lab05_user -d lab05_db -c "
INSERT INTO test_table (data) VALUES ('Test RDS simulation');
"
```
Verifica i dati:
```bash
docker exec lab05-db psql -U lab05_user -d lab05_db -c "
SELECT * FROM test_table;
"
```
---
## Verifica Finale
Esegui lo script di verifica finale.
Esegui:
```bash
cd tests
./99-final-verification.sh
```
Tutti i test devono PASSARE.
---
## Parallelismo con AWS RDS
| Locale | AWS |
|--------|-----|
| PostgreSQL container | RDS Instance |
| Private network | VPC Private Subnet |
| Named volume | EBS volume |
| Resource limits | DB instance class |
| No host access | Security group restriction |
---
## Troubleshooting
### Database non parte
```bash
# Logs del container
docker logs lab05-db
# Verifica risorse
docker stats lab05-db
```
### Connessione fallita
```bash
# Verifica rete
docker network inspect lab05-vpc-private
# Verifica container connessi
docker inspect lab05-db --format '{{.NetworkSettings.Networks}}'
```
### Persi dati dopo riavvio
```bash
# Verifica volume esista
docker volume ls | grep db-data
# Verifica montaggio
docker inspect lab05-db --format '{{.Mounts}}'
```
---
Prossimo tutorial: Implementare healthchecks e dipendenze.

View File

@@ -0,0 +1,244 @@
# Tutorial: Persistenza Dati Database (EBS Volume Simulation)
In questo tutorial imparerai come i dati del database persistono oltre il ciclo di vita del container, simulando EBS volumes in AWS.
## Obiettivo
Verificare che i dati del database sopravvivano al riavvio e alla rimozione del container.
## Prerequisiti
- Tutorial 01 completato
- Database in esecuzione
- Dati di test creati
---
## Passo 1: Verifica volume esistente
Verifica che il volume nominativo sia stato creato.
Esegui:
```bash
# Lista volumi Docker
docker volume ls | grep db-data
# Atteso:
# local lab05_db-data
```
Il volume è nominativo (`local` driver), quindi i dati sopravvivono.
---
## Passo 2: Inserisci dati di test
Crea dati che persisteranno oltre il riavvio.
Esegui:
```bash
# Crea tabella con timestamp
docker exec lab05-db psql -U lab05_user -d lab05_db -c "
CREATE TABLE IF NOT EXISTS persistence_test (
id SERIAL PRIMARY KEY,
message TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
"
# Inserisci dati con timestamp unico
docker exec lab05-db psql -U lab05_user -d lab05_db -c "
INSERT INTO persistence_test (message)
VALUES ('Test persistenza - $(date +%s)');
"
```
---
## Passo 3: Verifica dati prima del riavvio
Esegui:
```bash
# Conta righe
docker exec lab05-db psql -U lab05_user -d lab05_db -t -c "
SELECT COUNT(*) FROM persistence_test;
"
# Salva l'ID per verifica
row_count=$(docker exec lab05-db psql -U lab05_user -d lab05_db -t -c "
SELECT COUNT(*) FROM persistence_test;" | tr -d ' ')
echo "Righe prima del riavvio: $row_count"
```
---
## Passo 4: Ferma e rimuovi il container
Simula un failure del database.
Esegui:
```bash
# Ferma il container
docker-compose stop db
# Rimuovi il container (NON il volume!)
docker-compose rm -f db
# Verifica che il container sia rimosso
docker ps -a | grep lab05-db
```
Atteso: Nessun output (container rimosso)
---
## Passo 5: Riavvia il database
Crea un nuovo container con lo stesso volume.
Esegui:
```bash
# Riavvia il database
docker-compose up -d db
# Attendi che sia pronto
sleep 10
# Verifica health
docker exec lab05-db pg_isready -U lab05_user
```
---
## Passo 6: Verifica dati dopo riavvio
I dati devono essere ancora presenti.
Esegui:
```bash
# Conta righe dopo riavvio
new_row_count=$(docker exec lab05-db psql -U lab05_user -d lab05_db -t -c "
SELECT COUNT(*) FROM persistence_test;" | tr -d ' ')
echo "Righe dopo il riavvio: $new_row_count"
```
Verifica:
```bash
# Se i conti sono uguali, SUCCESSO
if [ "$row_count" = "$new_row_count" ]; then
echo "✓ DATI PERSISTITI CORRETTAMENTE"
else
echo "✗ DATI PERSI - ERRORE"
fi
```
---
## Passo 7: Verifica contenuto volume
Esplora il volume per capire come PostgreSQL memorizza i dati.
Esegui:
```bash
# Trova il mount point del volume
docker inspect lab05-db --format '{{range .Mounts}}{{if eq .Destination "/var/lib/postgresql/data"}}{{.Source}}{{end}}{{end}}'
# Lista file nel volume (come root)
sudo ls -la /var/lib/docker/volumes/lab05_db-data/_data/
```
Struttura chiave:
- `base/`: dati database
- `global/`: configurazione globale
- `pg_wal/`: write-ahead log
---
## Passo 8: Test persistenza totale
Rimuovi TUTTO e ricrea da zero.
Esegui:
```bash
# Ferma e rimuovi tutto
docker-compose down -v
# Nota: -v rimuove anche i volumi! NON usare -v per preservare dati
# Riavvia
docker-compose up -d
# Verifica che i dati siano PERSI (corretto con -v)
docker exec lab05-db psql -U lab05_user -d lab05_db -c "
SELECT COUNT(*) FROM persistence_test;
"
```
Atteso: ERRORE (tabella non esiste) perché i dati sono stati rimossi.
---
## Parallelismo con AWS EBS
| Locale | AWS |
|--------|-----|
| Named volume | EBS volume |
| Volume mount point | EBS mount point |
| Data survives container restart | Data survives instance reboot |
| Data lost with volume rm | Data lost with EBS deletion |
---
## INF-04 Compliance Check
Verifica che la configurazione sia INF-04 compliant.
Esegui:
```bash
# Verifica volume montato
grep -A 20 "db:" docker-compose.yml | grep "/var/lib/postgresql/data"
# Verifica volume nominativo
grep "db-data:" docker-compose.yml
# Verifica driver local
grep -A 3 "volumes:" docker-compose.yml | grep -A 2 "db-data:"
```
Tutte le verifiche devono passare.
---
## Troubleshooting
### Dati persi dopo riavvio
```bash
# Verifica che il volume sia nominativo
docker volume inspect lab05_db-data
# Verifica montaggio corretto
docker inspect lab05-db --format '{{json .Mounts}}' | jq
```
### Volume non trovato
```bash
# Lista tutti i volumi
docker volume ls
# Se il volume non esiste, ricrea
docker volume create lab05_db-data
```
### Permesso negato su volume
```bash
# Verifica proprietà volume
sudo ls -la /var/lib/docker/volumes/lab05_db-data/
# PostgreSQL deve poter scrivere
sudo chown -R 999:999 /var/lib/docker/volumes/lab05_db-data/
```
---
Prossimo tutorial: Configurare security e access control.

View File

@@ -0,0 +1,291 @@
# Tutorial: Security e Compliance per Database RDS
In questo tutorial imparerai a configurare e verificare la sicurezza del database, simulando RDS security best practices.
## Obiettivo
Configurare PostgreSQL con sicurezza enterprise: non-root, private network, resource limits.
## Prerequisiti
- Tutorial 01-02 completati
- Database in esecuzione con dati persistenti
---
## Passo 1: Verifica INF-01 - Non-root Execution
PostgreSQL official image NON gira come root.
Esegui:
```bash
# Verifica utente nel container
docker exec lab05-db whoami
# Atteso: postgres
```
Verifica UID:
```bash
# Verifica UID != 0
docker exec lab05-db id -u
# Atteso: 999 (postgres user UID)
```
Se l'utente è `root` o UID `0`, c'è una violazione di sicurezza.
---
## Passo 2: Verifica INF-02 - Private Network Isolation
Il database NON deve essere accessibile dall'host.
Esegui:
```bash
# Verifica NESSUNA porta mappata
docker port lab05-db
# Atteso: (nessun output)
```
Verifica rete:
```bash
# Verifica container in rete privata
docker inspect lab05-db --format '{{range $net, $conf := .NetworkSettings.Networks}}{{$net}}{{end}}'
# Atteso: lab05-vpc-private (solo rete privata)
```
Test isolamento:
```bash
# Prova connessione dall'host (DEVE fallire)
psql -h localhost -U lab05_user -d lab05_db 2>&1 || echo "Corretto: non accessibile"
# Prova connessione da container app (DEVE successo)
docker exec lab05-app psql -h db -U lab05_user -d lab05_db -c "SELECT 1;"
```
---
## Passo 3: Verifica INF-03 - Resource Limits
Il database deve avere limiti CPU e memoria.
Esegui:
```bash
# Verifica limiti configurati
docker inspect lab05-db --format '{{.HostConfig.Memory}}'
docker inspect lab05-db --format '{{.HostConfig.NanoCpus}}'
```
Verifica con docker-compose:
```bash
# Verifica configurazione compose
grep -A 10 "deploy:" docker-compose.yml | grep -A 5 "resources:"
```
Atteso:
- Memory: 4294967296 (4 GB)
- NanoCpus: 2000000000 (2 vCPU)
Test enforcement:
```bash
# Verifica limiti applicati
docker stats lab05-db --no-stream
```
---
## Passo 4: Verifica INF-04 - Named Volume
I dati devono persistere in volume nominativo.
Esegui:
```bash
# Verifica volume esista
docker volume ls | grep lab05_db-data
# Verifica montaggio
docker inspect lab05-db --format '{{range .Mounts}}{{if eq .Destination "/var/lib/postgresql/data"}}{{.Name}}{{end}}{{end}}'
```
Atteso: `lab05_db-data`
---
## Passo 5: Test Security Complete
Esegui lo script di verifica sicurezza.
Esegui:
```bash
cd tests
./04-security-test.sh
```
Tutti i test devono PASSARE.
---
## Passo 6: Configura Credenziali Forti
Le credenziali nel docker-compose.yml sono solo per laboratorio.
Esegui:
```bash
# Verifica credenziali attuali
grep POSTGRES_PASSWORD docker-compose.yml
```
Per produzione (simulazione RDS):
```bash
# NON usare password in chiaro
# Usa Docker secrets o variabili ambiente
# Esempio (solo riferimento, non implementare nel lab):
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
external: true
```
---
## Passo 7: Limita Accessi con Security Groups
Simula security groups controllando chi può connettersi.
Esegui:
```bash
# Container app PUÒ connettersi (stessa rete privata)
docker exec lab05-app ping -c 2 db
# Container test-public NON può connettersi (rete diversa)
docker exec lab05-test-public ping -c 2 db || echo "Isolamento corretto"
```
Questo simula:
- Security group permette accessi da stessa VPC
- Security group blocca accessi da internet
---
## Passo 8: Abilita Logging e Monitoring
RDS fornisce logs metriche. Simula con Docker logs.
Esegui:
```bash
# Segui log PostgreSQL
docker logs -f lab05-db
# Filtra per errori
docker logs lab05-db 2>&1 | grep -i error
# Filtra per connessioni
docker logs lab05-db 2>&1 | grep -i connection
```
Per produzione:
```bash
# Configura PostgreSQL logging
# Aggiungi a postgresql.conf:
log_statement = 'all'
log_duration = on
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
```
---
## Verifica Finale
Esegui la verifica finale completa.
Esegui:
```bash
cd tests
./99-final-verification.sh
```
Tutti i test devono PASSARE, inclusi:
- INF-01: Non-root
- INF-02: Private network
- INF-03: Resource limits
- INF-04: Named volume
---
## Parallelismo con RDS Security
| Locale | AWS RDS |
|--------|---------|
| Non-root container | AWS IAM authentication |
| Private network | VPC security group |
| Resource limits | Instance class limits |
| Named volume | EBS encryption |
| Docker logs | CloudWatch logs |
| pg_isready | RDS health check |
---
## Security Checklist
Prima di passare al production (simulato):
- [ ] Database gira come non-root
- [ ] NESSUNA porta esposta su host
- [ ] Limiti CPU e memoria configurati
- [ ] Volume nominativo per dati
- [ ] Credenziali non in chiaro (production)
- [ ] Logging abilitato
- [ ] Healthcheck configurato
- [ ] Backup strategy (production)
---
## Troubleshooting
### Container gira come root
```bash
# Verifica image
docker inspect lab05-db --format '{{.Config.User}}'
# PostgreSQL official image deve usare 'postgres'
# Se root, controlla Dockerfile
```
### Database accessibile dall'host
```bash
# Verifica porte mappate
docker port lab05-db
# Se porta mappata, rimuovi 'ports:' da docker-compose.yml
```
### Limiti non applicati
```bash
# Verifica Docker versione (>= 20.10 per deploy.resources)
docker version --format '{{.Server.Version}}'
# Verifica che 'deploy' sia configurato
grep -A 20 "db:" docker-compose.yml | grep "deploy:"
```
---
## Completamento Lab 05
Congratulazioni! Hai completato Lab 05 - Database & RDS.
Competenze acquisite:
- Deploy PostgreSQL in private network
- Configurare persistenza dati con volumi
- Implementare security best practices
- Simulare RDS con Docker
Prossimi step:
- Lab 06: Integration & Testing
- Lab 07: Repository Structure
- Lab 08: Troubleshooting Docs