Skip to content

Deploying RepoWrangler

RepoWrangler is platform-neutral (ADR-013): the same product runs on Cloudflare, a self-hosted container, Azure, or Kubernetes. Ranch Hand defaults every supported target to a real production-data deployment; its optional demo mode uses mock data. Some manual quick-start recipes still begin in demo mode so you can inspect the product before supplying credentials.

First choose how you want to deploy; then choose the target/tier.

Choose a deployment method

MethodSource cloneBest forCurrent coverage
Recommended — Ranch Hand Public Preview for WindowsNoThe primary guided path: verified download, plan, preflight, dry run, and supported target workflow without build tools or deployment CLIsProduction data mode by default on WSL Compose, Docker Desktop, remote Linux Compose, Cloudflare, and Azure Container Apps; demo mode is explicit; broad lifecycle currently only for Docker Desktop
Supported alternative — manual recipes / your CI/CDYes, or consume v1.0.18 artifacts directlyProduction deployments, contributors, custom automation, Kubernetes, decoupled hosting, and any topology not yet enabled in Ranch HandEvery recipe and tier documented below

Both methods deploy the same RepoWrangler product. Ranch Hand is the primary recommended Windows experience; it does not eliminate clone/fork/manual deployment. RepoWrangler release pages contain server images and deployment bundles. Download the Windows application and read its operating instructions directly from the public Ranch Hand guide; GitHub is not required for normal use.

For the manual path, deployment is a two-step choice: pick a tier (how much do you want to spend and scale?), then pick a recipe within it (which host?).

Pick a tier

Tiers sort by cost and scale — the thing most people decide first. Every tier below Tier 3 uses recipes that already ship in ../deploy/.

TierForCostBackendRecipes
Tier 0 — Free / self-runTrying it out, a home lab, or running it on hardware you already own$0D1 or SQLitecloudflare, docker, github-pages, azure-swa
Tier 1 — Low-cost / managedA small always-on instance you don't want to babysit~a few $/moSQLite on managed storageazure-container-apps (SQLite)
Tier 2 — Team / scaledA team instance with a real database, backups, and room to scalelow $$/momanaged PostgreSQLazure-container-apps (Postgres), kubernetes
Tier 3 — EnterpriseHA, private networking, SSO/RBAC, observabilityvariesHA PostgreSQLtarget state — see the tier page

Free but self-run vs. free but managed. Tier 0 holds two different $0 shapes: the integrated Cloudflare Worker (zero-ops, someone else's edge) and the self-hosted Docker container (your box, your uptime). Both cost nothing out of pocket. The decoupled options (GitHub Pages / Azure SWA + a Worker) are also free but split the UI from the API, so you maintain a CORS contract — more moving parts for the same $0.

Topology

Independently of cost, a recipe runs in one of three topologies — how the pieces are wired (ADR-011). This is orthogonal to the tier (tier ≠ topology):

TopologyWhat runs whereRecipes
IntegratedOne Cloudflare Worker serves the SPA and the API + D1cloudflare
DecoupledSPA on a static host (GitHub Pages / Azure SWA / Cloudflare Pages); API on a Workergithub-pages, azure-swa
Self-hostedOne Node container serves the SPA and the API over SQLite/Postgres — no Cloudflaredocker, azure-container-apps, kubernetes

All self-hosted recipes deploy the same apps/server container (apps/server/README.md, ADR-014); they differ only in the surrounding infrastructure — where the database volume lives, where secrets come from, and how ingress is exposed.

Capability matrix — features by platform

Read a capability down the left, a platform across the top; the cell tells you how that platform delivers it.

CapabilityCloudflare WorkerDocker / composeAzure Container AppsKubernetesDecoupled SPA + Worker
Tier001 (SQLite) · 2 (Postgres)20
Cost floorFree tierYour compute~a few $/moCluster costFree tier
Backend storeD1SQLite (file)SQLite on Azure Files, or PostgreSQLSQLite on a PVC, or PostgreSQLD1
No Cloudflare account✗ required✗ required
Setup effortLowestLowMediumMedium–HighMedium
Data survives redeploys✅ D1✅ volume✅ Azure Files✅ PVC✅ D1
Managed secretsCF secrets.envKey Vault (managed identity)K8s Secret / ext-secretsCF secrets
Scheduler (sync cron)✅ CF cron✅ in-process✅ in-process✅ in-process✅ CF cron
Real-time webhooks
Custom domain / TLS✅ built-invia your proxy✅ built-in✅ ingress✅ built-in
Horizontal scaleEdge-managed1 replica (SQLite)✅ with PostgreSQL *✅ with PostgreSQL *Edge-managed
Runs offline / air-gappedpartial
Recipedeploy/cloudflaredeploy/dockerdeploy/azure-container-appsdeploy/kubernetesdeploy/github-pages, deploy/azure-swa

* SQLite is single-writer, so a SQLite deployment runs one replica. Set DATABASE_URL to a shared PostgreSQL (ADR-015) to run multiple API replicas behind a load balancer — same container, no recipe change; run the scheduler on exactly one replica (ENABLE_SCHEDULER=false on the rest). That Postgres step is what moves a self-hosted recipe from Tier 1 to Tier 2.

Choose your deployment — decision flowchart

Start at the top and follow the answers to your tier and recipe:

The two-minute demo (any target)

  • Cloudflare: pnpm install && pnpm build && pnpm devhttp://localhost:8787
  • Docker: docker compose up --buildhttp://localhost:8080
  • Azure Container Apps: RESOURCE_GROUP=… ACR_NAME=… deploy/azure-container-apps/deploy.sh (or deploy.ps1 on PowerShell)
  • Kubernetes: kubectl apply -f deploy/kubernetes/manifests.yaml (or the Helm chart)

Each serves mock data with no secrets. When you're ready for real data, follow the recipe's "real mode" section.

Going to real mode

Real mode needs infrastructure secrets and at least one read-only provider. The flow is the same everywhere, in every tier:

  1. Create a GitHub App (each operator owns their own — design line 620). A personal-account app works even if you don't own an org; see deploy/cloudflare/README.md for the manifest flow.
  2. Set SESSION_SECRET and SECRET_ENCRYPTION_KEY where the target keeps infrastructure secrets (Cloudflare secret put, .env, Key Vault, or a Kubernetes Secret). For a public-internet first boot, also set the optional SETUP_TOKEN.
  3. Set DEMO_MODE=false and open the instance. With no usable sign-in provider, RepoWrangler enters setup mode and sends the browser to the onboarding wizard.
  4. Use the wizard to store the GitHub App/OAuth credentials and select the estate. As soon as OAuth sign-in is usable, setup endpoints lock and the app sends you to normal sign-in.
  5. Point the App's OAuth callback and webhook URL at your instance's public URL.

For traceable container releases, build with the release tag:

bash
docker build -f apps/server/Dockerfile \
  --build-arg APP_VERSION=v1.0.10 \
  -t repo-wrangler-server:v1.0.10 .

See configuration.md for every setting.

Scale and roadmap

SQLite fits a single node — the Tier 0/1 self-hosted recipes pin one replica (SQLite is single-writer) that also runs the scheduler. Scaling to a team wants a shared database: the Postgres adapter (ADR-015) slots in behind the same apps/server host without changing any recipe — that's the Tier 2 step. Tier 3 (HA, separated controller/workers, private networking, SSO/RBAC hardening, observability) is the enterprise target state; its net-new pieces are tracked in ROADMAP.md and summarized on the Tier 3 page.

Apache-2.0 licensed. Read-only by design.