Setting up sfp server
Step-by-Step Setup
Step 1: Generate Security Keys
Generate required secrets on your local machine:
# Generate Encryption Key (save this value)
openssl rand -base64 32Step 2: Create Configuration File
Create server.json on your local machine. This file provides all the secrets needed for the SFP server to:
Pull Docker images from the registry
Connect to your Supabase database
Authenticate with GitHub
Configure HTTPS domain and worker processes
{
"domain": "sfp.yourcompany.com",
"workerCounts": "1,2,1",
"secrets": {
"DOCKER_REGISTRY": "ghcr.io",
"DOCKER_REGISTRY_TOKEN": "ghp_xxxxxxxxxxxx",
"SUPABASE_DB_URL": "postgresql://postgres:[email protected]:5432/postgres",
"SUPABASE_URL": "https://project.supabase.co",
"SUPABASE_ANON_KEY": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"SUPABASE_SERVICE_KEY": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"SUPABASE_JWT_SECRET": "gAZgjd0n6yQxQkANH8DHRkgQg8Jyf2Z3QFZv...",
"SUPABASE_ENCRYPTION_KEY": "your-encryption-key-from-step-1",
"GITHUB_TOKEN": "your-github-token",
"GITHUB_APP_ID": "123456",
"GITHUB_APP_PRIVATE_KEY": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQ...\n-----END RSA PRIVATE KEY-----",
"AUTH_USE_GLOBAL_AUTH": "false",
"AUTH_SUPABASE_URL": "https://project.supabase.co",
"AUTH_SUPABASE_ANON_KEY": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
// Optional: Slack Bot Integration (Experimental)
"SLACK_APP_TOKEN": "xapp-your-app-token",
"SLACK_SIGNING_SECRET": "your-signing-secret",
"SLACK_BOT_TOKEN": "xoxb-your-bot-token"
}
}Where to get each value:
DOCKER_REGISTRY_TOKEN: GitHub → Settings → Developer settings → Personal access tokens (classic) → Generate new token → Select
read:packagesscopeSUPABASE_DB_URL: Supabase Dashboard → Click "Connect" button at top (Note: URL-encode password if it contains special characters like @ → %40)
SUPABASE_URL: Supabase Dashboard → Project overview → Project API section → Project URL
SUPABASE_ANON_KEY: Supabase Dashboard → Project overview → Project API section → API Key (anon/public)
SUPABASE_SERVICE_KEY: Supabase Dashboard → Project Settings → API Keys → service_role key (keep this secret!)
SUPABASE_JWT_SECRET: Supabase Dashboard → Project Settings → JWT Keys → JWT Secret
SUPABASE_ENCRYPTION_KEY: Generated in Step 1 using
openssl rand -base64 32GITHUB_APP_ID: GitHub → Settings → Developer settings → GitHub Apps → Your App → App ID (at top of page)
GITHUB_APP_PRIVATE_KEY: GitHub App settings → Scroll to "Private keys" section → Generate a private key → Download .pem file (replace newlines with
\n)AUTH_SUPABASE_URL and AUTH_SUPABASE_ANON_KEY: Same as SUPABASE_URL and SUPABASE_ANON_KEY if not using global auth
Note: For
GITHUB_APP_PRIVATE_KEY, replace all line breaks with\nto make it a single line.
Validation: The configuration will be validated when you run
sfp server initin Step 4. Invalid credentials will cause the initialization to fail with specific error messages.
Step 3: Prepare Your Server
SSH into your server and run:
Step 4: Deploy SFP Server
From your local machine, run:
Alternative for local deployment:
The initialization process will:
Create directory structure
Generate Docker Compose configuration
Configure Caddy for automatic HTTPS
Initialize database schema
Create default admin user (if Supabase credentials provided)
Step 5: Start the Server
After initialization, start the server containers:
Step 6: Verify Installation
Expected response:
Step 7: Enable Auto-Restart
SSH to your server and configure auto-restart:
Optional Features
Slack Bot Integration (Experimental)
After your server is running, you can optionally enable the AI-powered Slack bot for natural language interaction with your sfp-server:
For detailed configuration instructions, see Slack Bot Integration.
Post-Installation Management
Common Management Commands
All commands can be run remotely from your local machine:
Troubleshooting Quick Fixes
Docker Registry Authentication Issues
Supabase Connection Failed
Verify Supabase URL is publicly accessible
Check service key permissions
Test connection:
curl -X GET "SUPABASE_URL/rest/v1/" -H "apikey: ANON_KEY"
IPv6 Network Unreachable Error
If you see network is unreachable with an IPv6 address ([2a05:d014:...]):
Cause: Your server lacks IPv6 connectivity (common on Hetzner)
Solution 1: Use Supabase Session Pooler connection (recommended)
In Supabase Dashboard → Click "Connect" → Select "Session pooler"
Use the pooler connection string (port 6543) instead of direct connection
Update
SUPABASE_DB_URLin your server.json
Solution 2: Purchase IPv4 add-on from Supabase
Solution 3: Enable IPv6 on your server (if supported by your host)
Domain Not Resolving
Check DNS:
nslookup sfp.yourcompany.comVerify A record configuration
Allow up to 48 hours for propagation
Container Issues
Security Best Practices
Firewall Configuration
Regular Updates
Enable automatic security updates
Rotate secrets quarterly
Monitor server logs regularly
Backup Strategy
Configure database backups
Backup
/opt/sfp-serverdirectoryTest restore procedures
Next Steps
Configure GitHub Integration
Connect repositories
Set up webhooks
Configure CI/CD pipelines
Set Up Monitoring
Access metrics at
/metricsConfigure alerting
Set up log aggregation
User Management
Create additional users via API
Configure teams and permissions
Set up SSO if required
Getting Help
Documentation: Full details in subsequent sections
Logs: Check
sfp server logsfor debuggingSupport: Contact your SFP support channel
Last updated