Files
laboratori-cloud/.planning/research/ARCHITECTURE.md
2026-03-24 19:26:48 +01:00

409 lines
18 KiB
Markdown

# Architecture Patterns
**Domain:** Docker-based Cloud Lab Environments for Education
**Researched:** 2026-03-24
**Confidence:** HIGH
## Recommended Architecture
```
┌─────────────────────────────────────────────────────────────────────┐
│ Docker Host System │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Student/Developer Interface │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Terminal/SSH │ │ Browser │ │ Git Client │ │ │
│ │ │ (docker cli) │ │ (Web Console)│ │ (Versioning) │ │ │
│ │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ │
│ └─────────┼─────────────────┼─────────────────┼─────────────────┘ │
├────────────┼─────────────────┼─────────────────┼─────────────────────┤
│ │ │ │ │
│ ┌─────────▼─────────────────▼─────────────────▼─────────────────┐ │
│ │ Docker Engine (v24.0+) │ │
│ │ Container Orchestration │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────┼───────────────────────────────────┐ │
│ │ │ │ │
│ │ ┌────────────────────────▼─────────────────────────────┐ │ │
│ │ │ Docker Compose (Project Level) │ │ │
│ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │ │ │
│ │ │ │ Lab 1 │ │ Lab 2 │ │ Lab 3 │ │ Lab 4 │ │ │ │
│ │ │ │ IAM │ │ Network │ │ Compute │ │Storage │ │ │ │
│ │ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └───┬────┘ │ │ │
│ │ └───────┼─────────────┼─────────────┼─────────────┼──────┘ │ │
│ └──────────┼─────────────┼─────────────┼─────────────┼───────────┘ │
│ │ │ │ │ │
│ ┌──────────▼─────────────▼─────────────▼─────────────▼───────────┐ │
│ │ Docker Networks Layer │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ Public Network │ │ Private Net 1 │ │ Private Net 2 │ │ │
│ │ │ (bridge) │ │ (isolated) │ │ (isolated) │ │ │
│ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────▼───────────────────────────────────┐ │
│ │ Storage Layer │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │
│ │ │ Named Volume │ │ Named Volume │ │ Bind Mounts │ │ │
│ │ │ (Block) │ │ (Object) │ │ (Config/Scripts) │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
```
### Component Boundaries
| Component | Responsibility | Communicates With |
|-----------|---------------|-------------------|
| **Docker Engine** | Container lifecycle, image management, network isolation | Docker CLI, Docker Compose |
| **Docker Compose** | Multi-container orchestration per lab, service dependencies | Docker Engine, docker-compose.yml files |
| **Bridge Networks** | VPC/Subnet simulation, network isolation, DNS resolution | Containers within same network only |
| **Named Volumes** | Persistent data storage (DB, Object Storage), data isolation | Containers mounting specific volumes |
| **Test Containers** | Network connectivity verification, service health checks | Target services via internal DNS |
| **Student Workspace** | Git repo, lab documentation, test scripts | Docker CLI via socket |
### Data Flow
**1. Lab Initialization:**
```
Student → git checkout lab-XX-network
Student → docker compose up -d
Docker Compose → Parse compose.yml
Docker Engine → Create networks (public, private-a, private-b)
Docker Engine → Create volumes (data-b, logs)
Docker Engine → Start containers (attach to networks)
Containers → Internal DNS resolution (service names)
```
**2. Cross-Network Communication (VPC Simulation):**
```
Container A (Public Net) → curl http://backend:8080
Docker Internal DNS → Resolve backend to 10.0.1.2
Network Layer → Check routing table
[Different networks] → REJECT (no route)
[Same network] → Allow → Container B receives request
```
**3. Persistent Storage Flow:**
```
Container (PostgreSQL) → Write to /var/lib/postgresql/data
Volume Mount (named volume: db-data)
Docker Volume Driver → Store in /var/lib/docker/volumes/db-data/_data
Container restart → Data persists
docker compose down -v → Volume removed
```
## Patterns to Follow
### Pattern 1: Network Isolation for VPC Simulation
**What:** Use multiple bridge networks to simulate VPC public/private subnets. Containers in different networks cannot communicate unless explicitly connected.
**When:** All network labs, security isolation demonstrations, multi-tier applications.
**Example:**
```yaml
# docker-compose.yml
networks:
public-subnet:
driver: bridge
ipam:
config:
- subnet: 10.0.1.0/24
private-subnet:
driver: bridge
internal: true # No internet access
ipam:
config:
- subnet: 10.0.2.0/24
services:
web-server:
networks:
- public-subnet
- private-subnet # Can talk to both
database:
networks:
- private-subnet # Only private
```
### Pattern 2: Resource Limits for Compute Quota
**What:** Enforce CPU and memory limits at container level to simulate cloud instance sizes (t3.micro, t3.small, etc.).
**When:** Compute labs, performance testing, resource isolation demos.
**Example:**
```yaml
services:
app-tier:
deploy:
resources:
limits:
cpus: '0.5' # 0.5 vCPU = t3.micro equivalent
memory: 512M # 512MB RAM
reservations:
cpus: '0.25'
memory: 256M
```
### Pattern 3: Healthcheck for Service Readiness
**What:** Use built-in HEALTHCHECK directive to ensure services are ready before dependent containers start.
**When:** Multi-tier applications, database-dependent services, testing labs.
**Example:**
```yaml
services:
postgres:
healthcheck:
test: ["CMD", "pg_isready", "-U", "admin"]
interval: 5s
timeout: 3s
retries: 5
app:
depends_on:
postgres:
condition: service_healthy
```
### Pattern 4: Volume Initialization with Seed Data
**What:** Use init containers or volume pre-population to create databases with initial schema/data.
**When:** Database labs, storage testing, demonstration environments.
**Example:**
```yaml
services:
db-init:
image: postgres:15
volumes:
- db-data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
environment:
POSTGRES_DB: labdb
POSTGRES_USER: admin
POSTGRES_PASSWORD: secret
```
### Pattern 5: Test Container Pattern
**What:** Create lightweight "probe" containers to verify network isolation and connectivity.
**When:** Network labs, security testing, isolation verification.
**Example:**
```yaml
# test-connectivity.yml
services:
probe-public:
image: nicolaka/netshoot
networks:
- public-subnet
command: |
sh -c "nc -zv web-server 80 &&
nc -zv minio 9000 &&
! nc -zv database 5432" # Should fail
```
## Anti-Patterns to Avoid
### Anti-Pattern 1: Using Default Bridge Network
**What:** Not defining custom networks, letting containers use the default `bridge` network.
**Why bad:** Containers communicate without restriction, no DNS resolution by name, poor security simulation.
**Instead:** Always create named bridge networks with explicit subnets.
### Anti-Pattern 2: Running Containers as Root
**What:** Not specifying `user:` directive in Dockerfile or compose file.
**Why bad:** Security vulnerability, violates cloud best practices (no root in production).
**Instead:** Use `user: "1000:1000"` or create users in Dockerfile.
### Anti-Pattern 3: Exposing All Ports to Host
**What:** Using `ports: ["8080:8080"]` for all services.
**Why bad:** Port conflicts, security exposure, breaks isolation simulation.
**Instead:** Only expose public-facing services. Use internal networking for backend.
### Anti-Pattern 4: Anonymous Volumes for Persistent Data
**What:** Letting Docker create anonymous volumes without naming.
**Why bad:** Difficult to manage, can't backup easily, hard to reference.
**Instead:** Always use named volumes in compose file.
### Anti-Pattern 5: No Resource Limits
**What:** Running containers without CPU/memory constraints.
**Why bad:** No cloud quota simulation, one container can starve others, unrealistic behavior.
**Instead:** Always set limits matching simulated instance sizes.
## Scalability Considerations
| Concern | Single Student Lab | Classroom (20 students) | Online Course (1000+) |
|---------|-------------------|-------------------------|----------------------|
| **Docker Daemon** | Single instance sufficient | Local daemon per machine | Consider Docker-in-Docker or VMs |
| **Network Overhead** | Negligible | < 50 networks per host | Use network cleanup between labs |
| **Storage** | Named volumes on host | Same, per student machine | Cloud storage for container images |
| **Resource Limits** | Not critical | Important to prevent host OOM | Enforce quotas via Docker daemon limits |
### Build Order Implications
**Phase 1: Foundation (Prerequisites)**
1. Docker Engine + Docker Compose installation
2. Base network setup (public/private networks)
3. Volume structure creation
**Phase 2: IAM & Security (Lab 1)**
- Independent, can run parallel
- No dependencies on other labs
- Tests: user permissions, Docker socket access
**Phase 3: Network (Lab 2)**
- Depends on: Docker Engine understanding
- Enables: All subsequent labs
- Tests: Network isolation, DNS resolution
**Phase 4: Compute (Lab 3)**
- Depends on: Network (for service communication)
- Enables: Multi-tier applications
- Tests: Resource limits, health checks
**Phase 5: Storage (Lab 4)**
- Depends on: Network (for access patterns)
- Independent from: Compute
- Tests: Volume persistence, permissions
**Phase 6: Database (Lab 5)**
- Depends on: Network (VPC simulation), Storage (volumes)
- Culmination: Multi-tier architecture
- Tests: Cross-network communication, persistence
## Lab Environment Structure
### Recommended Directory Layout
```
laboratori-cloud/
├── .planning/ # Project planning
│ ├── PROJECT.md # Project requirements
│ └── research/ # Research documents
├── labs/ # Individual labs
│ ├── lab-01-iam/
│ │ ├── docker-compose.yml
│ │ ├── README.md # Tutorial
│ │ ├── how-to/ # How-to guides
│ │ ├── reference/ # Technical specs
│ │ ├── tests/ # Test scripts
│ │ │ ├── test-iam-setup.sh
│ │ │ └── verify-permissions.sh
│ │ └── docs/ # Explanation documents
│ ├── lab-02-network/
│ │ ├── docker-compose.yml
│ │ ├── networks.yml # Network definitions
│ │ ├── README.md
│ │ ├── tests/
│ │ │ ├── test-isolation.sh
│ │ │ └── test-routing.sh
│ │ └── docs/
│ ├── lab-03-compute/
│ │ ├── docker-compose.yml
│ │ ├── Dockerfile # Custom image
│ │ ├── README.md
│ │ ├── tests/
│ │ │ ├── test-resources.sh
│ │ │ └── test-oom.sh
│ │ └── docs/
│ ├── lab-04-storage/
│ │ ├── docker-compose.yml
│ │ ├── README.md
│ │ ├── tests/
│ │ │ ├── test-volumes.sh
│ │ │ └── test-minio.sh
│ │ └── docs/
│ └── lab-05-database/
│ ├── docker-compose.yml
│ ├── init.sql
│ ├── README.md
│ ├── tests/
│ │ ├── test-connectivity.sh
│ │ └── test-persistence.sh
│ └── docs/
├── shared/ # Shared resources
│ ├── base-images/ # Custom base images
│ ├── test-utils/ # Common test utilities
│ └── monitoring/ # Optional monitoring tools
├── ARCHITECTURE.md # This document
├── CLAUDE.md # Development manifesto
└── PRD.md # Product requirements
```
## Security Architecture
### Isolation Layers
1. **Host Level:** User namespaces, AppArmor profiles
2. **Network Level:** Bridge networks, iptables rules
3. **Container Level:** Non-root users, read-only filesystems
4. **Resource Level:** CPU/memory limits, disk quotas
### Authentication Simulation
```
Local IAM (Lab 1) Cloud IAM (Parallel)
├── Linux users ├── AWS IAM Users
├── Unix groups ├── IAM Groups
├── Docker socket permissions ├── IAM Roles
└── SSH key pairs ├── Access Keys
```
## Sources
### HIGH Confidence (Official Documentation)
- Docker Networking Documentation - https://docs.docker.com/engine/network/ - Bridge networks, internal networks, DNS resolution
- Docker Compose Documentation - https://docs.docker.com/compose/ - Multi-container orchestration, service dependencies
- Docker Storage Documentation - https://docs.docker.com/storage/volumes/ - Named volumes, bind mounts, data persistence
- MinIO Documentation - https://min.io/docs/minio/linux/index.html - S3-compatible object storage for local simulation
### MEDIUM Confidence (Best Practices)
- Docker Security Best Practices - Container hardening, user namespaces
- Cloud Lab Environment Patterns - Educational infrastructure simulation
- Multi-stage Docker Builds - Image optimization for labs
### Project Context
- .planning/PROJECT.md - Project requirements and lab structure
- laboratori-cloud/prd.md - Detailed lab specifications and learning objectives
---
*Architecture research for: Docker-based Cloud Lab Environments*
*Researched: 2026-03-24*