Migration Guide
Purpose: Upgrade between Fulcrum versions safely Audience: Operators managing Fulcrum deployments Format: Step-by-step procedures for each migration path
Before Any Migration
Pre-Migration Checklist
- [ ] Back up your database
- [ ] Document current policy configuration
- [ ] Review release notes for breaking changes
- [ ] Plan maintenance window (if production)
- [ ] Test migration in staging first
Backup Procedures
Database Backup:
# Local development
docker compose -f docker-compose.unified.yml exec fulcrum-postgres \
pg_dump -U fulcrum fulcrum > backup-$(date +%Y%m%d).sql
# Production (Railway)
railway run pg_dump -Fc > backup-$(date +%Y%m%d).dump
Export Policies:
Export Configuration:
Version 0.x to 1.0 Migration
Breaking Changes in 1.0
| Area | Change | Action Required |
|---|---|---|
| API | /api/v1/check renamed to /api/v1/evaluate |
Update API calls |
| SDK | client.check() renamed to client.evaluate() |
Update SDK usage |
| Policy Schema | action field renamed to decision |
Update policy JSON |
| Database | New columns in policies table |
Run migrations |
Step 1: Update SDKs First
Python:
Update code:
# Before (0.x)
result = env.check("send_email", input_text=content)
# After (1.0)
result = env.evaluate("send_email", input_text=content)
TypeScript:
Update code:
// Before (0.x)
const result = await envelope.check('send_email', content);
// After (1.0)
const result = await envelope.evaluate('send_email', content);
Step 2: Update API Calls
If calling the API directly:
# Before (0.x)
curl http://localhost:8080/api/v1/check -d '...'
# After (1.0)
curl http://localhost:8080/api/v1/evaluate -d '...'
Step 3: Run Database Migrations
Local Development:
docker compose -f docker-compose.unified.yml down
docker compose -f docker-compose.unified.yml pull
docker compose -f docker-compose.unified.yml up -d
Production (Railway):
Step 4: Update Policy Definitions
Export, transform, and re-import:
# Export current policies
curl http://localhost:8080/api/v1/policies > policies.json
# Transform (update field names)
jq '[.[] | .decision = .action | del(.action)]' policies.json > policies-v1.json
# Re-import
curl -X POST http://localhost:8080/api/v1/policies/import \
-H "Content-Type: application/json" \
-d @policies-v1.json
Step 5: Verify Migration
# Check version
curl http://localhost:8080/version
# Expected: {"version": "1.0.0", ...}
# Test policy evaluation
curl -X POST http://localhost:8080/api/v1/evaluate \
-H "Content-Type: application/json" \
-d '{
"action": "test_action",
"input_text": "test",
"workflow_id": "migration-test"
}'
Minor Version Upgrades (1.x to 1.y)
Minor versions are backward compatible. No code changes required.
Upgrade Procedure
Local Development:
docker compose -f docker-compose.unified.yml pull
docker compose -f docker-compose.unified.yml up -d
Production (Railway):
SDKs:
Post-Upgrade Verification
# Health check
curl http://localhost:8080/health
# Version check
curl http://localhost:8080/version
# Quick functional test
curl -X POST http://localhost:8080/api/v1/evaluate \
-d '{"action": "test", "input_text": "hello", "workflow_id": "test"}'
SDK Version Compatibility
| Server Version | Python SDK | TypeScript SDK |
|---|---|---|
| 0.1.x | 0.1.x | 0.1.x |
| 1.0.x | 1.0.x - 1.1.x | 1.0.x - 1.1.x |
| 1.1.x | 1.0.x - 1.2.x | 1.0.x - 1.2.x |
Rule: SDK minor version can be higher than server, but not lower.
Database Migration Reference
Checking Migration Status
# Local
docker compose -f docker-compose.unified.yml exec fulcrum-server \
/app/migrate status
# Production
railway run /app/migrate status
Manual Migration (if needed)
# Apply pending migrations
docker compose -f docker-compose.unified.yml exec fulcrum-server \
/app/migrate up
# Rollback last migration
docker compose -f docker-compose.unified.yml exec fulcrum-server \
/app/migrate down 1
Migration Files
Located in migrations/ directory:
migrations/
├── 001_initial_schema.sql
├── 002_add_policies_table.sql
├── 003_add_traces_table.sql
├── 004_add_semantic_fields.sql
└── ...
Self-Hosted to Cloud Migration
Moving from self-hosted to Fulcrum Cloud (api.fulcrumlayer.io):
Step 1: Export Data
# Export policies
curl http://localhost:8080/api/v1/policies > policies-export.json
# Export configuration
curl http://localhost:8080/api/v1/config > config-export.json
Step 2: Create Cloud Account
- Sign up at fulcrumlayer.io
- Create tenant and obtain API key
- Note your Tenant ID from dashboard
Step 3: Import to Cloud
# Import policies
curl -X POST https://api.fulcrumlayer.io/api/v1/policies/import \
-H "X-API-Key: your-cloud-key" \
-H "X-Tenant-ID: your-tenant-id" \
-H "Content-Type: application/json" \
-d @policies-export.json
Step 4: Update SDK Configuration
# Before (self-hosted)
client = FulcrumClient(host="localhost:50051")
# After (cloud)
client = FulcrumClient(
host="api.fulcrumlayer.io:443",
api_key=os.environ["FULCRUM_API_KEY"],
tenant_id=os.environ["FULCRUM_TENANT_ID"],
use_tls=True
)
// Before (self-hosted)
const client = new FulcrumClient({ host: 'localhost:50051' });
// After (cloud)
const client = new FulcrumClient({
host: 'api.fulcrumlayer.io:443',
apiKey: process.env.FULCRUM_API_KEY,
tenantId: process.env.FULCRUM_TENANT_ID,
useTls: true
});
Step 5: Update MCP Configuration
{
"mcpServers": {
"fulcrum-governance": {
"transport": "http",
"url": "https://api.fulcrumlayer.io/mcp",
"headers": {
"X-API-Key": "your-cloud-key",
"X-Tenant-ID": "your-tenant-id"
}
}
}
}
Rollback Procedures
If migration fails and you need to rollback:
Application Rollback
Local Development:
# Stop current version
docker compose -f docker-compose.unified.yml down
# Pull previous version
docker compose -f docker-compose.unified.yml pull fulcrum-server:v0.1.x
# Start previous version
docker compose -f docker-compose.unified.yml up -d
Production (Railway):
Database Rollback
# Rollback last N migrations
docker compose -f docker-compose.unified.yml exec fulcrum-server \
/app/migrate down N
# Or restore from backup
docker compose -f docker-compose.unified.yml exec fulcrum-postgres \
psql -U fulcrum fulcrum < backup-20260201.sql
SDK Rollback
# Python
pip install fulcrum-governance==0.1.1
# TypeScript
npm install @fulcrum-governance/sdk@0.1.1
Troubleshooting Migrations
Migration Stuck
# Check for locks
docker compose -f docker-compose.unified.yml exec fulcrum-postgres \
psql -U fulcrum -c "SELECT * FROM pg_locks WHERE NOT granted;"
# Kill blocking queries (carefully)
docker compose -f docker-compose.unified.yml exec fulcrum-postgres \
psql -U fulcrum -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction';"
Schema Mismatch
If schema doesn't match expected state:
# Check current schema
docker compose -f docker-compose.unified.yml exec fulcrum-postgres \
psql -U fulcrum -c "\dt"
# Force migration version (dangerous)
docker compose -f docker-compose.unified.yml exec fulcrum-server \
/app/migrate force VERSION
Data Corruption
If data appears corrupted after migration: 1. Stop all services immediately 2. Restore from backup 3. Review migration logs 4. Contact support if needed
Getting Help
For migration assistance: - Review release notes - Check troubleshooting guide - Open GitHub issue - Enterprise: support@fulcrumlayer.io
Document created: 2026-02-01 Diataxis category: How-to Guide (task-oriented)