g1t/deploy/stack.jsonc

261 lines8,489 bytesCodeBlame
1// Everything g1t deploys to Cloudflare, in one place. Read by
2// scripts/deploy.mjs (plan, deploy), deploy/self-host/configs.mjs (what a
3// self-hosted installation runs) and the tests in scripts/deploy/.
4// docs/DEPLOYING.md explains each field and how to add a unit.
5//
6// What is written here is what the Wrangler configs cannot say. The rest is
7// read from each unit's wrangler.jsonc, never copied: its D1 databases and
8// migrations, the services it binds to, its KV, R2, queues and routes. The
9// shared crates and packages a unit is built from are read from Cargo's and
10// npm's workspace metadata. `worker` and `d1` are written here too, so the
11// file reads as an inventory, and a test checks they match the configs.
12{
13 // Deployed in this order. A stage starts only when the one before it
14 // succeeded. A unit binds only to units in its own stage or an earlier
15 // one (a test checks it), so new code never calls a service that has
16 // not shipped yet. Within a stage, units go out in parallel.
17 //
18 // migrations: every pending D1 migration, before any code.
19 // core: the services, reached through service bindings.
20 // edge: public endpoints other than the site: API, MCP, models, g1t.page, status.
21 // front: the site, sudo and the docs.
22 "stages": ["migrations", "core", "edge", "front"],
23
24 // Names for the resources the configs refer to by id, for setup
25 // commands and the docs. A test checks every KV id in a config is here.
26 "resources": {
27 "kv": {
28 "16a4232cb746418db53782aa068be693": "g1t-actions-blobs",
29 "e627b571f07047e187c03e1fc2b3bbdd": "g1t-avatars",
30 "14bc5c233d4c46a5bbf23b5367cce5fd": "g1t-domains",
31 "be765052d0124c2a935b3db4dff99f1f": "g1t-repos-git-cache"
32 }
33 },
34
35 // Each deployable unit, by short name (`--only events,web`).
36 //
37 // kind: rust-worker (worker-build), ts-worker (Wrangler bundles it),
38 // react-router (vite build first), astro (astro build first).
39 // secrets: names only; set with `npx wrangler secret put NAME` in its folder.
40 // setup: one-time steps no config can say, for a first deploy.
41 // self_host: what deploy/self-host does with it: "run" (in the one
42 // workerd), "off" (bound to the off Worker), "separate" (a
43 // process of its own), or "none".
44 // inputs: files outside its folder it is built from that no workspace
45 // metadata names (a test finds such imports).
46 // image: a Containers image, built with Docker on deploy.
47 "units": {
48 "events": {
49 "path": "services/events",
50 "kind": "rust-worker",
51 "worker": "g1t-events",
52 "d1": { "database": "g1t-events", "migrations": "migrations" },
53 "stage": "core",
54 "secrets": [],
55 "self_host": "run"
56 },
57 "identity": {
58 "path": "services/identity",
59 "kind": "rust-worker",
60 "worker": "g1t-identity",
61 "d1": { "database": "g1t", "migrations": "migrations" },
62 "stage": "core",
63 "secrets": ["GITHUB_APP_CLIENT_SECRET", "IDENTITY_KEY"],
64 "setup": ["Email Sending on g1t.sh (the EMAIL binding)"],
65 "self_host": "run"
66 },
67 "repos": {
68 "path": "services/repos",
69 "kind": "rust-worker",
70 "worker": "g1t-repos",
71 "d1": { "database": "g1t-repos", "migrations": "migrations" },
72 "stage": "core",
73 "secrets": ["REPOS_KEY"],
74 "setup": ["The Artifacts namespace `g1t` (the ARTIFACTS binding)"],
75 "self_host": "run"
76 },
77 "work": {
78 "path": "services/work",
79 "kind": "rust-worker",
80 "worker": "g1t-work",
81 "d1": { "database": "g1t-work", "migrations": "migrations" },
82 "stage": "core",
83 "secrets": [],
84 "self_host": "run"
85 },
86 "search": {
87 "path": "services/search",
88 "kind": "rust-worker",
89 "worker": "g1t-search",
90 "d1": { "database": "g1t-search", "migrations": "migrations" },
91 "stage": "core",
92 "secrets": [],
93 "self_host": "run"
94 },
95 "projects": {
96 "path": "services/projects",
97 "kind": "ts-worker",
98 "worker": "g1t-projects",
99 "d1": { "database": "g1t-projects", "migrations": "migrations" },
100 "stage": "core",
101 "secrets": [],
102 "self_host": "run"
103 },
104 "billing": {
105 "path": "services/billing",
106 "kind": "rust-worker",
107 "worker": "g1t-billing",
108 "d1": { "database": "g1t-billing", "migrations": "migrations" },
109 "stage": "core",
110 "secrets": ["STRIPE_SECRET_KEY", "CLOUDFLARE_USAGE_TOKEN"],
111 "self_host": "run"
112 },
113 "integrations": {
114 "path": "services/integrations",
115 "kind": "rust-worker",
116 "worker": "g1t-integrations",
117 "d1": { "database": "g1t-integrations", "migrations": "migrations" },
118 "stage": "core",
119 "secrets": ["INTEGRATIONS_KEY", "GITHUB_APP_PRIVATE_KEY", "GITHUB_APP_WEBHOOK_SECRET"],
120 "self_host": "run"
121 },
122 "webhooks": {
123 "path": "services/webhooks",
124 "kind": "rust-worker",
125 "worker": "g1t-webhooks",
126 "d1": { "database": "g1t-webhooks", "migrations": "migrations" },
127 "stage": "core",
128 "secrets": ["WEBHOOKS_KEY"],
129 "self_host": "run"
130 },
131 "actions": {
132 "path": "services/actions",
133 "kind": "rust-worker",
134 "worker": "g1t-actions",
135 "d1": { "database": "g1t-actions", "migrations": "migrations" },
136 "stage": "core",
137 "secrets": ["ACTIONS_KEY"],
138 "self_host": "run"
139 },
140 "security": {
141 "path": "services/security",
142 "kind": "rust-worker",
143 "worker": "g1t-security",
144 "d1": { "database": "g1t-security", "migrations": "migrations" },
145 "stage": "core",
146 "secrets": [],
147 "self_host": "run"
148 },
149 "deployments": {
150 "path": "services/deployments",
151 "kind": "ts-worker",
152 "worker": "g1t-deployments",
153 "d1": { "database": "g1t-deployments", "migrations": "migrations" },
154 "stage": "core",
155 "secrets": ["CLOUDFLARE_API_TOKEN"],
156 "setup": [
157 "Workers for Platforms, and the dispatch namespace: scripts/setup-deployments.sh",
158 "Custom domains (Cloudflare for SaaS on g1t.page): scripts/setup-custom-domains.sh"
159 ],
160 "self_host": "run"
161 },
162 "runner": {
163 "path": "services/runner",
164 "kind": "ts-worker",
165 "worker": "g1t-runner",
166 "stage": "core",
167 "secrets": ["AI_GATEWAY_TOKEN"],
168 "setup": ["Containers on the account; Docker on the machine that deploys a new image"],
169 "image": {
170 "dockerfile": "services/runner/Dockerfile",
171 // The image compiles this crate (and what it depends on).
172 "crate": "g1t-runner"
173 },
174 "self_host": "off"
175 },
176 "context": {
177 "path": "services/context",
178 "kind": "ts-worker",
179 "worker": "g1t-context",
180 "d1": { "database": "g1t-context", "migrations": "migrations" },
181 "stage": "core",
182 "secrets": [],
183 "setup": [
184 "The Vectorize index: npx wrangler vectorize create g1t-context --dimensions=768 --metric=cosine, with metadata indexes on workspace, kind, project and private"
185 ],
186 "self_host": "off"
187 },
188 "og": {
189 "path": "services/og",
190 "kind": "ts-worker",
191 "worker": "g1t-og",
192 "stage": "core",
193 "secrets": [],
194 "setup": ["Browser Rendering on the account (the BROWSER binding)"],
195 // The roadmap cards read the site's roadmap.
196 "inputs": ["apps/web/app/lib/roadmap.ts"],
197 "self_host": "none"
198 },
199 "api": {
200 "path": "apps/api",
201 "kind": "rust-worker",
202 "worker": "g1t-api",
203 "stage": "edge",
204 "secrets": [],
205 "self_host": "none"
206 },
207 "models": {
208 "path": "services/models",
209 "kind": "ts-worker",
210 "worker": "g1t-models",
211 "stage": "edge",
212 "secrets": ["AI_GATEWAY_TOKEN"],
213 "setup": ["The AI Gateway `g1t`"],
214 "self_host": "none"
215 },
216 "pages": {
217 "path": "services/pages",
218 "kind": "ts-worker",
219 "worker": "g1t-pages",
220 "stage": "edge",
221 "secrets": [],
222 "setup": ["A proxied wildcard DNS record on g1t.page (`*`, AAAA 100::): scripts/setup-deployments.sh"],
223 "self_host": "none"
224 },
225 "status": {
226 "path": "apps/status",
227 "kind": "ts-worker",
228 "worker": "g1t-status",
229 "d1": { "database": "g1t-status", "migrations": "migrations" },
230 "stage": "edge",
231 "secrets": ["STATUS_SECRET"],
232 "setup": ["Email Sending on g1t.sh (the EMAIL binding)"],
233 "self_host": "separate"
234 },
235 "web": {
236 "path": "apps/web",
237 "kind": "react-router",
238 "worker": "g1t",
239 "stage": "front",
240 "secrets": [],
241 "self_host": "run"
242 },
243 "sudo": {
244 "path": "apps/sudo",
245 "kind": "react-router",
246 "worker": "g1t-sudo",
247 "stage": "front",
248 "secrets": [],
249 "setup": ["A Cloudflare Access application on sudo.g1t.sh; its AUD tag is ACCESS_AUD"],
250 "self_host": "none"
251 },
252 "docs": {
253 "path": "apps/docs",
254 "kind": "astro",
255 "worker": "g1t-docs",
256 "stage": "front",
257 "secrets": [],
258 "self_host": "none"
259 }
260 }
261}