# 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*