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.
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 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. | |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 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/. |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 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" |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 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. | |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 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} |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 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:-} | |
| 45 | GITHUB_APP_SLUG: ${GITHUB_APP_SLUG:-} | |
| 46 | GITHUB_APP_CLIENT_ID: ${GITHUB_APP_CLIENT_ID:-} | |
| 47 | GITHUB_APP_CLIENT_SECRET: ${GITHUB_APP_CLIENT_SECRET:-} | |
| 48 | GITHUB_APP_PRIVATE_KEY: ${GITHUB_APP_PRIVATE_KEY:-} | |
| 49 | GITHUB_APP_WEBHOOK_SECRET: ${GITHUB_APP_WEBHOOK_SECRET:-} | |
| 50 | # open: anyone may register. invite: a new account needs an invite | |
| 51 | # code, as on g1t.sh; the owners of INVITE_STAFF_WORKSPACES (slugs, | |
| 52 | # comma separated) invite without limit, everyone else INVITES_PER_USER. | |
| 53 | REGISTRATION_MODE: ${REGISTRATION_MODE:-open} | |
| 54 | INVITE_STAFF_WORKSPACES: ${INVITE_STAFF_WORKSPACES:-} | |
| 55 | INVITES_PER_USER: ${INVITES_PER_USER:-} | |
| 56 | # Where summaries of new access requests go; empty sends none. | |
| 57 | WAITLIST_NOTIFY_EMAIL: ${WAITLIST_NOTIFY_EMAIL:-} | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 58 | # Packages' files (container images and the rest), in RustFS below or |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 59 | # any S3-compatible store. S3_PUBLIC_ENDPOINT, when clients can reach |
| 60 | # the store, sends large downloads there directly. | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 61 | S3_ENDPOINT: ${S3_ENDPOINT:-http://rustfs:9000} |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 62 | S3_BUCKET: ${S3_BUCKET:-g1t-packages} |
| 63 | S3_REGION: ${S3_REGION:-us-east-1} | |
| 64 | S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-g1t} | |
| 65 | S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY:-g1t-packages-secret} | |
| 66 | S3_PUBLIC_ENDPOINT: ${S3_PUBLIC_ENDPOINT:-} | |
| Merge branch 'worktree-agent-ac5b181a013e54348' | 67 | # 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. | 68 | # the same store (docs.g1t.sh/guides/self-hosting-architecture/#storage). |
| Merge branch 'worktree-agent-ac5b181a013e54348' | 69 | BACKUP_S3_BUCKET: ${BACKUP_S3_BUCKET:-g1t-backups} |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 70 | # Packs kept for fresh clones, so the next clone of the same commit |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 71 | # does not rebuild one; storage-setup expires them after 7 days. |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 72 | 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 | 73 | # Images and files people put in Docs pages. |
| 74 | DOCS_S3_BUCKET: ${DOCS_S3_BUCKET:-g1t-docs-files} | |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 75 | volumes: |
| 76 | - g1t-data:/data | |
| 77 | - g1t-secrets:/secrets:ro | |
| 78 | depends_on: | |
| 79 | gitstore: | |
| 80 | condition: service_healthy | |
| 81 | mailpit: | |
| 82 | condition: service_started | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 83 | storage-setup: |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 84 | condition: service_completed_successfully |
| 85 | restart: unless-stopped | |
| 86 | ||
| 87 | # The status page, in a process of its own so it stays up when the site | |
| 88 | # does not: http://localhost:8788. It checks the site every minute. | |
| 89 | status: | |
| 90 | build: | |
| 91 | context: ../.. | |
| 92 | dockerfile: deploy/self-host/Dockerfile | |
| 93 | command: ["bash", "deploy/self-host/status.sh"] | |
| 94 | ports: | |
| 95 | - "${STATUS_PORT:-8788}:8788" | |
| 96 | environment: | |
| 97 | PUBLIC_URL: ${PUBLIC_URL:-http://localhost:8787} | |
| 98 | # How the status page reaches the site, from inside Compose. | |
| 99 | STATUS_CHECK_URL: http://g1t:8787 | |
| 100 | # A public repository, `workspace/repo`, whose branches it lists as a | |
| 101 | # clone would. Empty: git is not checked. | |
| 102 | STATUS_PROBE_REPO: ${STATUS_PROBE_REPO:-} | |
| 103 | volumes: | |
| 104 | - g1t-status:/data | |
| 105 | restart: unless-stopped | |
| 106 | ||
| 107 | gitstore: | |
| 108 | build: | |
| 109 | context: ./gitstore | |
| 110 | environment: | |
| 111 | GITSTORE_URL: http://gitstore:8080 | |
| 112 | GITSTORE_SECRET_FILE: /secrets/gitstore | |
| 113 | volumes: | |
| 114 | - g1t-git:/data/git | |
| 115 | - g1t-secrets:/secrets | |
| 116 | # Not published: only the g1t container reaches it. | |
| 117 | restart: unless-stopped | |
| 118 | ||
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 119 | # Packages' files, backups and clone packs, in RustFS (S3-compatible). |
| 120 | # Not published: only the g1t container reaches it, unless you publish | |
| 121 | # 9000 and set S3_PUBLIC_ENDPOINT. Any S3-compatible store works in its | |
| 122 | # place (S3_ENDPOINT). | |
| 123 | rustfs: | |
| 124 | image: ${RUSTFS_IMAGE:-rustfs/rustfs:1.0.1} | |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 125 | environment: |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 126 | RUSTFS_ACCESS_KEY: ${S3_ACCESS_KEY_ID:-g1t} |
| 127 | RUSTFS_SECRET_KEY: ${S3_SECRET_ACCESS_KEY:-g1t-packages-secret} | |
| 128 | RUSTFS_CONSOLE_ENABLE: "false" | |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 129 | volumes: |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 130 | - g1t-objects:/data |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 131 | healthcheck: |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 132 | test: ["CMD", "curl", "-fsS", "-o", "/dev/null", "http://localhost:9000/health/ready"] |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 133 | interval: 5s |
| 134 | retries: 20 | |
| 135 | restart: unless-stopped | |
| 136 | ||
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 137 | # Makes the buckets once, then exits: packages' files, backups, clone |
| 138 | # packs and Docs pages' files, with a lifecycle rule on the packs' bucket that deletes | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 139 | # packs 7 days old and uploads left unfinished after a day. |
| 140 | storage-setup: | |
| 141 | image: ${AWS_CLI_IMAGE:-amazon/aws-cli:2.37.10} | |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 142 | depends_on: |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 143 | rustfs: |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 144 | condition: service_healthy |
| 145 | entrypoint: | |
| 146 | - sh | |
| 147 | - -c | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 148 | - >- |
| 149 | set -e; | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 150 | for bucket in "$$S3_BUCKET" "$$BACKUP_S3_BUCKET" "$$PACK_S3_BUCKET" "$$DOCS_S3_BUCKET"; do |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 151 | aws s3api head-bucket --bucket "$$bucket" >/dev/null 2>&1 || aws s3api create-bucket --bucket "$$bucket" >/dev/null; |
| 152 | done; | |
| 153 | aws s3api put-bucket-lifecycle-configuration --bucket "$$PACK_S3_BUCKET" --lifecycle-configuration | |
| 154 | '{"Rules":[{"ID":"expire-packs","Status":"Enabled","Filter":{"Prefix":"packs/"},"Expiration":{"Days":7}},{"ID":"abort-unfinished-uploads","Status":"Enabled","Filter":{"Prefix":""},"AbortIncompleteMultipartUpload":{"DaysAfterInitiation":1}}]}'; | |
| 155 | echo "buckets ready" | |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 156 | environment: |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 157 | AWS_ENDPOINT_URL: http://rustfs:9000 |
| 158 | AWS_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-g1t} | |
| 159 | AWS_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY:-g1t-packages-secret} | |
| 160 | AWS_DEFAULT_REGION: ${S3_REGION:-us-east-1} | |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 161 | S3_BUCKET: ${S3_BUCKET:-g1t-packages} |
| Merge branch 'worktree-agent-ac5b181a013e54348' | 162 | BACKUP_S3_BUCKET: ${BACKUP_S3_BUCKET:-g1t-backups} |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 163 | 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 | 164 | DOCS_S3_BUCKET: ${DOCS_S3_BUCKET:-g1t-docs-files} |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 165 | |
| 166 | mailpit: | |
| 167 | image: axllent/mailpit:latest | |
| 168 | ports: | |
| 169 | - "${MAILPIT_PORT:-8025}:8025" | |
| 170 | # To deliver for real, relay through your SMTP server: | |
| 171 | # environment: | |
| 172 | # MP_SMTP_RELAY_HOST: smtp.example.com | |
| 173 | # MP_SMTP_RELAY_PORT: "587" | |
| 174 | # MP_SMTP_RELAY_USERNAME: ... | |
| 175 | # MP_SMTP_RELAY_PASSWORD: ... | |
| 176 | # MP_SMTP_RELAY_ALL: "true" | |
| 177 | restart: unless-stopped | |
| 178 | ||
| 179 | volumes: | |
| 180 | g1t-data: | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 181 | g1t-objects: |
| Tab bars on pull requests, search and profiles scroll without showing a scrollbar | 182 | g1t-status: |
| 183 | g1t-git: | |
| 184 | g1t-secrets: |
This file's history is long; its oldest lines are credited to the oldest commit read.