AgentSkillsCN

local-alternatives

云服务本地化替代方案参考指南。架构师可借此规划适配器模式,实现在无需云端部署的情况下,支持本地运行与端到端测试。

SKILL.md
--- frontmatter
name: local-alternatives
description: "Reference guide for local development alternatives to cloud services. Used by architects to plan adapter patterns enabling local execution and E2E testing without cloud deployment."

Local Alternatives for Cloud Services

This skill provides guidance on selecting local alternatives for cloud services, enabling:

  • Local development without cloud dependencies
  • E2E testing without deployment
  • Consistent interfaces via adapter patterns

Core Principle: Repository Pattern with Adapters

All cloud service integrations MUST use the Repository/Adapter Pattern:

code
┌─────────────────┐
│  Business Logic │
└────────┬────────┘
         │ uses
         ▼
┌─────────────────┐
│    Interface    │  ← Defined in specs
└────────┬────────┘
         │ implemented by
    ┌────┴────┐
    ▼         ▼
┌───────┐ ┌───────┐
│ Cloud │ │ Local │
│Adapter│ │Adapter│
└───────┘ └───────┘

Key Requirements:

  1. Define interface contracts in .specs/interfaces/
  2. Cloud adapter for production
  3. Local adapter for LOCAL_RUN=true mode
  4. Adapter selection via environment variable or configuration

Service Categories & Local Alternatives

1. Message Queues

Cloud ServiceLocal AlternativeDocker ImageNotes
AWS SQSRabbitMQrabbitmq:3-managementUse AMQP protocol
Azure Service BusRabbitMQrabbitmq:3-managementOr use Azurite (limited)
Google Cloud Pub/SubRabbitMQrabbitmq:3-managementOr use emulator
AWS SNS + SQSRabbitMQ + Exchangerabbitmq:3-managementFan-out via exchanges

Interface Pattern:

code
MessageQueue:
  - publish(topic: string, message: Message): Promise<void>
  - subscribe(topic: string, handler: MessageHandler): Subscription
  - acknowledge(messageId: string): Promise<void>

Adapter Selection:

  • LOCAL_RUN=true → RabbitMQ adapter (localhost:5672)
  • LOCAL_RUN=false → Cloud adapter (SQS/Service Bus/Pub/Sub)

2. Object/Blob Storage

Cloud ServiceLocal AlternativeDocker ImageNotes
AWS S3MinIOminio/minioS3-compatible API
Azure Blob StorageAzuritemcr.microsoft.com/azure-storage/azuriteFull emulation
Google Cloud StorageMinIOminio/minioOr fake-gcs-server

Interface Pattern:

code
ObjectStorage:
  - upload(bucket: string, key: string, data: Buffer): Promise<string>
  - download(bucket: string, key: string): Promise<Buffer>
  - delete(bucket: string, key: string): Promise<void>
  - getSignedUrl(bucket: string, key: string, expiry: number): Promise<string>
  - list(bucket: string, prefix?: string): Promise<ObjectMetadata[]>

Adapter Selection:

  • LOCAL_RUN=true → MinIO adapter (localhost:9000)
  • LOCAL_RUN=false → Cloud adapter (S3/Blob/GCS)

3. Relational Databases

Cloud ServiceLocal AlternativeDocker ImageNotes
AWS RDS PostgreSQLPostgreSQLpostgres:15Direct compatibility
Azure Database PostgreSQLPostgreSQLpostgres:15Direct compatibility
AWS RDS MySQLMySQLmysql:8Direct compatibility
Azure SQLSQL Servermcr.microsoft.com/mssql/serverOr PostgreSQL
Google Cloud SQLPostgreSQL/MySQLpostgres:15Direct compatibility

Interface Pattern:

code
Database:
  - query(sql: string, params: any[]): Promise<Result>
  - transaction(fn: (tx: Transaction) => Promise<T>): Promise<T>
  - healthCheck(): Promise<boolean>

Note: Use same database engine locally - no adapter needed if using standard SQL. Use environment variables for connection strings.


4. NoSQL Databases

