525 lines
14 KiB
Markdown
525 lines
14 KiB
Markdown
# Common Container Patterns
|
|
|
|
This document provides reusable architecture patterns for C4 Model Level 2 (Container) analysis with detailed examples.
|
|
|
|
## Pattern 1: Simple SPA + API + Database
|
|
|
|
**Scenario:** Basic web application with frontend, backend, and database
|
|
|
|
**Containers identified:**
|
|
|
|
1. **Frontend SPA Container**
|
|
- Type: `spa`
|
|
- Technology: React 18 + TypeScript
|
|
- Runtime: Browser
|
|
- Communicates with API via HTTP REST
|
|
|
|
2. **Backend API Container**
|
|
- Type: `api`
|
|
- Technology: Express.js + Node.js 18
|
|
- Runtime: Server (Node.js)
|
|
- Communicates with database via PostgreSQL protocol
|
|
|
|
3. **PostgreSQL Database Container**
|
|
- Type: `database`
|
|
- Technology: PostgreSQL 15
|
|
- Runtime: Server (Docker)
|
|
- Stores application data
|
|
|
|
**Architecture:**
|
|
```
|
|
┌──────────────────┐
|
|
│ Browser │
|
|
│ ┌────────────┐ │
|
|
│ │ React SPA │ │
|
|
│ └──────┬─────┘ │
|
|
└─────────┼────────┘
|
|
│ HTTP REST
|
|
▼
|
|
┌─────────────────┐
|
|
│ Server │
|
|
│ ┌────────────┐ │
|
|
│ │ Express API│ │
|
|
│ └──────┬─────┘ │
|
|
└─────────┼───────┘
|
|
│ SQL
|
|
▼
|
|
┌─────────────────┐
|
|
│ ┌────────────┐ │
|
|
│ │PostgreSQL │ │
|
|
│ │ Database │ │
|
|
│ └────────────┘ │
|
|
└─────────────────┘
|
|
```
|
|
|
|
**Detection Commands:**
|
|
```bash
|
|
# Detect pattern
|
|
find . -name "package.json" | grep -E "(frontend|client|web)"
|
|
find . -name "package.json" | grep -E "(backend|server|api)"
|
|
find . -name "docker-compose.yml" | xargs grep postgres
|
|
|
|
# Verify frontend
|
|
cat frontend/package.json | jq '.dependencies | keys | .[]' | grep -E "react|vue|angular"
|
|
|
|
# Verify backend
|
|
cat backend/package.json | jq '.dependencies | keys | .[]' | grep -E "express|fastify|nestjs"
|
|
|
|
# Verify database
|
|
docker-compose config | grep postgres
|
|
```
|
|
|
|
---
|
|
|
|
## Pattern 2: Microservices with API Gateway
|
|
|
|
**Scenario:** Multiple microservices behind API gateway
|
|
|
|
**Containers identified:**
|
|
|
|
1. **API Gateway Container**
|
|
- Type: `web-server`
|
|
- Technology: Nginx or Kong
|
|
- Runtime: Server
|
|
- Routes requests to services
|
|
|
|
2. **Auth Service Container**
|
|
- Type: `api`
|
|
- Technology: NestJS
|
|
- Runtime: Server (Node.js in Docker)
|
|
- Handles authentication
|
|
|
|
3. **User Service Container**
|
|
- Type: `api`
|
|
- Technology: Spring Boot
|
|
- Runtime: Server (JVM in Docker)
|
|
- Manages user data
|
|
|
|
4. **Order Service Container**
|
|
- Type: `api`
|
|
- Technology: FastAPI
|
|
- Runtime: Server (Python in Docker)
|
|
- Processes orders
|
|
|
|
5. **Message Broker Container**
|
|
- Type: `message-broker`
|
|
- Technology: RabbitMQ
|
|
- Runtime: Server (Docker)
|
|
- Event bus
|
|
|
|
6. **Per-Service Databases**
|
|
- Each service has its own database container
|
|
|
|
**Architecture:**
|
|
```
|
|
┌──────────────┐
|
|
│ API Gateway │
|
|
└──────┬───────┘
|
|
│ HTTP
|
|
┌───┴────┬────────┐
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
┌─────┐ ┌──────┐ ┌───────┐
|
|
│Auth │ │User │ │Order │
|
|
│Svc │ │Svc │ │Svc │
|
|
└──┬──┘ └──┬───┘ └───┬───┘
|
|
│ │ │
|
|
└───────┴────┬────┘
|
|
│
|
|
▼
|
|
┌─────────┐
|
|
│RabbitMQ │
|
|
└─────────┘
|
|
```
|
|
|
|
**Detection Commands:**
|
|
```bash
|
|
# Detect microservices pattern
|
|
find . -type d -name "*-service" -o -name "*-api"
|
|
ls services/ | wc -l # Count service directories
|
|
|
|
# Find API gateway
|
|
grep -r "nginx\|kong\|traefik" docker-compose.yml k8s/
|
|
|
|
# Find message broker
|
|
grep -r "rabbitmq\|kafka" docker-compose.yml k8s/
|
|
|
|
# Count services
|
|
find services/ -name "package.json" -o -name "pom.xml" -o -name "requirements.txt" | wc -l
|
|
```
|
|
|
|
---
|
|
|
|
## Pattern 3: Serverless Architecture
|
|
|
|
**Scenario:** Serverless functions with managed services
|
|
|
|
**Containers identified:**
|
|
|
|
1. **Frontend SPA Container**
|
|
- Type: `spa`
|
|
- Deployed to: CloudFront + S3
|
|
- Technology: React
|
|
- Runtime: Browser
|
|
|
|
2. **API Lambda Functions Container(s)**
|
|
- Type: `api`
|
|
- Multiple functions or single function
|
|
- Technology: Node.js Lambda handlers
|
|
- Runtime: AWS Lambda (serverless)
|
|
|
|
3. **DynamoDB Database**
|
|
- Type: `database`
|
|
- Technology: AWS DynamoDB
|
|
- Runtime: AWS managed
|
|
- Fully serverless
|
|
|
|
4. **S3 Storage Container**
|
|
- Type: `file-storage`
|
|
- Technology: AWS S3
|
|
- Runtime: AWS managed
|
|
- Stores uploaded files
|
|
|
|
**Architecture:**
|
|
```
|
|
┌─────────────┐
|
|
│ CloudFront │
|
|
│ + S3 │
|
|
│ (SPA) │
|
|
└──────┬──────┘
|
|
│ HTTP
|
|
▼
|
|
┌─────────────┐
|
|
│ API Gateway │
|
|
└──────┬──────┘
|
|
│
|
|
▼
|
|
┌─────────────┐ ┌──────────┐
|
|
│ Lambda │──────▶ DynamoDB │
|
|
│ Functions │ └──────────┘
|
|
└─────────────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ S3 Bucket │
|
|
└─────────────┘
|
|
```
|
|
|
|
**Detection Commands:**
|
|
```bash
|
|
# Detect serverless pattern
|
|
find . -name "serverless.yml" -o -name "serverless.yaml"
|
|
find . -name "vercel.json" -o -name "netlify.toml"
|
|
find . -name "template.yaml" | xargs grep "AWS::Serverless"
|
|
|
|
# Find Lambda functions
|
|
grep -r "AWS::Serverless::Function\|handler:" serverless.yml
|
|
|
|
# Find DynamoDB tables
|
|
grep -r "DynamoDB\|AWS::DynamoDB" template.yaml
|
|
|
|
# Find S3 usage
|
|
grep -r "S3_BUCKET\|aws-sdk.*s3" .
|
|
```
|
|
|
|
---
|
|
|
|
## Pattern 4: Full-Stack Framework (Next.js/Nuxt)
|
|
|
|
**Scenario:** Single full-stack application with SSR
|
|
|
|
**Containers identified:**
|
|
|
|
1. **Next.js Application Container**
|
|
- Type: `app-server` (full-stack)
|
|
- Technology: Next.js 13
|
|
- Runtime: Server (Node.js)
|
|
- Serves both frontend and API routes
|
|
- **Note:** This is ONE container, not separate frontend/backend
|
|
|
|
2. **Database Container**
|
|
- Type: `database`
|
|
- Technology: PostgreSQL
|
|
- Runtime: Server (Docker)
|
|
|
|
3. **Redis Cache Container**
|
|
- Type: `cache`
|
|
- Technology: Redis
|
|
- Runtime: Server (Docker)
|
|
- Caches SSR pages
|
|
|
|
**Architecture:**
|
|
```
|
|
┌────────────────────┐
|
|
│ Next.js App │
|
|
│ ┌──────────────┐ │
|
|
│ │ SSR + API │ │
|
|
│ │ Routes │ │
|
|
│ └──────┬───────┘ │
|
|
└─────────┼──────────┘
|
|
┌─┴──┐
|
|
│ │
|
|
┌───▼──┐ └──▼─────┐
|
|
│ DB │ │ Redis │
|
|
└──────┘ └───────┘
|
|
```
|
|
|
|
**Detection Commands:**
|
|
```bash
|
|
# Detect Next.js/Nuxt pattern
|
|
grep -r "\"next\":\|\"nuxt\":" package.json
|
|
|
|
# Check for API routes
|
|
find . -type d -name "api" -path "*/pages/api" -o -path "*/app/api"
|
|
|
|
# Check for SSR
|
|
grep -r "getServerSideProps\|getStaticProps" pages/ app/
|
|
|
|
# Verify single application
|
|
[ $(find . -name "package.json" -not -path "*/node_modules/*" | wc -l) -eq 1 ] && echo "Single app"
|
|
```
|
|
|
|
---
|
|
|
|
## Pattern 5: Mobile App + Backend
|
|
|
|
**Scenario:** Mobile application with supporting backend
|
|
|
|
**Containers identified:**
|
|
|
|
1. **Mobile Application Container**
|
|
- Type: `mobile-app`
|
|
- Technology: React Native
|
|
- Runtime: iOS/Android
|
|
- Communicates with API
|
|
|
|
2. **Backend API Container**
|
|
- Type: `api`
|
|
- Technology: Django REST Framework
|
|
- Runtime: Server (Python)
|
|
- Provides mobile API
|
|
|
|
3. **PostgreSQL Database Container**
|
|
- Type: `database`
|
|
- Technology: PostgreSQL
|
|
- Runtime: Server
|
|
|
|
4. **Redis Cache Container**
|
|
- Type: `cache`
|
|
- Technology: Redis
|
|
- Runtime: Server
|
|
- API response caching
|
|
|
|
5. **Push Notification Service Container**
|
|
- Type: `worker`
|
|
- Technology: Custom Python service
|
|
- Runtime: Server
|
|
- Sends push notifications via FCM/APNS
|
|
|
|
**Architecture:**
|
|
```
|
|
┌─────────────────┐
|
|
│ Mobile Device │
|
|
│ ┌─────────────┐ │
|
|
│ │React Native │ │
|
|
│ │ App │ │
|
|
│ └──────┬──────┘ │
|
|
└────────┼────────┘
|
|
│ HTTPS
|
|
▼
|
|
┌────────────────┐ ┌────────┐
|
|
│ Django API │──────▶ Postgres│
|
|
└────────┬───────┘ └────────┘
|
|
│
|
|
┌────┴────┐
|
|
▼ ▼
|
|
┌──────┐ ┌────────┐
|
|
│Redis │ │Push │
|
|
│Cache │ │Service │
|
|
└──────┘ └────────┘
|
|
```
|
|
|
|
**Detection Commands:**
|
|
```bash
|
|
# Detect mobile app
|
|
find . -name "package.json" | xargs grep "react-native\|@ionic\|flutter"
|
|
find . -name "Podfile" -o -name "build.gradle"
|
|
|
|
# Detect backend API
|
|
grep -r "djangorestframework\|flask\|fastapi" requirements.txt
|
|
|
|
# Find push notification service
|
|
grep -r "fcm\|apns\|firebase-admin" . | grep -v node_modules
|
|
```
|
|
|
|
---
|
|
|
|
## Pattern 6: Event-Driven with Workers
|
|
|
|
**Scenario:** Async processing with message queue and workers
|
|
|
|
**Containers identified:**
|
|
|
|
1. **Web Application Container**
|
|
- Type: `spa`
|
|
- Technology: Vue 3
|
|
- Runtime: Browser
|
|
|
|
2. **Backend API Container**
|
|
- Type: `api`
|
|
- Technology: FastAPI
|
|
- Runtime: Server (Python)
|
|
- Publishes events to queue
|
|
|
|
3. **Message Queue Container**
|
|
- Type: `message-broker`
|
|
- Technology: Kafka
|
|
- Runtime: Server (Docker)
|
|
- Event streaming
|
|
|
|
4. **Email Worker Container**
|
|
- Type: `worker`
|
|
- Technology: Celery
|
|
- Runtime: Server (Python)
|
|
- Consumes email events
|
|
|
|
5. **Report Worker Container**
|
|
- Type: `worker`
|
|
- Technology: Celery
|
|
- Runtime: Server (Python)
|
|
- Generates reports
|
|
|
|
6. **Database Container**
|
|
- Type: `database`
|
|
- Technology: PostgreSQL
|
|
- Runtime: Server
|
|
|
|
**Architecture:**
|
|
```
|
|
┌──────┐ ┌─────┐
|
|
│ Vue │───▶│ API │
|
|
│ SPA │ └──┬──┘
|
|
└──────┘ │
|
|
│ publish
|
|
▼
|
|
┌──────────┐
|
|
│ Kafka │
|
|
│ Queue │
|
|
└─────┬────┘
|
|
┌───┴───┐
|
|
subscribe subscribe
|
|
│ │
|
|
┌────▼──┐ ┌─▼──────┐
|
|
│Email │ │Report │
|
|
│Worker │ │Worker │
|
|
└───────┘ └────────┘
|
|
```
|
|
|
|
**Detection Commands:**
|
|
```bash
|
|
# Detect event-driven pattern
|
|
grep -r "celery\|sidekiq\|bull\|bee-queue" requirements.txt package.json Gemfile
|
|
|
|
# Find message brokers
|
|
grep -r "kafka\|rabbitmq\|redis.*pub.*sub" docker-compose.yml
|
|
|
|
# Find worker definitions
|
|
find . -name "*worker*.py" -o -name "*job*.py"
|
|
grep -r "celery.*worker\|worker.*start" .
|
|
```
|
|
|
|
---
|
|
|
|
## Pattern Selection Guide
|
|
|
|
### When to Use Each Pattern
|
|
|
|
| Pattern | Best For | Complexity | Scalability |
|
|
|---------|----------|------------|-------------|
|
|
| Pattern 1: SPA + API + DB | Simple web apps, MVPs | Low | Medium |
|
|
| Pattern 2: Microservices | Large systems, independent teams | High | Very High |
|
|
| Pattern 3: Serverless | Variable load, cost optimization | Medium | Auto-scale |
|
|
| Pattern 4: Full-Stack Framework | Rapid development, SSR needs | Low-Medium | Medium |
|
|
| Pattern 5: Mobile + Backend | Mobile-first apps | Medium | High |
|
|
| Pattern 6: Event-Driven | Async processing, decoupling | Medium-High | Very High |
|
|
|
|
### Mixing Patterns
|
|
|
|
Real-world systems often combine patterns:
|
|
|
|
**Example: E-commerce Platform**
|
|
- Pattern 1: Customer web portal (SPA + API + DB)
|
|
- Pattern 5: Mobile shopping app (Mobile + Backend)
|
|
- Pattern 6: Order processing (Event-driven workers)
|
|
- Pattern 3: Static assets (Serverless CDN)
|
|
|
|
---
|
|
|
|
## Detection Best Practices
|
|
|
|
1. **Start with docker-compose.yml or K8s manifests** - Shows all containers
|
|
2. **Check package manifests** - package.json, requirements.txt, pom.xml
|
|
3. **Look for framework indicators** - next.config.js, serverless.yml
|
|
4. **Examine folder structure** - services/, apps/, packages/
|
|
5. **Review deployment configs** - Dockerfile, K8s deployments
|
|
6. **Check environment variables** - .env files reveal connections
|
|
|
|
## Common Variations
|
|
|
|
### Pattern 1 Variations
|
|
- Add Redis cache → Pattern 1 + Cache
|
|
- Add Nginx proxy → Pattern 1 + Reverse Proxy
|
|
- Add worker → Pattern 1 + Background Jobs
|
|
|
|
### Pattern 2 Variations
|
|
- Per-service databases → Database-per-Service
|
|
- Shared database → Shared-Database (anti-pattern)
|
|
- Service mesh → Add Istio/Linkerd sidecar containers
|
|
|
|
### Pattern 3 Variations
|
|
- Vercel deployment → Vercel Edge Functions
|
|
- Netlify deployment → Netlify Functions
|
|
- Azure → Azure Functions + Cosmos DB
|
|
|
|
### Pattern 4 Variations
|
|
- Monorepo → Multiple Next.js apps
|
|
- Standalone API → Next.js + Separate API
|
|
- Edge runtime → Vercel Edge Runtime
|
|
|
|
---
|
|
|
|
## Anti-Patterns to Avoid
|
|
|
|
1. **Shared Database Across Services**
|
|
- Violates microservices principles
|
|
- Creates tight coupling
|
|
- Makes each service dependent
|
|
|
|
2. **Monolith in Disguise**
|
|
- Multiple "microservices" that all call each other synchronously
|
|
- Should be one container
|
|
|
|
3. **Over-Granular Containers**
|
|
- Breaking down below deployment boundary
|
|
- Example: Separating utility functions into "containers"
|
|
|
|
4. **Missing Infrastructure Containers**
|
|
- Forgetting databases, caches, message brokers
|
|
- Only documenting application containers
|
|
|
|
5. **Generic Container Types**
|
|
- "Node.js App" instead of "Express API Server"
|
|
- "Python Service" instead of "FastAPI API + Celery Worker"
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
After identifying the pattern:
|
|
|
|
1. **Document each container** using container-types-reference.md
|
|
2. **Map communication** using communication-patterns.md
|
|
3. **Capture technology details** using technology-detection-patterns.md
|
|
4. **Add observations** per observation-categories-c2.md
|
|
5. **Validate** using melly-validation scripts
|