Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
182 linesCodeBlameRaw

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.

Projects: when each was last pushed, and how active it is lately1# 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)
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.
8#
9# What runs: the site and every core service in one workerd (g1t), git
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
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/.
Projects: when each was last pushed, and how active it is lately15name: g1t
16
17services:
18 g1t:
19 build:
20 context: ../..
21 dockerfile: deploy/self-host/Dockerfile
22 ports:
23 - "${G1T_PORT:-8787}:8787"
24 - "${API_PORT:-8789}:8789"
25 environment:
26 # Where people reach this installation. Links in mail, clone URLs and
27 # the site's meta tags point here.
28 PUBLIC_URL: ${PUBLIC_URL:-http://localhost:8787}
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 address33 # 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:-}
Projects: when each was last pushed, and how active it is lately37 API_PORT: ${API_PORT:-8789}
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:-}
Projects: when each was last pushed, and how active it is lately48 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-a6da31375506fc440'53 # How many friends each person may invite by email (20 when empty;
54 # 0 turns it off). Anyone may register with or without one.
55 INVITES_PER_USER: ${INVITES_PER_USER:-}
Projects: when each was last pushed, and how active it is lately56 # Packages' files (container images and the rest), in RustFS below or
57 # any S3-compatible store. S3_PUBLIC_ENDPOINT, when clients can reach
58 # the store, sends large downloads there directly.
59 S3_ENDPOINT: ${S3_ENDPOINT:-http://rustfs:9000}
60 S3_BUCKET: ${S3_BUCKET:-g1t-packages}
61 S3_REGION: ${S3_REGION:-us-east-1}
62 S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-g1t}
63 S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY:-g1t-packages-secret}
64 S3_PUBLIC_ENDPOINT: ${S3_PUBLIC_ENDPOINT:-}
65 # 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.66 # the same store (docs.g1t.sh/guides/self-hosting-architecture/#storage).
Projects: when each was last pushed, and how active it is lately67 BACKUP_S3_BUCKET: ${BACKUP_S3_BUCKET:-g1t-backups}
68 # Packs kept for fresh clones, so the next clone of the same commit
69 # does not rebuild one; storage-setup expires them after 7 days.
70 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 store71 # Images and files people put in Docs pages.
72 DOCS_S3_BUCKET: ${DOCS_S3_BUCKET:-g1t-docs-files}
Projects: when each was last pushed, and how active it is lately73 volumes:
74 - g1t-data:/data
75 - g1t-secrets:/secrets:ro
76 depends_on:
77 gitstore:
78 condition: service_healthy
79 mailpit:
80 condition: service_started
81 storage-setup:
82 condition: service_completed_successfully
83 restart: unless-stopped
84
85 # The status page, in a process of its own so it stays up when the site
86 # does not: http://localhost:8788. It checks the site every minute.
87 status:
88 build:
89 context: ../..
90 dockerfile: deploy/self-host/Dockerfile
91 command: ["bash", "deploy/self-host/status.sh"]
92 ports:
93 - "${STATUS_PORT:-8788}:8788"
94 environment:
95 PUBLIC_URL: ${PUBLIC_URL:-http://localhost:8787}
96 # How the status page reaches the site, from inside Compose.
97 STATUS_CHECK_URL: http://g1t:8787
98 # A public repository, `workspace/repo`, whose branches it lists as a
99 # clone would. Empty: git is not checked.
100 STATUS_PROBE_REPO: ${STATUS_PROBE_REPO:-}
101 volumes:
102 - g1t-status:/data
103 restart: unless-stopped
104
105 gitstore:
106 build:
107 context: ./gitstore
108 environment:
109 GITSTORE_URL: http://gitstore:8080
110 GITSTORE_SECRET_FILE: /secrets/gitstore
111 volumes:
112 - g1t-git:/data/git
113 - g1t-secrets:/secrets
114 # Not published: only the g1t container reaches it.
115 restart: unless-stopped
116
117 # Packages' files, backups and clone packs, in RustFS (S3-compatible).
118 # Not published: only the g1t container reaches it, unless you publish
119 # 9000 and set S3_PUBLIC_ENDPOINT. Any S3-compatible store works in its
120 # place (S3_ENDPOINT).
121 rustfs:
122 image: ${RUSTFS_IMAGE:-rustfs/rustfs:1.0.1}
123 environment:
124 RUSTFS_ACCESS_KEY: ${S3_ACCESS_KEY_ID:-g1t}
125 RUSTFS_SECRET_KEY: ${S3_SECRET_ACCESS_KEY:-g1t-packages-secret}
126 RUSTFS_CONSOLE_ENABLE: "false"
127 volumes:
128 - g1t-objects:/data
129 healthcheck:
130 test: ["CMD", "curl", "-fsS", "-o", "/dev/null", "http://localhost:9000/health/ready"]
131 interval: 5s
132 retries: 20
133 restart: unless-stopped
134
Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store135 # Makes the buckets once, then exits: packages' files, backups, clone
136 # packs and Docs pages' files, with a lifecycle rule on the packs' bucket that deletes
Projects: when each was last pushed, and how active it is lately137 # packs 7 days old and uploads left unfinished after a day.
138 storage-setup:
139 image: ${AWS_CLI_IMAGE:-amazon/aws-cli:2.37.10}
140 depends_on:
141 rustfs:
142 condition: service_healthy
143 entrypoint:
144 - sh
145 - -c
146 - >-
147 set -e;
Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store148 for bucket in "$$S3_BUCKET" "$$BACKUP_S3_BUCKET" "$$PACK_S3_BUCKET" "$$DOCS_S3_BUCKET"; do
Projects: when each was last pushed, and how active it is lately149 aws s3api head-bucket --bucket "$$bucket" >/dev/null 2>&1 || aws s3api create-bucket --bucket "$$bucket" >/dev/null;
150 done;
151 aws s3api put-bucket-lifecycle-configuration --bucket "$$PACK_S3_BUCKET" --lifecycle-configuration
152 '{"Rules":[{"ID":"expire-packs","Status":"Enabled","Filter":{"Prefix":"packs/"},"Expiration":{"Days":7}},{"ID":"abort-unfinished-uploads","Status":"Enabled","Filter":{"Prefix":""},"AbortIncompleteMultipartUpload":{"DaysAfterInitiation":1}}]}';
153 echo "buckets ready"
154 environment:
155 AWS_ENDPOINT_URL: http://rustfs:9000
156 AWS_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-g1t}
157 AWS_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY:-g1t-packages-secret}
158 AWS_DEFAULT_REGION: ${S3_REGION:-us-east-1}
159 S3_BUCKET: ${S3_BUCKET:-g1t-packages}
160 BACKUP_S3_BUCKET: ${BACKUP_S3_BUCKET:-g1t-backups}
161 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 store162 DOCS_S3_BUCKET: ${DOCS_S3_BUCKET:-g1t-docs-files}
Projects: when each was last pushed, and how active it is lately163
164 mailpit:
165 image: axllent/mailpit:latest
166 ports:
167 - "${MAILPIT_PORT:-8025}:8025"
168 # To deliver for real, relay through your SMTP server:
169 # environment:
170 # MP_SMTP_RELAY_HOST: smtp.example.com
171 # MP_SMTP_RELAY_PORT: "587"
172 # MP_SMTP_RELAY_USERNAME: ...
173 # MP_SMTP_RELAY_PASSWORD: ...
174 # MP_SMTP_RELAY_ALL: "true"
175 restart: unless-stopped
176
177volumes:
178 g1t-data:
179 g1t-objects:
180 g1t-status:
181 g1t-git:
182 g1t-secrets:

This file's history is long; its oldest lines are credited to the oldest commit read.