Article Image

Self-Hosting RebelRoot Services: A Hands-On Guide

May 10, 2026

Reclaiming Your Infrastructure

Trusting third-party SaaS providers with your critical sync metadata defeats the purpose of privacy. True sovereignty requires running your own infrastructure. RebelRoot services are built from the ground up to be self-hostable, ensuring your databases stay behind your own firewalls.

Sovereignty isn't just about refusing telemetry; it's about owning the machines where your records live.
RebelRoot Infrastructure Group

Containerized Deployment: Docker Compose Stack

Our sync service uses a Docker structure optimized to consume minimum system resources. We recommend placing the container behind Caddy to automatically handle SSL/TLS certificate registration:

version: '3.8'
services:
caddy:
image: caddy:2-alpine
container_name: caddy-proxy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
sync-node:
image: rebelroot/sync-node:latest
container_name: rebelroot-sync
restart: unless-stopped
environment:
- PORT=8080
- DB_PATH=/data/sync.db
- JWT_SECRET=replace-with-a-secure-64-character-hex-string
- ENCRYPTION_ENFORCED=true
volumes:
- ./data:/data
volumes:
caddy_data:
caddy_config:

Create a Caddyfile next to the compose configuration to configure reverse proxy mapping and secure headers:

sync.yourdomain.com {
reverse_proxy sync-node:8080
header {
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "no-referrer"
}
}

SQLite Performance Tuning: Enabling WAL Mode

By default, SQLite uses a rollback journal for transactions, which locks the entire database file during writes. To support simultaneous read and write actions (e.g. multi-device sync), we configure the SQLite connection pools with Write-Ahead Logging (WAL) and busy timeout retries:

-- Run database configurations at startup to enable WAL mode
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA temp_store = MEMORY;
PRAGMA busy_timeout = 5000; -- Wait up to 5 seconds if database is locked

WAL mode speeds up write operations significantly while keeping memory footprint under 20MB.


Automating Secure Daily Backups

Because self-hosting places data responsibility on you, automated backup scripts are critical. Below is a shell script to safely snapshot the SQLite database using SQLite's online backup API (to prevent database corruption) and push the compressed result to an offsite secure storage bucket:

#!/bin/bash
# Backup daemon script for self-hosted SQLite DB
DB_FILE="./data/sync.db"
BACKUP_DIR="./backups"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
TEMP_BACKUP="$BACKUP_DIR/sync_temp.db"
FINAL_ZIP="$BACKUP_DIR/sync_backup_$TIMESTAMP.zip"
mkdir -p "$BACKUP_DIR"
# 1. Safely snapshot SQLite without locking writes
sqlite3 "$DB_FILE" ".backup '$TEMP_BACKUP'"
# 2. Compress the snapshot file
zip -j "$FINAL_ZIP" "$TEMP_BACKUP"
# 3. Clean up the temp uncompressed file
rm "$TEMP_BACKUP"
# 4. Upload to remote backup storage (example using AWS CLI / MinIO)
# aws s3 cp "$FINAL_ZIP" s3://your-secure-bucket/sync/
# 5. Clean up local backups older than 14 days
find "$BACKUP_DIR" -name "sync_backup_*.zip" -mtime +14 -exec rm {} \;
echo "Backup completed: $FINAL_ZIP"
Join the RebelRoot Community. Let's Build Better Software Together.