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-netbridge. Services talk to each other via internal DNS (brain:50051,router:50052). - Storage: A single PostgreSQL container handles both
contextunity.brainandcontextunity.commerceschemas. 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.envfiles.
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
- Spin Up: A new container of
contextunity.brainstarts up. - Heartbeat: Upon startup, the service registers itself to the central Redis Service Discovery registry (ex:
brain-replica-2:50051). - Routing:
contextunity.routerperiodically checks the Redis registry. It discoversbrain-replica-2and adds it to its internal gRPC load-balancing pool. - Execution: Traffic is load-balanced (Round-Robin or by
tenant_idsharding) 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
- Centralized: All base infrastructure settings (
REDIS_URL,LOG_LEVEL,OTEL_ENABLED) are defined incontextunity.core/config.py. - Extension: Individual services extend the base model. For example,
contextunity.routeradds itsRouterConfigwith specific LLM timeout settings. - Validation: Environment strings are coerced into types (e.g.,
LogLevelenums) and validated at boot time. If a production environment is missing a required setting (or provides an invalidredis://whenrediss://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 AnsibleLOG_LEVEL=INFOREDIS_URL=rediss://default:XYZ@redis-cluster.internal:6379/0GRPC_PORT=50051WORKER_CONCURRENCY=4