Cloud ServiceLocal AlternativeDocker ImageNotes
AWS DynamoDBDynamoDB Localamazon/dynamodb-localOfficial emulator
Azure Cosmos DBCosmos DB EmulatorWindows only, or use MongoDBLimited Linux support
MongoDB AtlasMongoDBmongo:6Direct compatibility
Google FirestoreFirestore Emulatorgcr.io/google.com/cloudsdktool/cloud-sdkVia gcloud
Redis (ElastiCache)Redisredis:7Direct compatibility

Interface Pattern:

code
DocumentStore:
  - get(collection: string, id: string): Promise<Document | null>
  - put(collection: string, id: string, document: Document): Promise<void>
  - delete(collection: string, id: string): Promise<void>
  - query(collection: string, filter: Filter): Promise<Document[]>

5. Notification Services

Cloud ServiceLocal AlternativeDocker ImageNotes
AWS SNSRabbitMQ (fanout)rabbitmq:3-managementExchange pattern
Azure Event GridRabbitMQrabbitmq:3-managementTopic exchanges
SendGrid/SES (Email)MailHogmailhog/mailhogEmail capture
Twilio (SMS)Mock serviceCustomLog to console/file

Interface Pattern:

code
NotificationService:
  - sendEmail(to: string[], subject: string, body: string): Promise<void>
  - sendSms(to: string, message: string): Promise<void>
  - publishEvent(topic: string, event: Event): Promise<void>

Adapter Selection:

  • LOCAL_RUN=true → MailHog (email), Console logger (SMS), RabbitMQ (events)
  • LOCAL_RUN=false → Cloud services

6. Authentication/Identity

Cloud ServiceLocal AlternativeDocker ImageNotes
AWS CognitoKeycloakquay.io/keycloak/keycloakFull OIDC support
Azure AD B2CKeycloakquay.io/keycloak/keycloakOr mock JWT
Auth0Keycloakquay.io/keycloak/keycloakOIDC compatible
Firebase AuthKeycloakquay.io/keycloak/keycloakOr emulator

Interface Pattern:

code
AuthService:
  - validateToken(token: string): Promise<TokenPayload>
  - getUserInfo(userId: string): Promise<UserInfo>
  - hasPermission(userId: string, permission: string): Promise<boolean>

Local Simplification: For E2E testing, LOCAL_RUN=true can use a simplified auth that:

  • Accepts predefined test tokens
  • Returns mock user data
  • Bypasses real authentication (see local-setup skill)

7. Secrets Management

Cloud ServiceLocal AlternativeDocker ImageNotes
AWS Secrets ManagerLocal .envN/AOr HashiCorp Vault
Azure Key VaultLocal .envN/AOr HashiCorp Vault
Google Secret ManagerLocal .envN/AOr HashiCorp Vault
HashiCorp VaultVault Dev Modevault:latestvault server -dev

Interface Pattern:

code
SecretsManager:
  - getSecret(name: string): Promise<string>
  - setSecret(name: string, value: string): Promise<void>

Adapter Selection:

  • LOCAL_RUN=true → Environment variables or .env file
  • LOCAL_RUN=false → Cloud secrets manager

8. Serverless Functions / Event Triggers

Cloud ServiceLocal AlternativeNotes
AWS LambdaLocal HTTP serverExpress/FastAPI endpoint
Azure FunctionsLocal HTTP serverOr func start
Google Cloud FunctionsLocal HTTP serverOr Functions Framework

Adapter Pattern:

  • Extract business logic into testable modules
  • Thin handler wrapper for cloud-specific triggers
  • Local: HTTP endpoint calling same business logic
  • Cloud: Lambda/Function handler calling same business logic

9. Search Services

Cloud ServiceLocal AlternativeDocker ImageNotes
AWS OpenSearchOpenSearchopensearchproject/opensearch:2Direct compatibility
Azure Cognitive SearchOpenSearchopensearchproject/opensearch:2Similar API
Elasticsearch ServiceElasticsearchelasticsearch:8Direct compatibility
AlgoliaMeiliSearchgetmeili/meilisearchSimilar features

Interface Pattern:

