SyncPilledDocs

Self-hosting

Run SyncPilled on your own Cloudflare account, managed through Cloudflare Access, with one deploy command.

SyncPilled is one Cloudflare Worker with a D1 database, an R2 bucket and a Durable Object per person. Everything fits Cloudflare's free tiers for small apps; R2 needs a payment method on file even within its free tier.

Deploy

git clone https://github.com/softpilled/syncpilled.git
cd syncpilled
pnpm install
pnpm exec wrangler login
pnpm run deploy

The deploy builds the console, creates the database and the bucket, applies the migrations, deploys, and generates the Worker's signing secrets on the first run. It prints the Worker's address, such as https://syncpilled.<you>.workers.dev. Later deploys keep everyone signed in.

To deploy with your own domain, a fixed database or a placement, put just those settings in a gitignored wrangler.<name>.overlay.jsonc and run pnpm run deploy --profile <name>.

Sign in with Cloudflare Access

A self-hosted deployment is managed by whoever Cloudflare Access lets in, and each of them manages everything. Without Access set up, nobody can sign in.

  1. In Cloudflare Zero Trust → Access → Applications, add a self-hosted application for the Worker's hostname (all paths), with a policy that allows your team's emails.
  2. Add a second self-hosted application for the same hostname with the path v1, with a Bypass policy for everyone. Devices sync through /v1/apps, and the CLI reaches /v1/admin with a management key; the Worker checks those itself.
  3. Copy the first application's Application Audience (AUD) tag.
  4. Set the Worker's variables ACCESS_TEAM_DOMAIN (your team name, such as my-team) and ACCESS_AUD (that tag), in the dashboard or your overlay, and deploy again.

Open the Worker's address: Access signs you in, and the console opens. Make a management key there for the CLI.

Update

git pull
pnpm install
pnpm run deploy

Migrations only ever add, so an update never loses data.

Moving data off a hosted account

Export each app from the console (or syncpilled export), and keep the NDJSON: every line is a person's current record with its user_id.

On this page