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

18 KiB

Architecture Patterns

Domain: Docker-based Cloud Lab Environments for Education Researched: 2026-03-24 Confidence: HIGH

┌─────────────────────────────────────────────────────────────────────┐
│                         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:

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

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:

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:

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:

# 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

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)

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