Skip to content

Sawabona Deployment Guide

Version: 2.0
Last Updated: 2026-01-28
Architecture: Single-Tenant Rust Self-Hosted

This guide covers deploying Sawabona as a self-hosted licensing server.

Pre-Deployment Checklist

  • [ ] Rust 1.70+ installed
  • [ ] PostgreSQL 12+ installed and running
  • [ ] Payment provider accounts created (Stripe recommended)
  • [ ] SSL/TLS certificates obtained
  • [ ] Environment variables configured
  • [ ] Database backups configured
  • [ ] Monitoring and logging set up
  • [ ] Firewall rules configured

Deployment Options

cd sawabona
docker-compose up -d

# Verify
curl http://localhost:8000/api/v1/health

2. Bare Metal Deployment

# Build release binary
cargo build --release

# Copy binary
cp target/release/sawabona-api /usr/local/bin/

# Create systemd service
sudo tee /etc/systemd/system/sawabona.service > /dev/null <<EOF
[Unit]
Description=Sawabona License Server
After=network.target postgresql.service

[Service]
Type=simple
User=sawabona
WorkingDirectory=/opt/sawabona
EnvironmentFile=/opt/sawabona/.env
ExecStart=/usr/local/bin/sawabona-api
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

# Enable and start
sudo systemctl enable sawabona
sudo systemctl start sawabona

3. Kubernetes Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sawabona
spec:
  replicas: 3
  selector:
    matchLabels:
      app: sawabona
  template:
    metadata:
      labels:
        app: sawabona
    spec:
      containers:
      - name: sawabona
        image: sawabona:latest
        ports:
        - containerPort: 8000
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: sawabona-secrets
              key: database-url
        - name: STRIPE_API_KEY
          valueFrom:
            secretKeyRef:
              name: sawabona-secrets
              key: stripe-api-key

Environment Configuration

Create .env file:

# Database
DATABASE_URL=postgresql://user:password@localhost/sawabona

# Server
SAWABONA_SERVER__HOST=0.0.0.0
SAWABONA_SERVER__PORT=8000

# Payment Providers
STRIPE_API_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...

# Logging
SAWABONA_LOGGING__LEVEL=INFO

# Security
ENCRYPTION_KEY=your_32_byte_key_here

Database Setup

# Create database
createdb sawabona

# Run migrations
cargo run --bin sawabona-cli -- db migrate

# Seed initial data
# The catalogue is yours and is not shipped: copy the example, describe your
# own products, and point the seed at it. Set SAWABONA_TENANCY__OWNER_TENANT
# first, or the seed asks before putting the catalogue in the anonymous
# default bucket.
cp examples/catalog.example.toml config/catalog.toml
cargo run --bin sawabona-cli -- db seed --catalog config/catalog.toml

# Set SAWABONA_CATALOG_PATH and the file rewrites itself whenever a CLI command
# changes a product or a plan. `db status` reports it as stale when something
# changed through the API instead. Regenerate at any time:
cargo run --bin sawabona-cli -- db export-catalog

SSL/TLS Configuration

Using Nginx as Reverse Proxy

server {
    listen 443 ssl http2;
    server_name license.yourcompany.com;

    ssl_certificate /etc/letsencrypt/live/license.yourcompany.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/license.yourcompany.com/privkey.pem;

    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Monitoring & Logging

Health Check

curl https://license.yourcompany.com/api/v1/health

Logs

# Docker
docker-compose logs -f sawabona-api

# Systemd
journalctl -u sawabona -f

# File
tail -f /var/log/sawabona/app.log

Backup Strategy

Database Backups

# Daily backup
0 2 * * * pg_dump sawabona > /backups/sawabona_$(date +\%Y\%m\%d).sql

# Restore
psql sawabona < /backups/sawabona_20260128.sql

Performance Tuning

PostgreSQL

-- Increase connection pool
ALTER SYSTEM SET max_connections = 200;

-- Enable query optimization
ALTER SYSTEM SET shared_buffers = '256MB';
ALTER SYSTEM SET effective_cache_size = '1GB';

Sawabona

# Increase worker threads
export SAWABONA_WORKERS=8

# Enable compression
export SAWABONA_COMPRESSION=true

Troubleshooting

Port Already in Use

lsof -i :8000
kill -9 <PID>

Database Connection Failed

# Test connection
psql -U user -d sawabona -c "SELECT 1"

# Check DATABASE_URL
echo $DATABASE_URL

Payment Provider Not Working

# Check provider health
curl https://license.yourcompany.com/api/v1/admin/payments/providers/stripe/test \
  -H "Authorization: Bearer your_token"

Need Help?

  • Documentation: https://docs.sawabona.dev
  • GitHub Issues: https://github.com/theaistep/sawabona/issues
  • Community: https://github.com/theaistep/sawabona/discussions