Skip to main content

Deployment

Guide for deploying Titan to production environments.

Architecture Overview

Requirements

ComponentMinimumRecommended
CPU2 cores per silo4+ cores
Memory2 GB per silo4+ GB
Storage10 GB50+ GB SSD
Redis1 instance3-node cluster
PostgreSQL1 instanceCockroachDB cluster

Environment Variables

API

# JWT Configuration
Jwt__Key=your-256-bit-secret-key
Jwt__Issuer=Titan
Jwt__Audience=TitanClient

# EOS Configuration (Production)
Eos__ClientId=your-eos-client-id
Eos__ClientSecret=your-eos-secret
Eos__DeploymentId=your-deployment-id

# Rate Limiting
RateLimiting__Enabled=true

# Sentry (optional)
Sentry__Dsn=https://xxx@sentry.io/xxx
Sentry__Environment=production

Connection Strings

# Redis (Orleans clustering)
ConnectionStrings__orleans-clustering=redis-host:6379

# Redis (Rate limiting)
ConnectionStrings__rate-limiting=redis-host:6380

# PostgreSQL
ConnectionStrings__titan=Host=db-host;Database=titan;Username=titan;Password=xxx
ConnectionStrings__titan-admin=Host=db-host;Database=titan_admin;Username=titan;Password=xxx

Docker Compose

Example docker-compose.yml:

version: '3.8'

services:
redis:
image: redis:7.4
ports:
- "6379:6379"
volumes:
- redis-data:/data

postgres:
image: postgres:16
environment:
POSTGRES_USER: titan
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: titan
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data

identity-host:
image: titan/identity-host:latest
environment:
- DOTNET_ENVIRONMENT=Production
- ConnectionStrings__orleans-clustering=redis:6379
- ConnectionStrings__titan=Host=postgres;Database=titan;Username=titan;Password=${DB_PASSWORD}
depends_on:
- redis
- postgres
deploy:
replicas: 2

inventory-host:
image: titan/inventory-host:latest
environment:
- DOTNET_ENVIRONMENT=Production
- ConnectionStrings__orleans-clustering=redis:6379
- ConnectionStrings__titan=Host=postgres;Database=titan;Username=titan;Password=${DB_PASSWORD}
depends_on:
- redis
- postgres
deploy:
replicas: 2

trading-host:
image: titan/trading-host:latest
environment:
- DOTNET_ENVIRONMENT=Production
- ConnectionStrings__orleans-clustering=redis:6379
- ConnectionStrings__titan=Host=postgres;Database=titan;Username=titan;Password=${DB_PASSWORD}
depends_on:
- redis
- postgres
deploy:
replicas: 2

api:
image: titan/api:latest
ports:
- "8080:8080"
environment:
- ASPNETCORE_ENVIRONMENT=Production
- Jwt__Key=${JWT_KEY}
- ConnectionStrings__orleans-clustering=redis:6379
- ConnectionStrings__rate-limiting=redis:6379
- ConnectionStrings__titan=Host=postgres;Database=titan;Username=titan;Password=${DB_PASSWORD}
- ConnectionStrings__titan-admin=Host=postgres;Database=titan_admin;Username=titan;Password=${DB_PASSWORD}
depends_on:
- identity-host
- inventory-host
- trading-host

volumes:
redis-data:
postgres-data:

Kubernetes

For Kubernetes deployments, consider:

Silo Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: identity-host
spec:
replicas: 2
selector:
matchLabels:
app: identity-host
template:
spec:
containers:
- name: identity-host
image: titan/identity-host:latest
resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "4Gi"
cpu: "2"
env:
- name: DOTNET_ENVIRONMENT
value: Production
# ... other env vars

Sticky Sessions for SignalR

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: titan-api
annotations:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "titan-sticky"

Scaling

API Gateway

  • Scale horizontally behind load balancer
  • Use sticky sessions for SignalR
  • Stateless - no local state

Orleans Silos

  • Add replicas to increase capacity
  • Orleans automatically rebalances grains
  • Use Replicas setting in AppHost for development

Redis

  • Use Redis Cluster for high availability
  • Separate clusters for clustering vs rate-limiting

Database

  • CockroachDB for distributed SQL
  • PostgreSQL with read replicas for read-heavy workloads

Monitoring

OpenTelemetry

Titan exports metrics via OpenTelemetry:

builder.AddServiceDefaults();  // Adds OpenTelemetry

Health Checks

EndpointDescription
/healthAll health checks
/aliveLiveness probe
/readyReadiness probe

Aspire Dashboard

Use the Aspire Dashboard for local development traces and logs.

Security Checklist

  • Change default admin password
  • Use strong JWT key (≥256 bits)
  • Enable TLS for all connections
  • Configure EOS for production
  • Set up Sentry for error tracking
  • Enable rate limiting
  • Review CORS origins
  • Use secrets management (Azure Key Vault, AWS Secrets Manager)