Skip to content

Deployment Principles

ContextUnity is fully containerized and designed originally as a distributed service mesh over gRPC. It degrades gracefully into monolithic or single-script contexts for development.

1. Environments

Local Development

In local mode, the goal is minimal friction.

  • Orchestration: docker-compose.yml
  • Network: All containers run on a single contextunity-net bridge. Services talk to each other via internal DNS (brain:50051, router:50052).
  • Storage: A single PostgreSQL container handles both contextunity.brain and contextunity.commerce schemas. Redis is optional. Local volume mounts are used for persistent data.
  • Security: Security is always on. Each project uses its own CU_PROJECT_SECRET (per-project HMAC). Redis encryption is disabled (REDIS_SECRET_KEY=false). TLS is disabled (GRPC_TLS_ENABLED=false). Secrets are read from plain .env files.

Production Deployment

Production environments focus on Zero-Trust, high availability, and horizontal scaling.

  • Orchestration: Ansible playbooks (infrastructure/ansible/) targeting physical/virtual Linux hosts, OR Kubernetes (Helm).
  • Network: Services communicate primarily over standard gRPC, bound to discrete ports.
  • Storage: High-availability external managed databases (e.g., AWS RDS, ElastiCache).
  • Security: Security is always on. Per-project HMAC (CU_PROJECT_SECRET) or Enterprise Shield (CU_SHIELD_GRPC_URL). Redis secrets encrypted (REDIS_SECRET_KEY). gRPC connections enforce TLS (GRPC_TLS_ENABLED=true) or mTLS if required.

2. Horizontal Scaling

Every Python service (contextunity.router, contextunity.brain, contextunity.worker, cu.zero) is designed to be stateless.

The Flow of Scaling

  1. Spin Up: A new container of contextunity.brain starts up.
  2. Heartbeat: Upon startup, the service registers itself to the central Redis Service Discovery registry (ex: brain-replica-2:50051).
  3. Routing: contextunity.router periodically checks the Redis registry. It discovers brain-replica-2 and adds it to its internal gRPC load-balancing pool.
  4. Execution: Traffic is load-balanced (Round-Robin or by tenant_id sharding) across all running replicas.

You can safely scale any tier up or down (e.g., run 10x contextunity.worker pods during a massive Harvester product ingestion) without notifying the rest of the cluster — the Redis registry handles the discovery automatically.

3. Configuration Management

ContextUnity rejects global state and scattered os.getenv() calls. All configuration is strictly managed through Pydantic SharedConfig.

The Rule of Settings

  1. Centralized: All base infrastructure settings (REDIS_URL, LOG_LEVEL, OTEL_ENABLED) are defined in contextunity.core/config.py.
  2. Extension: Individual services extend the base model. For example, contextunity.router adds its RouterConfig with specific LLM timeout settings.
  3. Validation: Environment strings are coerced into types (e.g., LogLevel enums) and validated at boot time. If a production environment is missing a required setting (or provides an invalid redis:// when rediss:// is required), the service fails fast before accepting traffic.

Ansible Injection

In production, environment variables are injected natively via systemd EnvironmentFile templates (roles/cu_service/templates/*.env.j2).

# Auto-generated by Ansible
LOG_LEVEL=INFO
REDIS_URL=rediss://default:XYZ@redis-cluster.internal:6379/0
GRPC_PORT=50051
WORKER_CONCURRENCY=4