code
SearchService:
  - index(collection: string, id: string, document: Document): Promise<void>
  - search(collection: string, query: SearchQuery): Promise<SearchResult>
  - delete(collection: string, id: string): Promise<void>

10. Caching

Cloud ServiceLocal AlternativeDocker ImageNotes
AWS ElastiCache (Redis)Redisredis:7Direct compatibility
Azure Cache for RedisRedisredis:7Direct compatibility
MemorystoreRedisredis:7Direct compatibility

Interface Pattern:

code
CacheService:
  - get(key: string): Promise<T | null>
  - set(key: string, value: T, ttl?: number): Promise<void>
  - delete(key: string): Promise<void>
  - exists(key: string): Promise<boolean>

Architecture Specification Template

When architects specify services, they MUST include adapter requirements:

markdown
## External Service: {Service Name}

### Purpose
{What this service does}

### Cloud Implementation
| Aspect | Value |
|--------|-------|
| **Provider** | {AWS/Azure/GCP} |
| **Service** | {Service name} |
| **Configuration** | {Key config} |

### Local Implementation
| Aspect | Value |
|--------|-------|
| **Alternative** | {Local service} |
| **Docker Image** | {image:tag} |
| **Port** | {port} |
| **Configuration** | {Key config} |

### Interface Contract
See: [{interface-name}](../interfaces/{interface-name}.md)

### Adapter Selection
| Environment | Adapter | Connection |
|-------------|---------|------------|
| Production | {CloudAdapter} | {connection string} |
| Local (LOCAL_RUN=true) | {LocalAdapter} | localhost:{port} |

### Data Consistency
- Schema: {Same/Compatible/Mapped}
- Message Format: {JSON/Protobuf/etc}
- Serialization: {Same across adapters}

Docker Compose Template for Local Services

Architects should reference this in .specs/deployment/local-services.md:

yaml
version: '3.8'

services:
  # Message Queue
  rabbitmq:
    image: rabbitmq:3-management
    ports:
      - "5672:5672"   # AMQP
      - "15672:15672" # Management UI
    environment:
      RABBITMQ_DEFAULT_USER: local
      RABBITMQ_DEFAULT_PASS: local

  # Object Storage
  minio:
    image: minio/minio
    ports:
      - "9000:9000"
      - "9001:9001"
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: minioadmin

  # Database
  postgres:
    image: postgres:15
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: local
      POSTGRES_PASSWORD: local
      POSTGRES_DB: app

  # Cache
  redis:
    image: redis:7
    ports:
      - "6379:6379"

  # Email Testing
  mailhog:
    image: mailhog/mailhog
    ports:
      - "1025:1025"  # SMTP
      - "8025:8025"  # Web UI

  # Identity (if needed)
  keycloak:
    image: quay.io/keycloak/keycloak
    ports:
      - "8080:8080"
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
    command: start-dev

Checklist for Architects

When specifying external service integrations:

  • Interface contract defined in .specs/interfaces/
  • Cloud service documented with configuration
  • Local alternative identified from this guide
  • Docker image and port specified
  • Adapter selection logic documented (LOCAL_RUN flag)
  • Data format consistency ensured (same schemas)
  • Connection string patterns documented for both environments
  • Added to .specs/deployment/local-services.md

Integration with Local Setup

The local-setup-configurator agent will:

  1. Read adapter specifications from container .specs/
  2. Generate docker-compose.yml for local services
  3. Configure containers to use local adapters when LOCAL_RUN=true
  4. Enable E2E testing across all containers locally

Environment Variable:

code
LOCAL_RUN=true   # Use local adapters
LOCAL_RUN=false  # Use cloud adapters (default)

Anti-Patterns to Avoid

Anti-PatternProblemSolution
Direct cloud SDK usageCan't test locallyAlways use interface + adapter
Cloud-specific types in business logicTight couplingMap to domain types at adapter boundary
Different schemas per adapterInconsistent behaviorSingle interface, adapters handle translation
Hardcoded connectionsNo flexibilityEnvironment-based configuration
Missing local alternativeCan't run E2E locallyEvery cloud service needs local option