Single Instance

./ensemble serve --config config/ensemble.yaml
Ensemble runs as a single Go binary. For a single instance deployment, SQLite handles all storage and Redis is optional.

Horizontally Scaled

For multiple instances behind a load balancer:
                ALB (Application Load Balancer)
                ┌──────────┬──────────┐
                ▼          ▼          ▼
           Ensemble-1  Ensemble-2  Ensemble-3
                │          │          │
                └──────────┼──────────┘

                       Redis/Valkey
                     (Rate limit sync)

Requirements for Scaling

  1. Redis/Valkey: Required for cross-instance rate limit coordination and API key sync
  2. S3: Required for response persistence (shared across instances)
  3. Shared encryption key: All instances need the same ENSEMBLE_ENCRYPTION_KEY

Redis Configuration

redis:
  address: "redis.example.com:6379"
  username: "ensemble"
  password: "${REDIS_PASSWORD}"
  pool_size: 20

AWS Deployment (Fargate)

Recommended production deployment:
ComponentAWS Service
ComputeECS Fargate (1 vCPU, 2GB per task)
Load BalancerALB with WebSocket support
Rate Limit StoreElastiCache for Redis (Valkey)
Response StorageS3
DatabaseSQLite (ephemeral, on EFS if persistence needed)
SecretsSSM Parameter Store or Secrets Manager

Docker

FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=1 go build -o ensemble ./cmd/ensemble

FROM debian:bookworm-slim
COPY --from=builder /app/ensemble /usr/local/bin/ensemble
COPY config/ /etc/ensemble/
CMD ["ensemble", "serve", "--config", "/etc/ensemble/config.yaml"]

Environment Configuration

Key environment variables for production:
ENSEMBLE_ENCRYPTION_KEY=<32-byte-base64-key>
ENSEMBLE_ADMIN_KEY=<admin-api-key>
ENSEMBLE_ENVIRONMENT=production

# Redis
REDIS_ADDRESS=redis.example.com:6379
REDIS_PASSWORD=<password>

# S3 for response persistence
AWS_REGION=us-east-1

# Provider API keys (stored encrypted in SQLite, seeded via admin API)

Health Checks

  • ALB target: GET /api/v1/health (returns 200 when healthy)
  • Deep health: GET /admin/status (includes provider connectivity)