Setting up SFP Server on EC2

This guide provides a step-by-step process for deploying SFP Server to an AWS EC2 instance using the --no-caddy flag, allowing your organization to handle HTTPS termination through your existing infrastructure.

Prerequisites

Refer to the Installing SFP Server guide for detailed system requirements, external dependencies, and secrets management. This guide focuses on AWS-specific configuration.

AWS-Specific Requirements

  • EC2 Instance:

    • OS: Ubuntu 24.04 (Recommended)

    • Instance Size: t3.large (2 vCPU, 8 GB RAM) or greater for production

    • Storage: 50 GB of EBS storage (gp3)

    • IAM Role: Instance must have read access to AWS Secrets Manager secrets

      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "secretsmanager:GetSecretValue",
                  "Resource": "arn:aws:secretsmanager:YOUR_REGION:YOUR_ACCOUNT_ID:secret:sfp-server/*"
              }
          ]
      }
  • Security Group: Configure inbound rules:

    • SSH (Port 22): From your deployment machine's IP

    • HTTP (Port 3029): From your load balancer/proxy IP ranges

  • Local Machine:

    • AWS CLI configured

    • jq command-line tool

    • sfp CLI installed

    • SSH key pair for EC2 access

Configuration

Store Credentials in AWS Secrets Manager

Store your SFP server secrets in AWS Secrets Manager for secure access:

  1. sfp-server/supabase: Supabase credentials

    aws secretsmanager create-secret --name "sfp-server/supabase" --secret-string '{
        "SUPABASE_URL": "YOUR_SUPABASE_URL",
        "SUPABASE_DB_URL": "YOUR_SUPABASE_DB_URL", 
        "SUPABASE_SERVICE_KEY": "YOUR_SUPABASE_SERVICE_KEY",
        "SUPABASE_ANON_KEY": "YOUR_SUPABASE_ANON_KEY",
        "SUPABASE_JWT_SECRET": "YOUR_SUPABASE_JWT_SECRET",
        "SUPABASE_ENCRYPTION_KEY": "YOUR_BASE64_ENCODED_ENCRYPTION_KEY"
    }'
  2. sfp-server/github: GitHub App credentials

    export GITHUB_KEY=$(awk 'NF {printf "%s\\n", $0}' /path/to/your-github-app.pem)
    aws secretsmanager create-secret --name "sfp-server/github" --secret-string "{
        \"GITHUB_APP_ID\": \"YOUR_APP_ID\",
        \"GITHUB_APP_PRIVATE_KEY\": \"$GITHUB_KEY\"
    }"
  3. sfp-server/docker: Docker registry credentials

    aws secretsmanager create-secret --name "sfp-server/docker" --secret-string '{
        "DOCKER_REGISTRY": "source.flxbl.io",
        "DOCKER_REGISTRY_TOKEN": "YOUR_GITEA_PAT"
    }'

Load Secrets for Deployment

Before running deployment commands, export secrets to your local environment:

export $(aws secretsmanager get-secret-value \
  --secret-id sfp-server/supabase \
  --query SecretString \
  --output text | jq -r 'to_entries|map("\\(.key)=\\(.value)")|.[]')

export $(aws secretsmanager get-secret-value \
  --secret-id sfp-server/github \
  --query SecretString \
  --output text | jq -r 'to_entries|map("\\(.key)=\\(.value)")|.[]')
  
export $(aws secretsmanager get-secret-value \
  --secret-id sfp-server/docker \
  --query SecretString \
  --output text | jq -r 'to_entries|map("\\(.key)=\\(.value)")|.[]')

Note: Repeat this step for each new terminal session.

Deployment

Step 1: Prepare the EC2 Instance

Connect to your EC2 instance and install Docker:

# Install Docker and Docker Compose
# See docker-installation.md for detailed instructions

Note: Docker registry authentication is handled automatically by the sfp server init command using your DOCKER_REGISTRY_TOKEN environment variable.

Step 2: Deploy SFP Server

Run from your local machine after loading secrets:

sfp server init \
  --tenant your-company-name \
  --mode prod \
  --secrets-provider custom \
  --no-caddy \
  --ssh-connection ubuntu@your-ec2-ip \
  --identity-file ~/.ssh/your-key.pem

Key flags:

  • --no-caddy: Disables built-in reverse proxy (app runs directly on port 3029)

  • --secrets-provider custom: Uses your exported environment variables

Step 3: Configure HTTPS Termination

Since you're using --no-caddy, configure your organization's HTTPS termination to:

  • Target: http://your-ec2-ip:3029

  • Health Check: http://your-ec2-ip:3029/health

  • SSL/TLS: Terminate at your load balancer/proxy level

Common setup with AWS Application Load Balancer:

  • Create Target Group pointing to EC2 instance on port 3029

  • Add HTTPS listener on port 443 with your SSL certificate

  • Configure health check endpoint: /health

Server Management

All commands run from your local machine (remember to load secrets first):

# Start server
sfp server start \
  --tenant your-company-name \
  --ssh-connection ubuntu@your-ec2-ip \
  --identity-file ~/.ssh/your-key.pem

# Stop server  
sfp server stop \
  --tenant your-company-name \
  --ssh-connection ubuntu@your-ec2-ip \
  --identity-file ~/.ssh/your-key.pem

# Update server
sfp server update \
  --tenant your-company-name \
  --secrets-provider custom \
  --ssh-connection ubuntu@your-ec2-ip \
  --identity-file ~/.ssh/your-key.pem

Verification

Test your deployment:

# Direct access to server (from your network)
curl http://your-ec2-ip:3029/health

# Through your HTTPS proxy
curl https://sfp.yourcompany.com/health

Expected response: {"status": "healthy", "version": "x.x.x"}

Troubleshooting

Docker Registry Authentication Issues

If sfp server start fails with Docker registry authentication errors, you can manually authenticate on the EC2 instance:

# SSH to your EC2 instance
ssh ubuntu@your-ec2-ip -i ~/.ssh/your-key.pem

# Manually log in to Docker registry
echo "YOUR_GITEA_PAT" | sudo docker login source.flxbl.io -u your-username --password-stdin

# Try pulling images manually to verify access
docker pull source.flxbl.io/your-org/sfp-server:latest

exit

Then retry the sfp server start command from your local machine.

Last updated