409 lines
18 KiB
Markdown
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*
|