Self-Hosting the Sync Server
Deploy a Persist sync server with Docker, configure TLS, and connect devices.
Overview
The Persist sync server is an optional component that acts as a relay for device-to-device replication. Devices push and pull changes through the server instead of connecting directly. Self-hosting gives you full control over where sync data is stored.
Docker deployment
The sync server is distributed as a Docker image:
docker run -d \
--name persist-sync \
-p 8787:8787 \
-v persist-data:/data \
-e PERSIST_ADAPTER=sqlite \
-e PERSIST_PATH=/data/sync.db \
-e PERSIST_AUTH_SECRET=your-secret-here \
ghcr.io/cuitty/persist-sync:latest
For production deployments, use Docker Compose:
# docker-compose.yml
services:
persist-sync:
image: ghcr.io/cuitty/persist-sync:latest
ports:
- "8787:8787"
volumes:
- persist-data:/data
environment:
PERSIST_ADAPTER: postgres
DATABASE_URL: postgresql://persist:pass@db:5432/persist
PERSIST_AUTH_SECRET: ${PERSIST_AUTH_SECRET}
restart: unless-stopped
db:
image: postgres:16-alpine
volumes:
- pg-data:/var/lib/postgresql/data
environment:
POSTGRES_DB: persist
POSTGRES_USER: persist
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
persist-data:
pg-data:
TLS configuration
In production, always terminate TLS. The sync server does not handle TLS directly. Place it behind a reverse proxy like Caddy, nginx, or Cloudflare Tunnel.
# Caddyfile
sync.example.com {
reverse_proxy persist-sync:8787
}
Clients connect using the HTTPS URL:
await enableSync(store, {
remote: "https://sync.example.com",
authToken: "your-device-token",
});
Authentication
The sync server validates device tokens on every request. Generate tokens using the CLI:
persist server token create --device "alice-laptop"
persist server token create --device "alice-phone"
persist server token list
persist server token revoke <token-id>
Resource requirements
- CPU: 1 vCPU handles approximately 1,000 sync operations per second.
- Memory: 256 MB minimum, 512 MB recommended.
- Disk: depends on data volume. The SQLite backend works well for small deployments (under 10 GB). For larger volumes, use the Postgres backend.
Health check
The server exposes a health endpoint at /health:
curl https://sync.example.com/health
# {"status":"ok","version":"0.1.0","uptime":86400}