Start with a product or guide

  • Start here

↑↓to moveto openEscto close
Sync & MeshSelf-deploy the backend

Self-deploy the backend

Run the Sync & Mesh backend in your own Cloudflare account with the mezair-cloud CLI. It uses the same Worker source as Mezair-hosted, from mezair-app/cloud/backend. The CLI lives in mezair-cloud.

Four commands cover the lifecycle: plan, apply, connection, remove. All accept --json for automation.

mesh plan

Terminal
mezair-cloud mesh plan --backend <path> --name <worker> \
  [--stage production] [--env <name>] [--account-id <id>] \
  [--base-url <url> | --subdomain <sub>] [--bucket <name>] \
  [--oidc-issuer <url> --oidc-client-id <id>] [--first-deploy] [--json]

plan computes the deployment and writes a generated wrangler.mesh.jsonc:

  • Durable Object bindings for the coordination objects the backend uses;
  • cumulative SQLite migrations. A deployable config always carries its full migration history, so --first-deploy records intent only and does not change what gets emitted;
  • the R2 artifact bucket for sealed artifact bytes.

--base-url and --subdomain are the addressing choice (a real URL or a workers.dev subdomain); --oidc-issuer/--oidc-client-id pin the identity the deployment advertises. Point --backend at the worker source: mezair-app/cloud/backend in the monorepo.

Provision, migrate, apply, and secrets

plan only computes configuration. For a real non-production deployment, run the lifecycle commands with the same target options on every invocation:

Terminal
mezair-cloud mesh provision --backend <path> --mode self-hosted --name <worker> \
  --account-id <id> --base-url <url> --bucket <name> --json
mezair-cloud mesh migrate --backend <path> --mode self-hosted --name <worker> \
  --account-id <id> --base-url <url> --bucket <name> --json
mezair-cloud mesh apply --backend <path> --mode self-hosted --name <worker> \
  --account-id <id> --base-url <url> --bucket <name> \
  --stage staging --test-deployment --json
mezair-cloud mesh secrets --backend <path> --mode self-hosted --name <worker> \
  --account-id <id> --base-url <url> --bucket <name> \
  --from-file <secret-json> --json

provision creates or reuses the selected R2 bucket. migrate applies any declared database migrations (self-hosted mode has no hosted billing D1). apply deploys through Wrangler; it does not install secrets or claim that a live backend is healthy. Install secrets after the Worker exists because the Worker must exist before Wrangler can attach them. --dry-run performs local checks without deploying. Production apply/remove requires --evidence <ref>; initial staging checks use --test-deployment.

mesh connection

Terminal
mezair-cloud mesh connection --name <worker> --base-url <url> \
  [--stage production] [--out <path>] [--allow-insecure] [--json]

Writes the discovery file the desktop app's Sync & Mesh settings consume That is the descriptor a "Your Cloudflare" or "Compatible backend" mode reads to learn endpoints, protocols, auth issuer, and negotiated limits. --allow-insecure exists for non-TLS development URLs; do not point a real backend at it.

mesh remove

Terminal
mezair-cloud mesh remove --backend <path> --name <worker> \
  [--evidence <ref>] [--json]

remove regenerates its own plan before deleting. It never targets whatever config happened to be generated last, so teardown deletes the worker you named, not a stale one.

Rehearsal and verification

The full lifecycle rehearsal (deploy, conformance, upgrade, restore, remove) is scripted in mezair-cloud/scripts/verify-mesh-rehearsal.mjs. Run it before you trust a deployment for real devices; it is the same rehearsal the hosted path has been through.

After deploy, prove the backend speaks the contract with the conformance suite, see Backend conformance:

Terminal
pnpm conformance -- --url <backend> --admin-token <token>

Wiring the desktop app

  1. mesh plan + mesh apply → worker live, secrets provisioned, admin ready.
  2. mesh connection → discovery file.
  3. Desktop: Settings → Sync & Mesh → Your Cloudflare (or Compatible backend) → paste the base URL or load the discovery file → sign in and choose Sync for each workspace whose portable configuration you want to share.

Pinning stores the backend association only. Sync stays off until you sign in and choose Sync for a workspace. See Connection modes for the full model.

This deploys the account backend; it does not provision host routes. Supported upgraded clients use an encrypted live host session only when a route is enabled and reachable. Managed HTTPS routes use a provider proxy, are off by default, and require separate operator setup.

Self-host account page

A self-hosted Worker serves an operator page at /account. It is deliberately not the hosted WorkOS account area: hosted deployments return no account page there and keep account management on the website. On a self-hosted Worker, enter the deployment admin token and an account id at /account to issue the first device enrollment code. The token is entered and used in the browser tab only. After the first device is enrolled, use Mezair Desktop's normal device management and in-app pairing for additional devices. The page's inspection control is an operator convenience, not a replacement for device auth.

Current limits

  • Rehearsed on real Cloudflare deployments; not yet demoed end-to-end on physical multi-device hardware.
  • plan emits generated config. Hand-edits to wrangler.mesh.jsonc will be regenerated away. Treat it as build output.
  • The full flag surface, exit codes, and JSON shapes are in the CLI reference. Backend internals and the rest of the Mezair Cloud CLI live in Mezair Cloud.

Suggest an edit to this page on GitHub