Skip to content

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

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.toml authoritative and run ./scripts/validate-railway-env.sh before 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.json rewrites /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 /api routes without drift.

Vercel CLI Configuration

Important: The Vercel project has Root Directory: dashboard configured. When using the Vercel CLI locally:

  • Place .vercel/project.json at 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 for dashboard/dashboard and 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)

cd /path/to/fulcrum
docker-compose -f docker-compose.unified.yml up -d

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:

  1. Network Isolation: Never expose Ollama to the public internet

    # Good - localhost only
    OLLAMA_HOST: "http://localhost:11434"
    
    # Bad - exposed to network
    OLLAMA_HOST: "http://0.0.0.0:11434"  # DON'T DO THIS
    

  2. Container Isolation (recommended for production):

    services:
      ollama:
        image: ollama/ollama
        network_mode: "none"  # No network access
        deploy:
          resources:
            limits:
              cpus: '2'
              memory: 4G
    

  3. Firewall Rules: Block port 11434 from external access

    # UFW example
    ufw deny in on eth0 to any port 11434
    

  4. Use Fallback Providers: Configure cloud LLM providers as fallback

  5. Groq (GROQ_API_KEY)
  6. 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

GET /health/live
Response: 200 OK

Readiness Probe

GET /health/ready
Response: 200 OK (when dependencies connected)

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.



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