Deployment
This page describes current deployment requirements, including session affinity. The tentative target removes live aggregate fan-out and durable upstream-session dependence; see ContextForge 2.0 Target Architecture and Roadmap.
Checklist
- Front door routes only
/contextforge-rsto the ContextForge external dataplane. - JWT verification key/secret matches the control plane’s signing material; clients use control-plane API tokens whose
submatches the published user-config key. - Redis reachable; TLS/mTLS across trust zones; write access restricted to the control plane;
DATAPLANE_PUBLISHER=trueon the control plane. - Upstream connection mode matches backend URL schemes.
- One replica per
Mcp-session-id(single replica or sticky routing). with_toolsfeature disabled in the production build.- Telemetry export pointed at the collector.
- System limits raised:
nofile 65535, TCP tuning (tcp_fin_timeout=15, widened local port range).
Health Endpoint
/contextforge-rs/health is a with_tools bootstrap helper only. Production builds compile it out. Use TCP-level liveness checks or the exported metrics until a real health endpoint exists.
nginx Front-Door Routing
Reference docker/nginx.conf split:
location ^~ /contextforge-rs→ proxies to the ContextForge external dataplane.- UI and management traffic → ContextForge control plane.
- Other MCP routes, including stateful and legacy/SSE compatibility routes → ContextForge built-in dataplane.
- Upstream retries on
error timeout http_502/503/504: 2 tries, 10-second window. Non-idempotent MCPPOSTbodies are not re-sent after they reached an upstream — only connection-stage failures retry.
Session Affinity And Failover
Backend MCP sessions are local process state — see routing.md.
-
1 replica requires sticky routing by
Mcp-session-id. The reference nginx config does not provide this; safe shapes today are a single replica or a front door with stickiness. - On restart or failover, all sessions are lost. Design clients to treat session-not-found as “reinitialize”, not “retry”.
Redis Availability
- Redis is required at startup and on every uncached config lookup.
- Connection manager retries 1,000 times (rather than failing fast).
- In-process cache (default 60s) rides out short Redis blips for warm subjects.
- A cold subject during a Redis outage fails at
user_config_store_layer→400until Redis returns.
Images
- CI builds
docker/Dockerfileon every push tomainand publishes bothghcr.io/<owner>/contextforge-data-plane:v<version>andghcr.io/<owner>/contextforge-data-plane:latest, where<version>is the Cargo package version. - Pin the
v-prefixed tag for reproducible deployments.latesttracksmain. - Builder:
rust:1.96.1indocker/Dockerfile. - The reference Compose stack runs the gateway with raised limits worth copying to real deployments:
nofile 65535and TCP tuning (tcp_fin_timeout=15, widened local port range).
TLS Choices
| Leg | Options |
|---|---|
| Front door to gateway | Plain HTTP on a trusted private network (common shape behind nginx), or terminate TLS at the gateway with --tls-address plus certificate and key. Both listeners can run at once on different sockets. |
| Gateway to Redis | --redis-mode plain, TLS, or mTLS. Use TLS/mTLS across trust zones — Redis is the config trust boundary. |
| Gateway to backends | HTTPS-only by default; opt into plain HTTP or mTLS with --upstream-connection-mode. |
Config Propagation Delay
worst-case staleness = publisher interval + user-config cache expiry
Both default to ~60s. For functional tests, shorten the publisher interval and disable the cache. For throughput benchmarks, keep both at 60s.
Security Posture
| Concern | Current state |
|---|---|
| JWT revocation | None. A leaked token is valid until exp. Rotate the key and restart to invalidate. |
| CORS / Origin | CORS response headers are permissive. mcp_origin_layer validates Origin before authentication, and RMCP validates Host at the MCP service boundary. Configure both --mcp-allowed-hosts and --mcp-allowed-origins for production. |
| Local bootstrap routes | /contextforge-rs/admin/tokens/{user}, /admin/userconfigs/{user}, /health are outside auth middleware — unauthenticated by design. Only exist with with_tools. Production builds must not enable with_tools. |
| Redis trust | Whoever can write Redis controls routing (arbitrary backend URLs receive caller traffic) AND which registered plugin hooks execute on payloads. Protect with TLS/mTLS and restrict write access to the control plane. |
| Downstream TLS | Optional. Plain HTTP is acceptable only behind a trusted front door on a private network. Identity is always the bearer JWT, not mTLS. |
| Plugin code | Fully trusted, in-process. Redis config activates compiled-in factories only — it cannot inject new Rust code. |