Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 1 | # Self-hosted g1t, phase 1: the core forge on your own machine. |
| 2 | # | |
| 3 | # docker compose -f deploy/self-host/docker-compose.yml up --build | |
| 4 | # | |
| 5 | # Then open http://localhost:8787. Mail (the confirmation link at sign-up) | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 6 | # lands in Mailpit at http://localhost:8025. The API is at |
| 7 | # http://localhost:8789 and the MCP server at http://localhost:8789/mcp. | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 8 | # |
| 9 | # What runs: the site and every core service in one workerd (g1t), git | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 10 | # repositories as bare repos on a volume (gitstore), the API in a second |
| 11 | # workerd beside it, packages' files, backups and the clone pack cache in | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 12 | # RustFS (S3-compatible storage), and Mailpit for mail. |
| The agents, models and context services are deleted. Nothing calls them any more: workspace agents, the hosted model proxy at models.g1t.sh with its AI Gateway, and the context hub with its search index are gone with the features they served. The deploy stack no longer builds or deploys them, so it no longer needs CONNECTORS_KEY, AI_GATEWAY_TOKEN, ANTHROPIC_API_KEY or WORKERS_AI_TOKEN, and a self-hosted install no longer generates CONNECTORS_KEY or stubs them out. Their databases, queues, index, gateway and domain stay in Cloudflare until they are deleted by hand after this is deployed. | 13 | # Cloud runners, deployments and billing are off. See |
| The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were. | 14 | # docs.g1t.sh/guides/self-hosting-architecture/. |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 15 | name: g1t |
| 16 | ||
| 17 | services: | |
| 18 | g1t: | |
| 19 | build: | |
| 20 | context: ../.. | |
| 21 | dockerfile: deploy/self-host/Dockerfile | |
| 22 | ports: | |
| 23 | - "${G1T_PORT:-8787}:8787" | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 24 | - "${API_PORT:-8789}:8789" |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 25 | environment: |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 26 | # Where people reach this installation. Links in mail, clone URLs and |
| 27 | # the site's meta tags point here. | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 28 | PUBLIC_URL: ${PUBLIC_URL:-http://localhost:8787} |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 29 | # Where the API (REST, OAuth) is reached, and its OAuth issuer; empty |
| 30 | # means PUBLIC_URL's host on API_PORT. MCP_URL, empty, is API_URL/mcp. | |
| 31 | API_URL: ${API_URL:-} | |
| 32 | MCP_URL: ${MCP_URL:-} | |
| Merge g1tusercontent.com: registry answers run nothing in a browser, the site's pages run only their own scripts, repository files and avatars on their own origin, raw files rate limited per address | 33 | # Where repository files and avatars are served: a host of its own |
| 34 | # that reaches this container, so they never share the site's | |
| 35 | # cookies; empty serves them under PUBLIC_URL/-/usercontent. | |
| 36 | USERCONTENT_URL: ${USERCONTENT_URL:-} | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 37 | API_PORT: ${API_PORT:-8789} |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 38 | GITSTORE_URL: http://gitstore:8080 |
| 39 | GITSTORE_SECRET_FILE: /secrets/gitstore | |
| 40 | MAIL_URL: ${MAIL_URL:-http://mailpit:8025} | |
| 41 | MAIL_FROM: ${MAIL_FROM:-g1t <noreply@localhost>} | |
| 42 | # Your own GitHub App, for "Continue with GitHub" and importing from | |
| 43 | # GitHub. Leave these unset to have neither. See the self-hosting guide. | |
| 44 | GITHUB_APP_ID: ${GITHUB_APP_ID:-} | |
| Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them. | 45 | # Cloudflare Turnstile on sign-up: both keys, or neither. |
| 46 | TURNSTILE_SITE_KEY: ${TURNSTILE_SITE_KEY:-} | |
| 47 | TURNSTILE_SECRET: ${TURNSTILE_SECRET:-} | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 48 | GITHUB_APP_SLUG: ${GITHUB_APP_SLUG:-} |
| 49 | GITHUB_APP_CLIENT_ID: ${GITHUB_APP_CLIENT_ID:-} | |
| 50 | GITHUB_APP_CLIENT_SECRET: ${GITHUB_APP_CLIENT_SECRET:-} | |
| 51 | GITHUB_APP_PRIVATE_KEY: ${GITHUB_APP_PRIVATE_KEY:-} | |
| 52 | GITHUB_APP_WEBHOOK_SECRET: ${GITHUB_APP_WEBHOOK_SECRET:-} | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 53 | # Packages' files (container images and the rest), in RustFS below or |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 54 | # any S3-compatible store. S3_PUBLIC_ENDPOINT, when clients can reach |
| 55 | # the store, sends large downloads there directly. | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 56 | S3_ENDPOINT: ${S3_ENDPOINT:-http://rustfs:9000} |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 57 | S3_BUCKET: ${S3_BUCKET:-g1t-packages} |
| 58 | S3_REGION: ${S3_REGION:-us-east-1} | |
| 59 | S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-g1t} | |
| 60 | S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY:-g1t-packages-secret} | |
| 61 | S3_PUBLIC_ENDPOINT: ${S3_PUBLIC_ENDPOINT:-} | |
| Merge branch 'worktree-agent-ac5b181a013e54348' | 62 | # Nightly backups' bundles and manifests, in a bucket of their own on |
| The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were. | 63 | # the same store (docs.g1t.sh/guides/self-hosting-architecture/#storage). |
| Merge branch 'worktree-agent-ac5b181a013e54348' | 64 | BACKUP_S3_BUCKET: ${BACKUP_S3_BUCKET:-g1t-backups} |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 65 | # Packs kept for fresh clones, so the next clone of the same commit |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 66 | # does not rebuild one; storage-setup expires them after 7 days. |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 67 | PACK_S3_BUCKET: ${PACK_S3_BUCKET:-g1t-git-packs} |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 68 | # Images and files people put in Docs pages. |
| 69 | DOCS_S3_BUCKET: ${DOCS_S3_BUCKET:-g1t-docs-files} | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 70 | volumes: |
| 71 | - g1t-data:/data | |
| 72 | - g1t-secrets:/secrets:ro | |
| 73 | depends_on: | |
| 74 | gitstore: | |
| 75 | condition: service_healthy | |
| 76 | mailpit: | |
| 77 | condition: service_started | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 78 | storage-setup: |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 79 | condition: service_completed_successfully |
| 80 | restart: unless-stopped | |
| 81 | ||
| 82 | # The status page, in a process of its own so it stays up when the site | |
| 83 | # does not: http://localhost:8788. It checks the site every minute. | |
| 84 | status: | |
| 85 | build: | |
| 86 | context: ../.. | |
| 87 | dockerfile: deploy/self-host/Dockerfile | |
| 88 | command: ["bash", "deploy/self-host/status.sh"] | |
| 89 | ports: | |
| 90 | - "${STATUS_PORT:-8788}:8788" | |
| 91 | environment: | |
| 92 | PUBLIC_URL: ${PUBLIC_URL:-http://localhost:8787} | |
| 93 | # How the status page reaches the site, from inside Compose. | |
| 94 | STATUS_CHECK_URL: http://g1t:8787 | |
| 95 | # A public repository, `workspace/repo`, whose branches it lists as a | |
| 96 | # clone would. Empty: git is not checked. | |
| 97 | STATUS_PROBE_REPO: ${STATUS_PROBE_REPO:-} | |
| 98 | volumes: | |
| 99 | - g1t-status:/data | |
| 100 | restart: unless-stopped | |
| 101 | ||
| 102 | gitstore: | |
| 103 | build: | |
| 104 | context: ./gitstore | |
| 105 | environment: | |
| 106 | GITSTORE_URL: http://gitstore:8080 | |
| 107 | GITSTORE_SECRET_FILE: /secrets/gitstore | |
| 108 | volumes: | |
| 109 | - g1t-git:/data/git | |
| 110 | - g1t-secrets:/secrets | |
| 111 | # Not published: only the g1t container reaches it. | |
| 112 | restart: unless-stopped | |
| 113 | ||
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 114 | # Packages' files, backups and clone packs, in RustFS (S3-compatible). |
| 115 | # Not published: only the g1t container reaches it, unless you publish | |
| 116 | # 9000 and set S3_PUBLIC_ENDPOINT. Any S3-compatible store works in its | |
| 117 | # place (S3_ENDPOINT). | |
| 118 | rustfs: | |
| 119 | image: ${RUSTFS_IMAGE:-rustfs/rustfs:1.0.1} | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 120 | environment: |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 121 | RUSTFS_ACCESS_KEY: ${S3_ACCESS_KEY_ID:-g1t} |
| 122 | RUSTFS_SECRET_KEY: ${S3_SECRET_ACCESS_KEY:-g1t-packages-secret} | |
| 123 | RUSTFS_CONSOLE_ENABLE: "false" | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 124 | volumes: |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 125 | - g1t-objects:/data |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 126 | healthcheck: |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 127 | test: ["CMD", "curl", "-fsS", "-o", "/dev/null", "http://localhost:9000/health/ready"] |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 128 | interval: 5s |
| 129 | retries: 20 | |
| 130 | restart: unless-stopped | |
| 131 | ||
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 132 | # Makes the buckets once, then exits: packages' files, backups, clone |
| 133 | # packs and Docs pages' files, with a lifecycle rule on the packs' bucket that deletes | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 134 | # packs 7 days old and uploads left unfinished after a day. |
| 135 | storage-setup: | |
| 136 | image: ${AWS_CLI_IMAGE:-amazon/aws-cli:2.37.10} | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 137 | depends_on: |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 138 | rustfs: |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 139 | condition: service_healthy |
| 140 | entrypoint: | |
| 141 | - sh | |
| 142 | - -c | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 143 | - >- |
| 144 | set -e; | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 145 | for bucket in "$$S3_BUCKET" "$$BACKUP_S3_BUCKET" "$$PACK_S3_BUCKET" "$$DOCS_S3_BUCKET"; do |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 146 | aws s3api head-bucket --bucket "$$bucket" >/dev/null 2>&1 || aws s3api create-bucket --bucket "$$bucket" >/dev/null; |
| 147 | done; | |
| 148 | aws s3api put-bucket-lifecycle-configuration --bucket "$$PACK_S3_BUCKET" --lifecycle-configuration | |
| 149 | '{"Rules":[{"ID":"expire-packs","Status":"Enabled","Filter":{"Prefix":"packs/"},"Expiration":{"Days":7}},{"ID":"abort-unfinished-uploads","Status":"Enabled","Filter":{"Prefix":""},"AbortIncompleteMultipartUpload":{"DaysAfterInitiation":1}}]}'; | |
| 150 | echo "buckets ready" | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 151 | environment: |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 152 | AWS_ENDPOINT_URL: http://rustfs:9000 |
| 153 | AWS_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-g1t} | |
| 154 | AWS_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY:-g1t-packages-secret} | |
| 155 | AWS_DEFAULT_REGION: ${S3_REGION:-us-east-1} | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 156 | S3_BUCKET: ${S3_BUCKET:-g1t-packages} |
| Merge branch 'worktree-agent-ac5b181a013e54348' | 157 | BACKUP_S3_BUCKET: ${BACKUP_S3_BUCKET:-g1t-backups} |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 158 | PACK_S3_BUCKET: ${PACK_S3_BUCKET:-g1t-git-packs} |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 159 | DOCS_S3_BUCKET: ${DOCS_S3_BUCKET:-g1t-docs-files} |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 160 | |
| 161 | mailpit: | |
| 162 | image: axllent/mailpit:latest | |
| 163 | ports: | |
| 164 | - "${MAILPIT_PORT:-8025}:8025" | |
| 165 | # To deliver for real, relay through your SMTP server: | |
| 166 | # environment: | |
| 167 | # MP_SMTP_RELAY_HOST: smtp.example.com | |
| 168 | # MP_SMTP_RELAY_PORT: "587" | |
| 169 | # MP_SMTP_RELAY_USERNAME: ... | |
| 170 | # MP_SMTP_RELAY_PASSWORD: ... | |
| 171 | # MP_SMTP_RELAY_ALL: "true" | |
| 172 | restart: unless-stopped | |
| 173 | ||
| 174 | volumes: | |
| 175 | g1t-data: | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 176 | g1t-objects: |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 177 | g1t-status: |
| 178 | g1t-git: | |
| 179 | g1t-secrets: |
This file's history is long; its oldest lines are credited to the oldest commit read.