Skip to content

Configuration reference

Every setting is environment variables read at server boot. There is no Settings UI for storage credentials — and there shouldn’t be: R2/S3 keys belong in .env, Docker secrets, or your host’s secret store, not in the browser.

You are…Set theseLeave defaults for…
Trying locally (dev compose)NothingEverything — local SQLite + local blobs
Production, local blobsDOMAIN, BLOB_URL_SECRETSTORAGE_KIND=local, TENANT_MODE=single
Production, R2 or Azure blobsAbove + storage block belowStripe, multi-tenant
Running syncbins.com-style hostingTENANT_MODE=multi + Stripe vars

Self-hosters run the same server binary as hosted syncbins.com. The difference is env: single-tenant vs multi-tenant, local disk vs cloud blobs, billing on or off.

VariableDefaultDescription
LISTEN_HOST0.0.0.0Bind address
LISTEN_PORT8080HTTP port (Caddy proxies here in production)
DATA_DIR./dataBase data directory
SQLITE_PATH./data/syncbins.dbSQLite metadata DB (items, devices, sessions, sync log)
LOG_LEVELinfoPino log level: tracefatal

In Docker production compose, SQLITE_PATH is usually /data/syncbins.db with ./data bind-mounted on the host.

VariableDefaultDescription
STORAGE_KINDlocallocal, azure, or r2
LOCAL_BLOB_DIR./data/blobsEncrypted blob files when STORAGE_KIND=local
BLOB_URL_SECRET(dev default)Required in production. 32+ char HMAC secret for signed local blob URLs. Generate: openssl rand -hex 32
VariableRequiredDefault
AZURE_STORAGE_CONNECTION_STRINGyes
AZURE_BLOB_CONTAINERnosyncbins
VariableRequiredDefault
R2_ACCOUNT_IDyes
R2_ACCESS_KEY_IDyes
R2_SECRET_ACCESS_KEYyes
R2_BUCKETnosyncbins

R2 uses Cloudflare’s S3-compatible API. There is no separate generic S3 driver today — AWS S3 would use the same presigned-URL pattern in a future driver; for now use R2 (S3-compatible, zero egress) or Azure.

VariableDefaultDescription
BLOB_UPLOAD_URL_TTL_MS900000 (15 min)Presigned upload URL lifetime
BLOB_DOWNLOAD_URL_TTL_MS300000 (5 min)Presigned download URL lifetime
VariableDefaultDescription
TENANT_MODEsinglesingle = one vault (default tenant). Self-hosters keep this.
BASE_DOMAINsyncbins.comUsed when TENANT_MODE=multi to build tenant URLs
STRIPE_BILLING_ENABLEDfalseSet true only for paid hosted service
STRIPE_SECRET_KEYStripe API secret
STRIPE_WEBHOOK_SECRETStripe webhook signing secret
STRIPE_PRICE_IDStripe price for Pro tier
VariableDefaultDescription
PAIR_CODE_TTL_MS300000 (5 min)Pair-code lifetime
docker/.env
DOMAIN=box.yourdomain.com
BLOB_URL_SECRET=abc123… # openssl rand -hex 32
STORAGE_KIND=local
TENANT_MODE=single
docker/.env
DOMAIN=box.yourdomain.com
BLOB_URL_SECRET=abc123…
STORAGE_KIND=r2
R2_ACCOUNT_ID=your-cloudflare-account-id
R2_ACCESS_KEY_ID=…
R2_SECRET_ACCESS_KEY=…
R2_BUCKET=syncbins
TENANT_MODE=single
docker/.env
DOMAIN=box.yourdomain.com
BLOB_URL_SECRET=abc123…
STORAGE_KIND=azure
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=…;AccountKey=…
AZURE_BLOB_CONTAINER=syncbins
TENANT_MODE=single