Fulcrum Deployment Guide
Purpose: Production deployment procedures for Fulcrum Audience: DevOps, Infrastructure Engineers Source of Truth: TRUTH_MAP.md
Production Deployment Options
Fulcrum supports multiple deployment models:
| Model | Best For | Complexity |
|---|---|---|
| Managed Cloud | Fast start, no ops | Low |
| Kubernetes | Enterprise scale | Medium |
| Docker Compose | Development/POC | Low |
| Self-Hosted | Air-gapped/compliance | High |
Managed Cloud (Recommended)
Fulcrum production infrastructure:
| Surface | Platform | Status | Notes |
|---|---|---|---|
| Dashboard + marketing | Vercel | ✅ Primary | dashboard/ Next.js app (route groups (marketing) + (app)) mapped to fulcrumlayer.io |
| Dashboard (fallback SSR) | Railway | ♻️ Backup | Same Next.js build deployed via railway.toml for preview/DR; keeps /api routes close to backend |
| Backend services | Railway | ✅ Primary | fulcrum-server, event-processor defined in railway.toml (MCP served via fulcrum-server) |
| Database | Railway TimescaleDB add-on | ✅ Primary | Multi-tenant Postgres + Timescale for metrics |
| Cache | Railway Redis add-on | ✅ Primary | Policy cache + session storage |
| NATS JetStream | Railway private service / self-hosted | ✅ Required | Durable event bus used by event-processor |
| Secrets | Doppler | ✅ Primary | Shared secret store + CI/CD injection |
- Railway now owns both compute and managed data stores (TimescaleDB + Redis add-ons). Keep
railway.tomlauthoritative and run./scripts/validate-railway-env.shbefore deploying. - Vercel remains the edge entrypoint for fulcrumlayer.io. Marketing and dashboard surfaces share the same Next.js project; traffic to
/app/**is authenticated. - Disaster recovery relies on Railway-managed backups as defined in
docs/runbooks/disaster-recovery.md.
Platform Responsibilities
- Railway: Primary compute platform for all backend services and managed data stores (TimescaleDB + Redis add-ons)
- Vercel: Dashboard and marketing site hosting (Next.js route groups)
- Doppler: All secrets and environment variables
Dashboard & Marketing Topology
- The
dashboard/project uses Next.js App Router route groups: (marketing)powers fulcrumlayer.io public pages(app)contains authenticated product experiences under/app/**- Vercel hosts the production build and handles domain + edge caching.
dashboard/vercel.jsonrewrites/api/grpc/*to the Railway API gateway. - Railway deploys the same Next.js image (service
dashboard) as a fallback SSR target and for preview environments that require proximity to backend services. - Keep environment variables aligned between Vercel and Railway so either platform can serve
/apiroutes without drift.
Vercel CLI Configuration
Important: The Vercel project has Root Directory: dashboard configured. When using the Vercel CLI locally:
- Place
.vercel/project.jsonat the repository root (not inside/dashboard/) - Deploy from the repository root:
cd /path/to/fulcrum && npx vercel --prod - If
.vercel/is inside/dashboard/, Vercel will look fordashboard/dashboardand fail with "No Next.js version detected"
# Correct setup - .vercel at repo root
/fulcrum/
├── .vercel/project.json # ✅ Correct location
├── dashboard/
│ └── package.json
└── ...
# Incorrect setup - causes "dashboard/dashboard" path error
/fulcrum/
├── dashboard/
│ ├── .vercel/project.json # ❌ Wrong location
│ └── package.json
└── ...
Kubernetes Deployment
Prerequisites
- Kubernetes 1.28+
- Helm 3.x
- PostgreSQL 16 (external or in-cluster)
- Redis 7 (external or in-cluster)
- NATS with JetStream
Helm Installation
# Add Fulcrum Helm repo
helm repo add fulcrum https://charts.fulcrumlayer.io
helm repo update
# Install with default values
helm install fulcrum fulcrum/fulcrum \
--namespace fulcrum \
--create-namespace
# Install with custom values
helm install fulcrum fulcrum/fulcrum \
--namespace fulcrum \
--create-namespace \
-f values.yaml
values.yaml Example
server:
replicas: 3
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
database:
host: postgresql.database.svc
port: 5432
name: fulcrum
sslMode: require
redis:
host: redis.cache.svc
port: 6379
nats:
url: nats://nats.messaging.svc:4222
jetstream: true
cognitive:
ollama:
enabled: true
# ⚠️ SECURITY: Use localhost sidecar or NetworkPolicy to isolate
host: http://localhost:11434 # Sidecar pattern recommended
model: llama3.2
# Fallback providers (recommended)
groq:
enabled: true
# apiKey: from secret
together:
enabled: true
# apiKey: from secret
Note: For Kubernetes, deploy Ollama as a sidecar container or use strict NetworkPolicy to prevent unauthorized access. See Security Advisory.
Docker Compose (Development)
Services started: - fulcrum-server (gRPC API) - postgres (PostgreSQL + TimescaleDB) - redis (Cache) - nats (Message queue) - dashboard (Next.js UI)
Security Considerations
Ollama (Cognitive Layer)
⚠️ CRITICAL: Ollama has known security vulnerabilities including missing authentication (CVE-2025-63389). See Security Advisory.
Required Mitigations:
-
Network Isolation: Never expose Ollama to the public internet
-
Container Isolation (recommended for production):
-
Firewall Rules: Block port 11434 from external access
-
Use Fallback Providers: Configure cloud LLM providers as fallback
- Groq (GROQ_API_KEY)
- Together.ai (TOGETHER_API_KEY)
Environment Variables
Required
| Variable | Description | Example |
|---|---|---|
| DATABASE_URL | PostgreSQL connection | postgresql://user:pass@host:5432/db |
| REDIS_URL | Redis connection | redis://host:6379 |
| NATS_URL | NATS connection | nats://host:4222 |
| CLERK_SECRET_KEY | Auth secret | sk_live_... |
Optional
| Variable | Description | Default |
|---|---|---|
| OLLAMA_HOST | Ollama URL | http://localhost:11434 |
| OLLAMA_MODEL | LLM model | llama3.2 |
| LOG_LEVEL | Logging verbosity | info |
| METRICS_PORT | Prometheus port | 9090 |
Database Migrations
# Run migrations
./cmd/migration/migrate up
# Check migration status
./cmd/migration/migrate status
# Rollback last migration
./cmd/migration/migrate down 1
Health Checks
Liveness Probe
Readiness Probe
Scaling Guidelines
| Component | Scaling Strategy | Notes |
|---|---|---|
| Server | Horizontal | Stateless, scale freely |
| PostgreSQL | Vertical + Read replicas | Primary bottleneck |
| Redis | Cluster mode | For >10K policies |
| NATS | Cluster mode | For >100K events/sec |
Secret Management (Doppler)
All production secrets are managed via Doppler with auto-sync to deployment platforms.
# View production secrets
doppler secrets --project fulcrum --config prd
# Set a secret
doppler secrets set MY_SECRET="value" --project fulcrum --config prd
# Run locally with production secrets
doppler run --project fulcrum --config prd -- go run ./cmd/fulcrum-server
Required Secrets
| Secret | Service | Description |
|---|---|---|
POSTGRES_CONN_STR |
Server, Dashboard | PostgreSQL connection with ?sslmode=require |
REDIS_URL |
Server | Redis connection string |
NATS_URL |
Server | NATS JetStream URL |
CLERK_SECRET_KEY |
Dashboard | Clerk authentication secret |
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY |
Dashboard | Clerk public key |
NEXT_PUBLIC_APP_URL |
Dashboard | Public app URL (https://fulcrumlayer.io) |
NEXT_PUBLIC_FULCRUM_API_URL |
Dashboard | API URL (https://api.fulcrumlayer.io) |
FULCRUM_GRPC_ENDPOINT |
Dashboard | gRPC endpoint |
FULCRUM_MCP_URL |
Dashboard | MCP endpoint |
MCP_DEV_MODE |
Dashboard | Must be false in production |
See DOPPLER_SETUP.md for detailed setup instructions.
Related Documents
| Document | Purpose |
|---|---|
| TRUTH_MAP.md | Authoritative infrastructure state |
| CREDENTIALS.md | Secret locations |
| DOPPLER_SETUP.md | Secret management setup |
Document Version: 1.3 Last Updated: February 1, 2026