Skip to content

Deployment

  • Cloudflare account with Workers Paid plan (for Durable Objects)
  • R2 bucket for git object storage
Section titled “Option A: Deploy via npm Package (recommended)”

No WASM build needed — pre-built binaries are included in the package.

Terminal window
npx gitmode init # Scaffolds worker/index.ts + wrangler.jsonc
npm install
npx gitmode deploy # Deploys to Cloudflare Workers

The scaffolded wrangler.jsonc includes all required bindings (R2 bucket, Durable Objects, WASM rules).

For contributors or custom builds. Requires Zig 0.15+, Binaryen, and pnpm.

Terminal window
# Build libgit2 for WASM (first time only)
bash wasm/libgit2-wasm/build.sh
# Build WASM (if not already built)
pnpm run build:wasm
# Deploy to Cloudflare
wrangler deploy

Whether scaffolded via npx gitmode init or written manually, your wrangler.jsonc needs:

{
"name": "gitmode",
"main": "./worker/index.ts",
"compatibility_date": "2025-12-01",
"compatibility_flags": ["nodejs_compat"],
"r2_buckets": [
{
"binding": "OBJECTS",
"bucket_name": "gitmode-objects"
}
],
"durable_objects": {
"bindings": [
{
"name": "REPO_STORE",
"class_name": "RepoStore"
},
{
"name": "PACK_WORKER",
"class_name": "PackWorkerDO"
}
]
},
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["RepoStore"] },
{ "tag": "v2", "new_classes": ["PackWorkerDO"] }
],
"rules": [
{
"type": "CompiledWasm",
"globs": ["**/*.wasm"],
"fallthrough": false
}
]
}

If you haven’t created the R2 bucket yet:

Terminal window
wrangler r2 bucket create gitmode-objects

After deploying, verify the server is running:

Terminal window
# Should return "gitmode"
curl https://your-worker.your-subdomain.workers.dev/
# Initialize a repo
curl -X POST https://your-worker.your-subdomain.workers.dev/api/repos/myuser/myrepo/init
# Clone it
git clone https://your-worker.your-subdomain.workers.dev/myuser/myrepo.git

To use a custom domain, add a route in your Wrangler config or use the Cloudflare dashboard:

{
"routes": [
{ "pattern": "git.example.com/*", "zone_name": "example.com" }
]
}
ResourceLimit
Worker request size100MB (Workers Paid)
R2 object size5TB per object
Durable Object storage10GB SQLite per DO
Durable Object CPU30s per request
R2 operations10M Class A / 100M Class B per month (free tier)

For typical git repositories, these limits are more than sufficient. Large binary files (LFS) are stored as regular git objects in R2.

To auto-deploy on push:

name: Deploy to Cloudflare Workers
on:
push:
branches: [main]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: goto-bus-stop/setup-zig@v2
with:
version: 0.15.2
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: "pnpm"
- run: pnpm install --no-frozen-lockfile
- name: Install Binaryen (wasm-opt, wasm-metadce)
run: pnpm add -g binaryen
- name: Build libgit2 for WASM
run: bash wasm/libgit2-wasm/build.sh
- name: Build WASM
run: pnpm run build:wasm
- name: Deploy Worker
uses: cloudflare/wrangler-action@v3
with:
command: deploy
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

Notes:

  • pnpm/action-setup@v4 reads the pnpm version from the packageManager field in package.json — do not specify version separately.
  • The Zig toolchain and Binaryen are required for the WASM build.
  • The libgit2 submodule must be checked out (submodules: true).