docs: complete project research
This commit is contained in:
408
.planning/research/ARCHITECTURE.md
Normal file
408
.planning/research/ARCHITECTURE.md
Normal file
@@ -0,0 +1,408 @@
|
||||
# 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*
|
||||
Reference in New Issue
Block a user