A self-hosted Git LFS server deployed as a Cloudflare Worker. Stores objects in Cloudflare R2 and authenticates via GitHub OAuth. Includes an integrated documentation site for onboarding team members to Git LFS.
| Path | Description |
|---|---|
server/ |
Cloudflare Worker (Hono) — Git LFS API, GitHub OAuth, R2 storage, Durable Object locks |
docs/ |
Documentation site (@docmd/core) — built into server/public/ and served as the landing page |
Config rendering is handled by the external @git-lfs-hub/config package, invoked via bun run config / turbo config (see below).
bun install1. Fill in vars.input.json (copy from vars.input.example.json in git-lfs-hub/config):
For a GitHub organization:
{
"org": "My Org",
"github": { "org": "my-org" },
"cloudflare": { "accountId": "...", "accountSlug": "..." }
}For a personal account:
{
"org": "My Name",
"github": { "user": "my-github-login" },
"cloudflare": { "accountId": "...", "accountSlug": "..." }
}| Key | Description |
|---|---|
cloudflare.accountSlug |
Sets the Worker URL prefix (GITHUB_APP_HOME) |
cloudflare.accountId |
Sets the R2 endpoint URL (S3_ENDPOINT) |
github.org[s] |
Org mode — active members of up to 5 orgs get access |
github.user |
User mode — single GitHub login gets access (mutually exclusive with github.org[s]) |
github.orgs accepts a JSON array or a space/comma-separated string.
2. Render config artifacts:
bun run config # or: turbo configInvokes bunx github:git-lfs-hub/config. Reads vars.input.json (or vars.json as fallback), merges with package defaults, validates, writes vars.json, and renders wrangler.jsonc + github-app.md.
3. Create an R2 API token:
Account dashboard → R2 → API tokens → Create API token (Object Read & Write, scoped to your bucket).
wrangler secret put S3_ACCESS_KEY_ID # R2 Access Key ID
wrangler secret put S3_SECRET_ACCESS_KEY # R2 Secret Access Key4. Register the GitHub OAuth App — follow the generated github-app.md, then:
wrangler secret put GITHUB_CLIENT_ID
wrangler secret put GITHUB_CLIENT_SECRET
wrangler secret put LOGIN_SECRET # openssl rand -hex 32turbo testturbo buildBuilds the docs site first, then links it into server/public/ before bundling the Worker.
turbo devturbo deployTwo workflows are included:
| Workflow | Trigger | Jobs |
|---|---|---|
pr.yml |
Pull requests | test + build |
main.yml |
Push to main, manual |
test + build + deploy |
Both workflows check out submodules, install dependencies (frozen lockfile, cached), and post a Turbo run summary.
Configure under Settings → Secrets and variables → Actions:
| Name | Kind | Description |
|---|---|---|
CLOUDFLARE_API_TOKEN |
Secret | Cloudflare API token with Worker deploy permissions (deploy job only) |
VARS_JSON |
Variable | Contents of vars[.input].json. Required unless vars.json are already committed. |
TURBO_TEAM |
Variable | Turbo team slug (optional) |
TURBO_TEAMID |
Variable | Turbo team ID (optional) |
TURBO_TOKEN |
Secret | Turbo remote cache token (optional) |