Self-Hosting Suture Hub

Prerequisites

  • Rust 1.85+ (for building from source) or Docker (for containerized deployment)
  • 1 GB RAM minimum, 10 GB disk
  • SQLite (bundled, zero config) or PostgreSQL (optional, for larger deployments)

Quick Start (Docker)

docker compose up -d
# Hub available at http://localhost:8080

Quick Start (Binary)

# Install
cargo install suture-hub

# Run
suture-hub --addr 0.0.0.0:8080 --data-dir ./hub-data

# Or with custom config
suture-hub --addr 0.0.0.0:8080 --data-dir /var/lib/suture --lfs-dir /var/lib/suture/lfs

Configuration

CLI Flags

FlagDefaultDescription --addr0.0.0.0:8080Listen address and port --data-dir./hub-dataRoot directory for all hub data --lfs-dir<data-dir>/lfsDirectory for LFS object storage --max-repo-size100 MBMaximum repository size --max-batch-size50Maximum operations per batch request

Environment Variables

VariableEquivalent Flag SUTURE_ADDR--addr SUTURE_DATA_DIR--data-dir SUTURE_LFS_DIR--lfs-dir

Environment variables take precedence over defaults but are overridden by CLI flags.

Storage

SQLite (default)

Zero configuration, good for deployments with fewer than 100 users. Uses WAL mode by default for improved concurrent access.

PostgreSQL (optional)

For larger deployments requiring higher write throughput. Configure via SUTURE_DATABASE_URL.

Data Directory Structure


hub-data/
├── hub.db           # Main database
├── repos/           # Repository data
│   └── {repo_id}/
│       ├── objects/ # Patch/content-addressable storage
│       └── refs/    # Branch/tag references
└── lfs/             # Large file storage
    └── objects/

LFS Support

  • Enabled by default — no additional configuration required
  • Max file size: configurable via --max-repo-size (default 5 GB)
  • Storage backend: local filesystem
  • S3 backend: planned

Backup

# Stop the hub
systemctl stop suture-hub

# Backup database
sqlite3 hub-data/hub.db ".backup hub-backup-$(date +%Y%m%d).db"

# Backup repos
tar czf hub-repos-backup-$(date +%Y%m%d).tar.gz hub-data/repos/

# Start the hub
systemctl start suture-hub

For zero-downtime backups with SQLite, use the online backup API or WAL checkpointing.

Reverse Proxy

Caddy

hub.suture.example.com {
    reverse_proxy localhost:8080
}

TLS is provisioned automatically.

Nginx

server {
    listen 443 ssl;
    server_name hub.suture.example.com;

    ssl_certificate     /etc/ssl/certs/hub.suture.example.com.pem;
    ssl_certificate_key /etc/ssl/private/hub.suture.example.com.key;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;

        client_max_body_size 5G;
    }
}

Performance

MetricValue Expected throughput~1000 pushes/hour on 2 CPU, 4 GB RAM Scaling strategyVertical (more RAM/CPU) or horizontal (load balancer + shared storage) Connection poolingSQLite WAL mode (default)

Monitoring

  • Health check: GET /
  • Metrics: planned (Prometheus endpoint)
  • Logs: set RUST_LOG=debug for verbose output
RUST_LOG=suture_hub=debug suture-hub --addr 0.0.0.0:8080

Security

  • Authentication: token-based
  • Rate limiting: per-IP
  • CORS: configurable
  • TLS: always use in production

Troubleshooting

SymptomCauseFix database is lockedHigh concurrent write loadIncrease SQLite busy_timeout; consider PostgreSQL permission deniedInsufficient filesystem permissionschown -R <user>:<group> <data-dir> address already in usePort conflictChange --addr or stop the conflicting process High memory usageLarge repos or many concurrent connectionsIncrease --max-repo-size limits or add more RAM

Helm Chart

A Helm chart for Kubernetes deployment is available at deploy/helm/suture-hub/.

helm install suture-hub deploy/helm/suture-hub

See Helm Chart README for full values reference.

NOTE: Helm chart documentation is pending. See deploy/helm/ for chart values.