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.

113 linesCodeBlameRaw
1---
2title: Deployments, packages and telemetry
3description: How apps are built and served on g1t.page, how the package registries are routed and stored, and where a project's logs, traces and metrics go.
4---
5
6import Diagram from '../../../components/Diagram.astro';
7
8## Deployments
9
10`deployments` (`services/deployments`, TypeScript, D1 `g1t-deployments`)
11builds apps and puts them live. `pages` (`services/pages`) serves them.
12Neither runs your app as a server that waits: each app is a Worker, which
13runs only while it answers a request, so an app nobody visits costs
14nothing.
15
16<Diagram name="deployment-path" />
17
18### Building
19
20Every push to the default branch makes a production deployment, and every
21open pull request gets a preview. `deployments` reads pushes from its
22event queue and asks `runner` for a sandbox in `deploy` mode
23([Actions, runners and sandboxes](/architecture/compute/#other-work-in-sandboxes)).
24The sandbox works out what the app is, preferring what runs nothing while
25no one visits, in this order
26([What a project is built as](/guides/deployments/#what-a-project-is-built-as)):
27
281. a Workers project, from `wrangler deploy --dry-run`;
292. a framework it knows, such as Vite, Astro, Next.js or SvelteKit, as
30 the site it builds, even beside a `Dockerfile`;
313. a Node.js server with no `Dockerfile` (Express, Koa, Hono…), as a
32 Worker: the sandbox writes an entry that serves the app's own server
33 with `httpServerHandler` from `cloudflare:node`, bundles it with
34 wrangler and starts it once with `wrangler dev` before deploying it
35 ([Node.js servers as Workers](/guides/deployments/#nodejs-servers-as-workers));
364. any other server it recognises, as a container, from its `Dockerfile`
37 or one it writes ([Docker deployments](/guides/deployments/#docker-deployments));
385. a `build` script's site or an `index.html`, even beside a
39 `Dockerfile`;
406. a `Dockerfile` with nothing else to serve, as a container.
41
42A container is the fallback: a Node.js server that cannot run as a Worker
43(a native addon, say), or whose Worker does not bundle or start, is
44deployed as a container instead.
45
46A container's image is pushed to Cloudflare's registry with a push-only
47login `deployments` mints for the build, and runs on Cloudflare
48Containers behind a Worker of g1t's own in the same namespace. A
49self-hosted g1t whose account has no Containers sets `CONTAINERS` to
50`off`.
51
52The sandbox is given a key that can upload the app's static files and
53nothing else. `deployments` uploads the built Worker itself to the Workers
54for Platforms dispatch namespace `g1t-deployments`. A site with only static
55files gets a Worker that serves just its assets. A workflow can build
56instead and hand over the result, with
57`POST /repos/{owner}/{repo}/deployments/builds` or the `g1t/deploy` action.
58
59### Serving
60
61| | Hostname |
62| --- | --- |
63| Production | `<project>-<workspace>.g1t.page` |
64| A preview | `<project>-git-<branch>-<workspace>.g1t.page` |
65| Your domain | A CNAME to `domains.g1t.page`, a custom hostname on g1t.page's zone |
66
67`pages` answers every one of those hostnames. It reads the app's name from
68the hostname, or looks a custom domain up in the `g1t-domains` KV, which
69`deployments` writes, and hands the request to that app's Worker with
70`env.APPS.get(app)`. Each request to an app may use 50 ms of CPU and 50
71subrequests. A preview comes down when its pull request closes, or after it
72has been idle for a number of days you choose (7 by default).
73
74## Packages
75
76`packages` (`services/packages`, Rust, D1 `g1t-packages`) is every package
77registry g1t has. The site recognises a registry's path and passes the
78request on whole, as it does for git:
79
80| Registry | Path on `g1t.sh` |
81| --- | --- |
82| Container images (OCI Distribution 1.1) | `/v2/`, with tokens at `/v2/token` |
83| npm | `/-/npm/` |
84| Cargo, sparse index | `/-/cargo/<workspace>/` |
85| Composer | `/-/composer/` |
86| Maven | `/-/maven/` |
87| NuGet | `/-/nuget/<workspace>/v3/index.json` |
88| RubyGems | `/-/rubygems/` |
89
90Files are stored in the `g1t-packages` bucket by their digest, so a layer
91or a tarball pushed twice is kept once. The bucket sits behind the
92`BlobStore` port, so a self-hosted installation keeps them in any S3
93store. Large downloads are answered with a signed URL to the bucket.
94[Packages](/guides/packages/) has each registry's setup.
95
96## Telemetry
97
98`telemetry` (`services/telemetry`, TypeScript) keeps each project's logs,
99traces, metrics and errors in a Durable Object of its own,
100`TelemetryStore`, in that object's SQLite storage. A project's data never
101shares a database with another's.
102
103It has three ways in:
104
105| Door | From |
106| --- | --- |
107| `otel.g1t.sh/v1/traces`, `/v1/logs`, `/v1/metrics` | Your software, as OpenTelemetry over HTTP, JSON or protobuf, with a `g1to_…` token |
108| Tail events | Apps on `g1t.page`: `telemetry` is `pages`' tail consumer, and apps name it as their Tail Worker |
109| `/otlp/v1/*` on the API | The same as `otel.g1t.sh`, passed on as it is; the only door on a self-hosted installation |
110
111A store keeps up to 4 GiB and sheds its oldest day past that. You choose
112how long raw data is kept, from 1 to 30 days; rollups are kept 90 days.
113[Observability](/guides/observability/) shows what you can do with it.