Skip to content

Commit

Merge branch 'worktree-agent-a0d1a64e2033a58ed' into claude/cool-newton-7nm8r9

Claudeagentcommitted Parents578dad5d71c0c8Browse files
36 files+437−500/36 viewed
+2−0
4141 | `root-dir` | The project's setting | Where the project is in the checkout. |
4242 | `build-command` | The project's setting, else what the build finds | What builds it. |
4343 | `output-dir` | The project's setting, else the folder the framework writes, else the first of `dist`, `build`, `out`, `public`, `_site`, `.output/public` | The folder a static build writes. |
44+| `build-as` | The project's setting, else `auto` | What it is built as: `auto`, `static`, `workers` or `docker`. A container is built with the `docker` on the job's `PATH`. |
45+| `dockerfile` | The project's setting, else `Dockerfile` or `Containerfile` | The Dockerfile a container is built from, relative to the project. |
4446 | `sha` | The run's commit | The commit this is a build of, for its `g1t / deploy` check. |
4547 | `token` | `${{ github.token }}` | The job's own token. It needs `deployments: write`; any other token is refused. |
4648
+10−0
1919 description: The folder a static build writes. The project's own setting, else the folder the framework writes, else the first of dist, build, out, public, _site or .output/public.
2020 required: false
2121 default: ""
22+ build-as:
23+ description: What it is built as, auto, static, workers or docker. The project's own setting unless you say; auto finds it from the project's files.
24+ required: false
25+ default: ""
26+ dockerfile:
27+ description: The Dockerfile a container is built from, relative to the project. The project's setting, else Dockerfile or Containerfile.
28+ required: false
29+ default: ""
2230 sha:
2331 description: The commit this is a build of, for the commit's g1t / deploy check. The run's commit unless you say.
2432 required: false
4957 INPUT_ROOT_DIR: ${{ inputs.root-dir }}
5058 INPUT_BUILD_COMMAND: ${{ inputs.build-command }}
5159 INPUT_OUTPUT_DIR: ${{ inputs.output-dir }}
60+ INPUT_BUILD_AS: ${{ inputs.build-as }}
61+ INPUT_DOCKERFILE: ${{ inputs.dockerfile }}
5262 INPUT_SHA: ${{ inputs.sha }}
5363 INPUT_TOKEN: ${{ inputs.token }}
5464 run: bash "$GITHUB_ACTION_PATH/deploy.sh"
+2−0
9393 export ROOT_DIR="$(pick "${INPUT_ROOT_DIR:-}" root_dir)"
9494 export BUILD_COMMAND="$(pick "${INPUT_BUILD_COMMAND:-}" build_command)"
9595 export OUTPUT_DIR="$(pick "${INPUT_OUTPUT_DIR:-}" output_dir)"
96+export BUILD_AS="$(pick "${INPUT_BUILD_AS:-}" build_as)"
97+export DOCKERFILE="$(pick "${INPUT_DOCKERFILE:-}" dockerfile)"
9698 export BUILD_ENV="$(field build_env <<<"${answer}")"
9799 export BUILD_SECRETS="$(field build_secrets <<<"${answer}")"
98100 unset GIT_REMOTE
+9−5
2424 | `root-dir` | The checkout | Where the project is in the checkout. |
2525 | `build-command` | None | A build command of your own, as `g1t/deploy` takes it. |
2626 | `output-dir` | None | An output folder of your own, as `g1t/deploy` takes it. |
27+| `build-as` | `auto` | What it is built as: `auto`, `static`, `workers` or `docker`, as `g1t/deploy` takes it. |
28+| `dockerfile` | None | A Dockerfile's path of your own, as `g1t/deploy` takes it. |
2729
2830 ## Outputs
2931
3032 | Output | |
3133 | --- | --- |
32−| `kind` | `workers` (a `wrangler.jsonc`, `wrangler.json` or `wrangler.toml`, or a framework's Cloudflare adapter), `static` (a site a build writes), `html` (the files as they are) or `none` (nothing to serve, or a framework set up to need a server). |
33−| `framework` | The framework it is built with, from the table below. Empty when there is none. |
34+| `kind` | `workers` (a `wrangler.jsonc`, `wrangler.json` or `wrangler.toml`, or a framework's Cloudflare adapter), `static` (a site a build writes), `html` (the files as they are), `container` (a `Dockerfile`, a framework set up to need a server, or a server g1t writes a Dockerfile for) or `none` (nothing to serve). |
35+| `framework` | The framework it is built with, from the table below; for a container without one, `dockerfile`, or the server g1t writes a Dockerfile for (`node`, `django`, `flask`, `fastapi`, `python`, `go`, `rails`, `rack`, `laravel`, `php`). Empty when there is none. |
36+| `dockerfile` | A container's own Dockerfile, relative to the project. Empty when g1t writes one, and for anything that is not a container. |
37+| `port` | The port a container listens on: its Dockerfile's `EXPOSE`, else `8080`. |
3438 | `install` | How dependencies are installed, from the lockfile: `npm ci`, `pnpm install --frozen-lockfile`, and so on, and `bundle install` for Jekyll. Empty when there is nothing to install. |
3539 | `build` | What builds it: your command, the package's `build` script (`npm run build`), the framework's own command, or `wrangler deploy --dry-run` for Workers. Empty when nothing does. |
3640 | `output-dir` | The folder served, relative to the project (`.` for the project itself): yours, a Workers project's assets directory, the folder the framework writes, or the first of `dist`, `build`, `out`, `public`, `_site`, `.output/public` that exists. Empty when a build has yet to write it, as for a Cloudflare adapter's Worker. |
3741
38−When `kind` is `none` because of how a framework is set up, such as a
39−Next.js app without `output: 'export'`, the step's log says what to
40−change.
42+When `kind` is `none`, the step's log says what to change or add, such as
43+a `Dockerfile`. [Docker deployments](https://docs.g1t.sh/guides/deployments/#docker-deployments)
44+has the order in which a project's kind is decided.
4145
4246 ## Frameworks
4347
+18−2
1515 description: An output folder of your own, as g1t/deploy takes it.
1616 required: false
1717 default: ""
18+ build-as:
19+ description: What it is built as, auto, static, workers or docker, as g1t/deploy takes it.
20+ required: false
21+ default: ""
22+ dockerfile:
23+ description: A Dockerfile's path of your own, as g1t/deploy takes it.
24+ required: false
25+ default: ""
1826
1927 outputs:
2028 kind:
21− description: workers (a Wrangler config, or a framework's Cloudflare adapter), static (a site a build writes), html (the files as they are) or none (nothing to serve, or a framework set up to need a server).
29+ description: workers (a Wrangler config, or a framework's Cloudflare adapter), static (a site a build writes), html (the files as they are), container (a Dockerfile, a framework set up to need a server, or a server g1t writes a Dockerfile for) or none (nothing to serve).
2230 value: ${{ steps.detect.outputs.kind }}
2331 install:
2432 description: How its dependencies are installed, such as npm ci. Empty without a package.json.
3038 description: The folder that is served, relative to the project (. for the project itself). Empty when a build has yet to write it.
3139 value: ${{ steps.detect.outputs.output-dir }}
3240 framework:
33− description: The framework it is built with, such as vite, astro, nextjs, sveltekit or hugo. Empty when there is none.
41+ description: The framework it is built with, such as vite, astro, nextjs, sveltekit or hugo; for a container without one, dockerfile or the server g1t writes a Dockerfile for (node, flask, rails…). Empty when there is none.
3442 value: ${{ steps.detect.outputs.framework }}
43+ dockerfile:
44+ description: A container's own Dockerfile, relative to the project. Empty when g1t writes one, or for anything else.
45+ value: ${{ steps.detect.outputs.dockerfile }}
46+ port:
47+ description: The port a container listens on, its Dockerfile's EXPOSE or 8080. Empty for anything else.
48+ value: ${{ steps.detect.outputs.port }}
3549
3650 runs:
3751 using: composite
4256 ROOT_DIR: ${{ inputs.root-dir }}
4357 BUILD_COMMAND: ${{ inputs.build-command }}
4458 OUTPUT_DIR: ${{ inputs.output-dir }}
59+ BUILD_AS: ${{ inputs.build-as }}
60+ DOCKERFILE: ${{ inputs.dockerfile }}
4561 run: |
4662 set -euo pipefail
4763 runner="$(bash "$GITHUB_ACTION_PATH/runner.sh")"
+1−1
8181 DeploymentsOp::CreateDeploymentStatus => "Add a status to a reported deployment: state (queued, in_progress, success, failure, error or inactive), description, environment_url (where it is served) and log_url (where its output can be read). The deployment takes its state, and any address it gives. A success with auto_inactive (true unless you say) makes the environment's older successful deployments inactive. The commit's `deploy / <environment>` check follows: pending while queued or in progress, then success, failure or error. A g1t.page build's statuses come from the build and cannot be added to. Needs the Write role.",
8282 DeploymentsOp::ListEnvironments => "List the environments a repository's deployments went to, those people use directly first (production by name before others), then the most recently deployed, and after them those with protection rules but no deployment yet. Each has its name, url (where its current deployment is served), production_environment, transient_environment, deployments_count, latest (its newest deployment, whatever its state), current (its newest successful deployment that is still active) and updated_at, and, when it has rules, protection_rules (required_reviewers, wait_timer, branch_policy), deployment_branch_policy, branch_policies and can_admins_bypass. total_count counts deployments across every environment. Needs the Read role.",
8383 DeploymentsOp::GetEnvironment => "Get one environment by name, matched without regard to case, with its current and latest deployments and its protection rules (see update_environment). An environment with rules but no deployment yet is found too. A name with slashes is URL-encoded in the path. Needs the Read role.",
84− DeploymentsOp::StartDeploymentBuild => "From a running g1t Actions job, open a g1t.page build of one of the repository's projects, which the job then builds in its own checkout with `g1t-runner deploy` (the g1t/deploy action does both). Only the job's own token (G1T_TOKEN) may call it, with `deployments: write` (or `pages: write`) in its `permissions:`. project is the project's slug; it may be left out when the repository has one project with Deployments on. The run decides what is built: a run on the project's production branch (a push, a dispatch or a schedule there) builds production, a pull request's run builds that pull request's preview, and a run on another branch builds that branch's preview; a tag's run is refused. sha is the commit built, the run's unless you say. A pull request from a fork or from someone without the Write role, and a run that had to be approved, get no build secrets. The workspace's plan must include Deployments and its spend limit must not be reached; the build's time is the job's Actions time and is not charged again. Returns deploy_id and token (DEPLOY_ID and DEPLOY_TOKEN for `g1t-runner deploy`, the token good for this build alone until it finishes), kind (production or preview), project, branch, number, commit, url (the app's address), trusted, the project's root_dir, build_command and output_dir, and build_env and build_secrets (the project's variables and secrets for builds of that kind). The commit's `g1t / deploy` check is pending until the build reports.",
84+ DeploymentsOp::StartDeploymentBuild => "From a running g1t Actions job, open a g1t.page build of one of the repository's projects, which the job then builds in its own checkout with `g1t-runner deploy` (the g1t/deploy action does both). Only the job's own token (G1T_TOKEN) may call it, with `deployments: write` (or `pages: write`) in its `permissions:`. project is the project's slug; it may be left out when the repository has one project with Deployments on. The run decides what is built: a run on the project's production branch (a push, a dispatch or a schedule there) builds production, a pull request's run builds that pull request's preview, and a run on another branch builds that branch's preview; a tag's run is refused. sha is the commit built, the run's unless you say. A pull request from a fork or from someone without the Write role, and a run that had to be approved, get no build secrets. The workspace's plan must include Deployments and its spend limit must not be reached; the build's time is the job's Actions time and is not charged again. Returns deploy_id and token (DEPLOY_ID and DEPLOY_TOKEN for `g1t-runner deploy`, the token good for this build alone until it finishes), kind (production or preview), project, branch, number, commit, url (the app's address), trusted, the project's root_dir, build_command and output_dir, build_as (auto, static, workers or docker) and dockerfile (its Dockerfile's path, or null to find `Dockerfile` or `Containerfile`), and build_env and build_secrets (the project's variables and secrets for builds of that kind). The commit's `g1t / deploy` check is pending until the build reports.",
8585 }
8686 }
8787
+8−4
549549 }
550550
551551 // A sandbox building a deployment, reporting with its build's token,
552− // which is not a g1t token. The body goes through as it is: it can
553− // carry a Worker's bundled code.
552+ // which is not a g1t token, or a container app's Worker reporting how
553+ // long its container ran, with its own token. The body goes through as
554+ // it is: it can carry a Worker's bundled code.
554555 if method == "POST" && !on_mcp
555− && let Some(rest) = path.strip_prefix("/deployments/jobs/")
556+ && let Some(rest) = path
557+ .strip_prefix("/deployments/jobs/")
558+ .map(|rest| format!("jobs/{rest}"))
559+ .or_else(|| path.strip_prefix("/deployments/apps/").filter(|rest| rest.ends_with("/meter")).map(|rest| format!("apps/{rest}")))
556560 {
557− let target = format!("https://deployments/jobs/{rest}");
561+ let target = format!("https://deployments/{rest}");
558562 let body = request.bytes().await?;
559563 let headers = worker::Headers::new();
560564 headers.set("content-type", "application/json")?;
+2−0
1188911889 "root_dir": "",
1189011890 "build_command": null,
1189111891 "output_dir": null,
11892+ "build_as": "auto",
11893+ "dockerfile": null,
1189211894 "build_env": {
1189311895 "PUBLIC_API_URL": "https://api.example.com"
1189411896 },
+29−9
364364
365365 ## Deployments
366366
367−### Static sites and Workers only
367+### Containers are not switched on yet
368368
369−Deployments run static sites and Workers projects. You can't deploy a
370−long-running server, a container, or an app that needs a process that stays
371−up.
369+[Docker deployments](/guides/deployments/#docker-deployments) are built,
370+but off on g1t.page: a project that runs as a container fails to deploy,
371+saying so, and one with a site besides its `Dockerfile` is built as that
372+site.
372373
373−- **Why.** Apps run on Cloudflare Workers, which run only while they answer a
374− request. That is why an app nobody visits costs nothing.
374+- **Why.** Cloudflare's container APIs (applications in a Workers for
375+ Platforms namespace, registry logins) have to be checked against g1t's
376+ own account first.
375377 - **Instead.** Build a framework app as a static export or with its
376378 Cloudflare adapter, as [Frameworks](/guides/deployments/#frameworks)
377− lists; a build set up to need a server fails and says which. Or deploy
378− the server from a workflow to wherever it runs today, with its
379− credentials in [secrets](/guides/secrets-and-variables/).
379+ lists, or set **Build as** to Static site. Or deploy the server from a
380+ workflow to wherever it runs today, with its credentials in
381+ [secrets](/guides/secrets-and-variables/).
382+
383+### A container is one instance, and keeps nothing
384+
385+A container app runs one instance at a time, sleeps after five minutes
386+without a request, and starts from its image each time it wakes.
387+
388+- **Why.** Each app's container is one Durable Object's, and Cloudflare
389+ Containers' disks last only as long as the container runs.
390+- **Instead.** Keep data in a database or a bucket the app reaches over
391+ the network. A larger **Container size** gives one instance more room.
392+
393+### What a container sends out is not counted
394+
395+The data a container sends back to visitors is metered; what it sends to
396+other hosts on the internet (a database elsewhere, an API) is not.
397+
398+- **Why.** It leaves the container without passing through g1t.
399+- **Instead.** Nothing to do: it is not charged.
380400 - **Status.** A runtime for servers is planned.
381401
382402 ### Some Workers bindings are not provisioned
+58−0
344344 nothing else expires in the bucket. Reset deletes the agent's object at
345345 once.
346346
347+## Docker deployments
348+
349+Container apps ([Docker deployments](/guides/deployments/#docker-deployments))
350+are off until `CONTAINERS` is `on` in `services/deployments/wrangler.jsonc`.
351+The code follows Cloudflare's documentation and Wrangler's own client for
352+these APIs, but none of them has been called against g1t's account yet.
353+Before turning it on, check each of these with a test project:
354+
355+1. **The token.** `CLOUDFLARE_API_TOKEN` of `services/deployments` has
356+ **Containers: Edit** (and the account has Containers, on Workers Paid).
357+2. **Registry logins.**
358+ `POST /accounts/{id}/containers/registries/registry.cloudflare.com/credentials`
359+ with `{ "permissions": ["push"], "expiration_minutes": 15 }` answers
360+ inside the API's usual `{ success, result }` with a `username` and
361+ `password`, and `docker push` succeeds with that login alone, with no
362+ `pull` (Docker checks for layers before it uploads them). If it needs
363+ `pull`, do not add it: a pull login reads every app's image. Find
364+ another way first, such as Cloudflare scoping logins to a repository.
365+3. **The registry's hosts.** A push from a guarded sandbox reaches only
366+ `registry.cloudflare.com` (on the deploy builds' list in
367+ `services/runner/src/egress.ts`). If its layers upload to another host,
368+ add that host there.
369+4. **Checking a digest.** g1t asks
370+ `HEAD https://registry.cloudflare.com/v2/<account>/g1t-<app>/manifests/sha256:…`
371+ with a pull login of its own, following a `WWW-Authenticate: Bearer`
372+ challenge. It answers 200 for an image that was pushed.
373+5. **The app's Worker.** A script uploaded to the dispatch namespace with
374+ `exports: { "G1tApp": { "type": "durable-object", "storage": "sqlite" } }`
375+ and `containers: [{ "class_name": "G1tApp" }]` in its metadata is taken,
376+ and taken again on the next deploy with nothing changed about the class.
377+6. **Its Durable Object namespace.**
378+ `GET /accounts/{id}/workers/durable_objects/namespaces` lists it with
379+ `class` `G1tApp`, `script` the app's name and `dispatch_namespace`
380+ `g1t-deployments`.
381+7. **The Container application.** `POST /accounts/{id}/containers/applications`
382+ with `scheduling_policy` `default`, the image by digest, `instance_type`,
383+ `max_instances` 1 and `durable_objects.namespace_id` creates it; a
384+ rollout (`…/rollouts`, `strategy` `rolling`, `step_percentage` 100,
385+ `kind` `full_auto`) moves it to a new image; `DELETE` removes it.
386+8. **Starting.** `ctx.container.start({ env, enableInternet: true })`
387+ works under the default policy from a Worker in a dispatch namespace,
388+ the container gets its environment, and `getTcpPort(port).fetch()`
389+ reaches it; the dispatcher's limits (50 ms of CPU, 50 subrequests) leave
390+ room for a page that waits on a container starting.
391+9. **Sleeping and billing.** Five minutes after the last request the
392+ container stops (the app's object stops it itself), Cloudflare's billable
393+ usage for Containers stops growing, and `container_meters` in the
394+ deployments database has the minutes the app's Worker reported, which
395+ should be at least what Cloudflare billed for the same time.
396+10. **Pausing and taking down.** A workspace over its limit gets its
397+ container app's Worker put back paused, which stops the container, and
398+ taking an app down deletes its application before its Worker.
399+
400+Then set `CONTAINERS` to `on`, deploy `services/deployments`, and the
401+container build of a project with a `Dockerfile` goes live; the
402+[limitations page](/about/limitations/#containers-are-not-switched-on-yet)
403+and the caution in the deployments guide come out in the same change.
404+
347405 ## Rolling back
348406
349407 - **One unit, at once:** `npx wrangler rollback` in its folder. Revert the
+226−27
1111 deploys nothing while the remote leads it: pushes copied in from the remote
1212 don't build, and its **Deployments** page comes with a takeover.
1313
14−Apps run on Cloudflare Workers, on `g1t.page`:
14+Apps run on Cloudflare Workers, on `g1t.page`, and a project with a
15+`Dockerfile` (or a server g1t can write one for) runs as a container on
16+Cloudflare Containers behind one; see [Docker deployments](#docker-deployments):
1517
1618 | | Address |
1719 | --- | --- |
5052 report your own, and hear of them by webhook.
5153
5254 An app runs only while it answers a request. One nobody visits runs
53−nothing and costs nothing, and the next visit wakes it in milliseconds.
55+nothing and costs nothing, and the next visit wakes it in milliseconds. A
56+container wakes in seconds, and sleeps again after five minutes without a
57+request.
5458
5559 Deployments are part of the [g1t plan](/guides/usage-and-billing/#the-g1t-plan),
5660 and are opt-in per project. A project set to deploy on g1t, with
96100 | --- | --- |
97101 | `wrangler.jsonc`, `wrangler.json` or `wrangler.toml` | Builds it as a **Workers project**: installs dependencies, runs `wrangler deploy --dry-run` to bundle it (which runs the config's own `build` command), and deploys the bundle with the config's static assets, `compatibility_date`, `compatibility_flags` and `vars`. |
98102 | A framework from the table below | Installs dependencies, builds it with the framework's command, and serves the folder it writes as a **static site**, or deploys the Worker its Cloudflare adapter writes as a **Workers project**. |
103+| A framework set up to need a server (Next.js without a static export, Astro's `@astrojs/node`, SvelteKit's `adapter-node`, a server-rendered React Router or Remix app) | Builds it as a **container**: from its `Dockerfile`, or one g1t writes for it. |
104+| A `Dockerfile` or `Containerfile`, and no framework above | Builds the image and runs it as a **container**. |
105+| A Node.js, Python, Go, Ruby or PHP server, with no `Dockerfile` | Writes a Dockerfile for it, shows it in the build's log, and runs it as a **container**. See [Docker deployments](#docker-deployments). |
99106 | A `build` script in `package.json` | Installs dependencies, runs `npm run build`, and serves the output as a **static site**. |
100107 | An `index.html` and nothing to build | Serves it as it is. |
108+| Nothing g1t recognises | Fails, saying to add a `Dockerfile`. |
101109
102110 **Settings → Deployments** shows what g1t detected at the project's last
103−finished build (**Workers project**, **Static site** or **Plain HTML**),
104−and what running it costs. Before the first build it says **Detected at
105−the first build**. The framework is named at the top of the build's log,
106−as `Detected Astro: framework=astro.`
111+finished build and what it was built with, such as **Static site ·
112+Astro**, **Workers project**, **Container · Dockerfile** or **Container ·
113+Flask, with a Dockerfile g1t wrote**, and what running it costs. Before
114+the first build it says **Detected at the first build**. The framework is
115+named at the top of the build's log, as `Detected Astro: framework=astro.`
116+**Build as**, under the same settings, overrides what is detected.
107117
108118 Dependencies are installed by the lockfile that is there: `npm ci`,
109119 `pnpm install --frozen-lockfile`, `yarn install` or `bun install`, and
138148 | Jekyll | `_config.yml` and a `Gemfile` | `bundle install`, then `bundle exec jekyll build` | `_site`, or `destination` |
139149 | mdBook | `book.toml` | `mdbook build` | `book`, or `build.build-dir` |
140150
141−- **Frameworks that need a server fail early, saying what to change.**
142− g1t.page runs static sites and Workers, not servers that stay up. A
143− Next.js app without `output: 'export'`, an Astro site with
144− `output: 'server'` and no Cloudflare adapter, a SvelteKit app with
145− `adapter-auto` or `adapter-node`, and a React Router or Remix app that
146− renders on the server each fail before anything is installed, with the
147− change that makes them deploy: a static export, or the framework's
148− Cloudflare adapter. An **Output directory** of your own skips the check.
151+- **Frameworks that need a server run as containers.** A Next.js app
152+ without `output: 'export'`, an Astro site with `@astrojs/node`, a
153+ SvelteKit app with `adapter-node`, and a React Router or Remix app that
154+ renders on the server are built from their `Dockerfile`, or one g1t
155+ writes ([Docker deployments](#docker-deployments)). A static export or
156+ the framework's Cloudflare adapter costs less, since it runs nothing
157+ while no one visits; the build's log says so. One g1t cannot run as a
158+ server, such as SvelteKit with `adapter-auto`, fails before anything is
159+ installed, saying what to change or to add a `Dockerfile`. An **Output
160+ directory** of your own, or **Build as** Static site, builds it as a
161+ static site instead.
149162 - **A framework's Worker.** Astro's and SvelteKit's Cloudflare adapters,
150163 OpenNext, and `@cloudflare/vite-plugin` with a Wrangler config build a
151164 Worker. g1t runs the build, then bundles what it wrote with
192205 lists each one it left out. Code that needs them should check that the
193206 binding is there.
194207
195−What Deployments cannot run yet, such as long-running servers, is on
208+### Docker deployments
209+
210+Any app that runs in a container deploys as one, whatever its framework or
211+age: give it a `Dockerfile`, or let g1t write one. It runs on
212+[Cloudflare Containers](https://developers.cloudflare.com/containers/)
213+behind the app's Worker, at the same addresses, custom domains and
214+previews as any other app.
215+
216+:::caution[Not switched on yet]
217+Docker deployments are built but off on g1t.page until Cloudflare's
218+container APIs are checked against g1t's account. Until then a container
219+build fails with "Docker deployments are not switched on for g1t.page
220+yet", and a project that is a container only for having a `Dockerfile`,
221+beside a site g1t could serve, is built as that site, as before.
222+:::
223+
224+What a project is built as is decided in this order:
225+
226+1. **Build as**, under **Settings → Deployments**: **Static site**,
227+ **Workers** or **Docker** is what it is built as, whatever else it has.
228+2. **Auto** (the default) finds it from its files:
229+ 1. A Wrangler config is a Workers project.
230+ 2. A framework that builds a static site or a Worker is that, even
231+ beside a `Dockerfile`: it costs nothing while no one visits.
232+ 3. A framework set up to need a server is a container, from its
233+ `Dockerfile`, or one g1t writes for it.
234+ 4. A project with no framework g1t knows is a container when it has a
235+ `Dockerfile` (or `Containerfile`, or the path set as its
236+ **Dockerfile**), or is a server g1t recognises.
237+ 5. Otherwise a static site or plain HTML, as above; with nothing to
238+ serve, the build fails, saying to add a `Dockerfile`.
239+
240+g1t writes a Dockerfile for these, when there is none:
241+
242+| The project has | Runs with |
243+| --- | --- |
244+| `package.json` with a `start` script, or a server package (`express`, `fastify`, `koa`, `@nestjs/core`, `@hono/node-server` and others) and a main file | `npm start`, or `node <main>`, on `node:22-slim` (or the major release in `.nvmrc` or `.node-version`), after `npm run build` when there is one |
245+| Next.js, Astro with `@astrojs/node`, SvelteKit with `adapter-node`, React Router or Remix | `next start`, `node ./dist/server/entry.mjs`, `node build`, `react-router-serve` or `remix-serve`, after the build |
246+| `requirements.txt`, `pyproject.toml` or `Pipfile`, and `manage.py` (Django) | `gunicorn <project>.wsgi` on `python:3.12-slim` |
247+| The same, with Flask and an `app.py`, `main.py`, `server.py`, `wsgi.py` or `asgi.py` | `gunicorn <module>:app` |
248+| The same, with FastAPI or Starlette | `uvicorn <module>:app` |
249+| The same, with neither | `python <module>.py` |
250+| `go.mod` and one `package main`, at the top or in one folder of `cmd/` | The program, built with `golang:1.25` into an image with nothing else |
251+| A `Gemfile` with Rails | `rails server`, after `assets:precompile`, on `ruby:3.3-slim` |
252+| A `Gemfile` and a `config.ru` | `rackup` |
253+| `composer.json`, and `artisan` with `public/index.php` (Laravel), or an `index.php` | Apache with PHP 8.3, after `composer install` |
254+
255+The Dockerfile g1t writes is printed whole in the build's log. To change
256+how the app is built or run, commit it as `Dockerfile` and edit it. It
257+leaves `.git`, `node_modules`, `.venv` and `__pycache__` out of the image.
258+
259+What a container gets, and what it must do:
260+
261+- **Listen on `0.0.0.0` at `PORT`.** `PORT` is the port its Dockerfile's
262+ first `EXPOSE` names (in its last stage), else `8080`. The first request
263+ waits up to 90 seconds for it to answer there; one that never does gets
264+ a 503 page saying so.
265+- **The project's [secrets and variables](#secrets-and-variables)** are
266+ its environment variables, set by g1t when it starts, never baked into
267+ the image. The image's build gets none of them: a step that needs one
268+ belongs in the app's start.
269+- **One instance, which sleeps.** It starts on the first request, and
270+ stops after five minutes without one; asleep, it costs nothing, and the
271+ next request starts it again in a few seconds. Its disk starts from the
272+ image each time: keep data in a database or a bucket.
273+- **Its size** is **Container size** under **Settings → Deployments**:
274+ `lite` (the default) to `standard-4`, as [What it costs](#what-it-costs)
275+ lists. The image may be as large as the size's disk, 2 GB for `lite`;
276+ a larger image fails the build, saying how large it was.
277+- **Built for `linux/amd64`**, with Docker, in the build's sandbox (or the
278+ workflow job's Docker, for [`g1t-runner deploy`](#deploying-from-a-workflow)),
279+ with network access as any build has. **Build command** is not used:
280+ the Dockerfile builds it.
281+
282+What Deployments cannot run yet is on
196283 [What g1t can't do yet](/about/limitations/#deployments).
197284
198285 ## Previews of branches
538625 | --- | --- | --- |
539626 | Production | On | Deploy the default branch on every push. |
540627 | Previews | On | A preview for every branch with an open pull request. |
541−| Build command | The project's own | Runs instead of `npm run build`, or before bundling a Workers project. |
628+| Build as | Auto | **Auto** (found from its files), **Static site**, **Workers** or **Docker**; see [Docker deployments](#docker-deployments). |
629+| Dockerfile | `Dockerfile` or `Containerfile` | For a container: its Dockerfile's path, inside the project. |
630+| Container size | `lite` | For a container: the instance it runs at, with its price an hour awake. |
631+| Build command | The project's own | Runs instead of `npm run build`, or before bundling a Workers project. Not used for a container. |
542632 | Output directory | Found by itself | What a static site serves. |
543633 | Idle days | 7 | 1 to 90. A preview no one visits this long comes down. |
544634 | Build with a workflow | Off | Build through the deploy workflow g1t manages for the project; see [build with a workflow](#build-with-a-workflow). |
556646
557647 The build gets them as environment variables, with secrets hidden in its
558648 log. The running app gets them as bindings, `env.KEY`, put in place by g1t
559−rather than the build. Secrets reach a preview only when the pull
649+rather than the build; a container gets them as its environment variables
650+when it starts, and its image's build gets none. Secrets reach a preview only when the pull
560651 request's author has Write or higher on the repository, whether a member
561652 or an [outside collaborator](/guides/access-and-roles/#outside-collaborators),
562653 or it is g1t working on its own. For a pull request g1t made, whoever
586677 | Requests, to all of the workspace's apps | $0.30 a million | $0.36 a million |
587678 | CPU time your code spends computing (waiting on the network is not counted) | $0.02 a million ms | $0.024 a million ms |
588679 | Custom domains, with their certificates (a www/apex pair is two) | $0.10 a month | $0.12 a month, by the most the workspace had at once that month |
680+| A container, while it is awake, by the minute (see the sizes below) | From $0.0129 an hour (`lite`) | From $0.0155 an hour |
681+| Data a container sends | $0.05 a GB, at most | $0.06 a GB |
589682
590−Builds are charged when they finish. Requests, CPU time and custom domains
591−are counted through the month, so your limit and **Billing** follow them as
592−they happen, and charged once, on the first sweep after the month ends, as
593−one line: *Deployments in 2026-10: 1,240,000 requests, 3,100,000 CPU ms, 2
594−custom domains*.
683+A container's price is its size's memory, disk and vCPU while it is awake,
684+with the Durable Object in front of it, at Cloudflare's
685+[Containers prices](https://developers.cloudflare.com/containers/platform/pricing/)
686+plus 20%. Cloudflare bills CPU only as it is used; g1t charges every vCPU
687+as busy while the container is awake, so a container that mostly waits
688+costs g1t less than it is charged. Data sent is charged at the most a GB
689+costs anywhere ($0.05; $0.025 in North America and Europe), since g1t
690+cannot tell where it went. Each minute it is awake is charged from its
691+start, so a container woken by one request, and stopped five minutes after
692+it, is charged five minutes.
693+
694+| Size | vCPU | Memory | Disk, and the largest image | An hour awake | Awake all month (730 hours) |
695+| --- | --- | --- | --- | --- | --- |
696+| `lite` | 1/16 | 256 MiB | 2 GB | $0.0155 | $11.28 |
697+| `basic` | 1/4 | 1 GiB | 4 GB | $0.0404 | $29.46 |
698+| `standard-1` | 1/2 | 4 GiB | 8 GB | $0.0956 | $69.77 |
699+| `standard-2` | 1 | 6 GiB | 12 GB | $0.1616 | $117.95 |
700+| `standard-3` | 2 | 8 GiB | 16 GB | $0.2708 | $197.68 |
701+| `standard-4` | 4 | 12 GiB | 20 GB | $0.4880 | $356.24 |
702+
703+**Settings → Deployments** shows these with the price book's prices of the
704+day. A container that is visited all day never sleeps, and costs the last
705+column; one visited for an hour a day costs about a thirtieth of it.
595706
707+Builds are charged when they finish. Requests, CPU time, custom domains
708+and container time are counted through the month, so your limit and
709+**Billing** follow them as they happen, and charged once, on the first
710+sweep after the month ends, as one line: *Deployments in 2026-10:
711+1,240,000 requests, 3,100,000 CPU ms, 2 custom domains, 41.5 container
712+hours and 2.3 GB sent*.
713+
596714 A static site, or plain HTML, runs no code when it is visited: its files
597715 are served as they are, so serving it adds no requests or CPU time. Its
598716 builds are metered. A Workers project's code runs on every request, so its
599−requests and CPU time are metered too.
717+requests and CPU time are metered too. A container's Worker is metered the
718+same way, and its container by the minute while it is awake.
600719
601720 An app that no one visits costs nothing. Previews still come down when
602721 their pull request closes and after their idle days, to keep the list of
603722 what is up short.
604723
605724 The only things that stop a workspace's apps are its own spend limit
606−(apps pause with a notice, and come back once there is room) and the plan
607−ending (they come down).
725+(apps pause with a notice, and come back once there is room; a paused
726+container is stopped and starts no more) and the plan ending (they come
727+down).
608728
609729 Deployments used to be a $5 plan of their own. A Deployments subscription
610730 bought before keeps working until its current period ends, and is not
653773 upload them and nothing else. Files Cloudflare already has are skipped.
654774 4. The sandbox sends the Worker's code to g1t, which puts the app in
655775 g1t's [Workers for Platforms](https://developers.cloudflare.com/cloudflare-for-platforms/workers-for-platforms/)
656− namespace, under the name in its address.
776+ namespace, under the name in its address. A container build goes as
777+ [below](#containers).
657778 5. A request to `*.g1t.page` reaches g1t's dispatcher, which runs the app
658779 by the name in the hostname. Nothing else is looked up. A request to a
659780 custom domain reaches the same dispatcher through Cloudflare for SaaS;
663784 `g1t.page`, not `g1t.sh`, so they share no cookies or origin with the site
664785 you sign in to.
665786
787+### Containers
788+
789+1. The build finds it is a container, and asks g1t where to push its
790+ image (the build's `registry` step). g1t mints a login to Cloudflare's
791+ registry, `registry.cloudflare.com`, that can **push only** and lasts
792+ **15 minutes**, and names the app's own repository,
793+ `<account>/g1t-<app>`, with the build's id as its tag. Asked before
794+ anything is built, so a build that could not push is not run.
795+2. The sandbox starts a Docker Engine of its own (as a workflow job's),
796+ builds the image for `linux/amd64`, checks its size against the
797+ container size's disk, pushes it with that login, and reports the
798+ image by its digest.
799+3. g1t runs only an image by digest in that app's repository, and asks
800+ the registry, with a pull login of its own, that the digest is there.
801+ It puts the app's Worker in the namespace: g1t's own code, never the
802+ project's, with a Durable Object class that holds the container, the
803+ project's secrets and variables, and a token for the app to report its
804+ running time with. Then it creates the app's Container application
805+ (at most one instance, at the project's size, attached to that class),
806+ or rolls it out to the new image.
807+4. A request reaches the app's Worker through the dispatcher, as any
808+ app's does. The Worker hands it to the app's Durable Object, which
809+ starts the container if it is asleep, with the environment, waits for
810+ it to answer on its port, and passes the request to it. Every minute it
811+ is awake, the object charges the next minute ahead and reports it to g1t
812+ (`POST /deployments/apps/<app>/meter` on the API, with its token); five
813+ minutes after the last request it stops the container.
814+5. A preview's container comes down with its pull request, its
815+ application and Worker deleted together.
816+
817+Why it is built this way, from Cloudflare's documentation and Wrangler's
818+own code (October 2026):
819+
820+- **Workers for Platforms runs containers.** A user Worker in a dispatch
821+ namespace may bind Containers, as a Durable Object
822+ ([WfP bindings](https://developers.cloudflare.com/cloudflare-for-platforms/workers-for-platforms/configuration/bindings/)).
823+ Wrangler's `deploy --dispatch-namespace` deploys containers by finding
824+ the Durable Object namespace of the class in that dispatch namespace and
825+ creating a Container application attached to it
826+ (`POST /accounts/{id}/containers/applications`, with
827+ `durable_objects.namespace_id`), then rolling out new images
828+ (`…/applications/{id}/rollouts`). So each app is a Worker of its own,
829+ with a class of its own, isolated as every app is, and the dispatcher
830+ routes to it unchanged. A single host Worker of g1t's could not run every
831+ app's image: a Durable Object starts only the images its Worker's
832+ configuration names.
833+- **The default scheduling policy.** It takes one image and size for the
834+ whole application, set through the API, which suits one app per
835+ application; the `durable_object` policy is in beta, and needs the
836+ image map uploaded with the Worker.
837+- **Registry logins.** Cloudflare mints registry credentials with
838+ `POST /accounts/{id}/containers/registries/registry.cloudflare.com/credentials`
839+ and `{ "permissions": ["push"], "expiration_minutes": 15 }`, as Wrangler
840+ does for its own pushes. They cannot be held to one repository, so g1t
841+ holds the build to its app's: it names the repository, runs nothing but a
842+ digest in it, and never gives a build a login that can pull, so no build
843+ can read another app's image. g1t's own Cloudflare token never reaches
844+ the sandbox.
845+- **Sizes and limits.** Containers' instance types are `lite` (1/16 vCPU,
846+ 256 MiB, 2 GB) through `standard-4` (4 vCPU, 12 GiB, 20 GB); an image
847+ may be as large as its instance's disk, and an account holds 50 GB of
848+ images ([limits](https://developers.cloudflare.com/containers/platform/limits/)).
849+- **Scale to zero.** Containers are billed every 10 ms while running, and
850+ stop being billed once asleep. The Durable Object stops its container
851+ itself after five minutes without a request, rather than leaving it to
852+ the inactivity timeout, since the object's own minute alarm, which
853+ meters it, would otherwise keep it awake.
854+
666855 ## Troubleshooting
667856
668857 | You see | Do |
671860 | A deployment **Skipped**, saying it reached its spend limit or that new compute is paused | The build was refused before it started. Follow the link in the message: raise the spend limit, prepay, or answer the spike, on Billing. |
672861 | "Stopped: unusual CPU use" | The build looked like it was mining. Contact support if it was a real build; see [abuse and mining](/guides/guardrails/#abuse-and-mining). |
673862 | "403" from a host in the build log | The build's network is restricted. Add the host to the project's allowed domains under **Settings → Guardrails**. |
674−| "found nothing to serve" | Add a `build` script, an `index.html`, or a Workers config; or set **Output directory**. |
863+| "found nothing to serve" | Add a `Dockerfile`, a `build` script, an `index.html`, or a Workers config; or set **Output directory**. |
864+| "Docker deployments are not switched on for g1t.page yet" | The project is a container, which g1t.page does not run yet. Set **Build as** to Static site or Workers if it can be built as one. See [Docker deployments](#docker-deployments). |
865+| "**Build as** is Docker, but this project has no Dockerfile" | Add a `Dockerfile`, or set **Dockerfile** to its path. |
866+| "The image is 2.4 GB, more than the 2.0 GB an app of its size (lite) can hold" | Make the image smaller (a slim base image, a multi-stage build), or choose a larger **Container size**. |
867+| A container app says "The app did not start" | It did not answer on its port within 90 seconds. Make it listen on `0.0.0.0` at `PORT`, or `EXPOSE` the port it uses in its Dockerfile. Its output is in the build's log only while it builds; run the image locally with `docker run -e PORT=8080 -p 8080:8080` to see it start. |
675868 | "the output directory `x` does not exist after the build" | The build wrote elsewhere: check its log, then fix **Output directory**. |
676869 | "`d1_databases` is not provisioned on g1t.page yet" | The app deployed without that binding. See [Workers projects](#workers-projects). |
677870 | "`triggers.crons` (1 schedule) is not set up on g1t.page yet" | The app deployed, but its `scheduled` handler never runs. See [Workers projects](#workers-projects). |
698891 `npx wrangler secret put CLOUDFLARE_API_TOKEN` in `services/deployments`.
699892 4. Deploy `services/deployments`, `services/pages`, and the runner.
700893
894+Docker deployments also need the token to have **Containers: Edit**, a
895+Workers Paid plan with Containers, and `CONTAINERS` set to `on` in
896+`services/deployments/wrangler.jsonc`; see
897+[Docker deployments](/guides/deploy-to-cloudflare/#docker-deployments)
898+for what to check first.
899+
701900 Custom domains also need Cloudflare for SaaS on the apps' zone. Turn it on
702901 under the zone's **SSL/TLS → Custom Hostnames**, give the token **SSL and
703902 Certificates: Edit** on the zone, and run `scripts/setup-custom-domains.sh`:
+5−2
157157 | App requests | Million | $0.30 | $0.36 |
158158 | App CPU time | Million CPU milliseconds | $0.02 | $0.024 |
159159 | Custom domains | Domain-month | $0.10 | $0.12 |
160+| [Container apps](/guides/deployments/#docker-deployments), while awake | Second, by the minute: vCPU, memory, disk and the Durable Object, by the size | From $0.0129 an hour (`lite`) | Cost + 20%: from $0.0155 an hour |
161+| Data container apps send | GB | $0.05 | $0.06 |
160162 | Private storage, past the free 1 GB | GB-month | $0.50 | $0.60 |
161163 | [Actions cache](#actions-cache) storage | GB-month | $0.015 | $0.018 |
162164 | Git operations, past the free 50,000 a month | 1,000 | $0.15 | $0.18 |
299301 | The [merge queue](/guides/merge-queue/) | [Sandbox time](#sandbox-time) |
300302 | [Workflow](/guides/actions/) jobs | [Sandbox time](#sandbox-time), more on a [larger machine](#workflow-jobs-on-larger-machines) |
301303 | [Actions cache](#actions-cache) | What it holds, on the plan only |
302−| [Deployments](/guides/deployments/) | Builds, requests, CPU time and custom domains, from the first. Projects and previews are not charged. |
304+| [Deployments](/guides/deployments/) | Builds, requests, CPU time, custom domains and container time, from the first. Projects and previews are not charged. |
303305 | [Private repository storage](#storage-search-embeddings-and-scans) | Past the free 1 GB, on the plan only |
304306 | [Git operations](#git-operations) | Past the free 50,000 a month, on the plan only |
305307 | [Search embeddings](#storage-search-embeddings-and-scans) | For private text, on the plan only |
374376 | Deploy builds | Per second |
375377 | App requests and CPU | Per million requests, per million CPU milliseconds |
376378 | Custom domains | Per domain-month |
379+| Container apps | Per vCPU-second, GiB-second of memory and GB-second of disk while awake, a second of the Durable Object in front of each, and per GB sent |
377380 | Private storage past the free 1 GB | Per GB-month |
378381 | Actions cache storage | Per GB-month |
379382 | Git operations past the free 50,000 a month | Per 1,000 |
10831086 | Runs on your own model provider | Older months only: the flat fee runs on your own provider used to carry. |
10841087 | Sandbox time | Each sandbox's time. |
10851088 | Self-hosted runner time | Each job on your own runners, at $0. |
1086− | Deployments | Builds as they finish; each month's requests, CPU time and custom domains when it closes. |
1089+ | Deployments | Builds as they finish; each month's requests, CPU time, custom domains and container time when it closes. |
10871090 | Private storage | Storage past the free 1 GB, once a month. |
10881091 | Actions cache storage | What `actions/cache` and artifacts held, on the plan, once a month. |
10891092 | Git operations | Operations past the free 50,000, once a month. |
+1−0
107107 | [Security](/guides/security/) | Secret push protection, history scanning and pull requests that upgrade vulnerable dependencies. | <Status is="live" /> |
108108 | [Deployments](/guides/deployments/) | A live preview of every pull request on g1t.page, production on merge, and custom domains. | <Status is="live" /> |
109109 | Preview data | Each preview gets its own copy of the database and bucket, deleted when the pull request closes. | <Status is="coming" /> |
110+| [Docker deployments](/guides/deployments/#docker-deployments) | Any app with a Dockerfile, or a Node.js, Python, Go, Ruby or PHP server, runs as a container that sleeps when no one visits. | <Status is="coming" /> |
110111 | Rollback and always on | One click back to any deploy, request logs, and container apps kept warm. | <Status is="coming" /> |
111112 | [GitHub](/guides/github/) and [mirroring](/guides/mirroring/) | Import repositories, keep them mirrored, or push changes back. | <Status is="live" /> |
112113 | Git over SSH | `git@g1t.sh` remotes. Use HTTPS until then. | <Status is="coming" /> |
+0−0

Binary or large file; its contents are not shown.

+19−0
1+import assert from "node:assert/strict";
2+import { test } from "node:test";
3+
4+import { detectedLabel, sizeLabel } from "./deploy-kind.ts";
5+
6+const NAMES = { astro: "Astro", dockerfile: "Dockerfile", flask: "Flask", nextjs: "Next.js" };
7+
8+test("what a build found is said with what it was built with", () => {
9+ assert.equal(detectedLabel("static", "astro", NAMES), "Static site · Astro");
10+ assert.equal(detectedLabel("container", "dockerfile", NAMES), "Container · Dockerfile");
11+ assert.equal(detectedLabel("container", "flask", NAMES), "Container · Flask, with a Dockerfile g1t wrote");
12+ assert.equal(detectedLabel("workers", null, NAMES), "Workers project");
13+ assert.equal(detectedLabel("html", "unknown", NAMES), "Plain HTML");
14+});
15+
16+test("a container size reads plainly", () => {
17+ assert.equal(sizeLabel({ vcpu: 1 / 16, memoryGib: 0.25, diskGb: 2 }), "1/16 vCPU, 256 MiB, 2 GB disk");
18+ assert.equal(sizeLabel({ vcpu: 2, memoryGib: 8, diskGb: 16 }), "2 vCPU, 8 GiB, 16 GB disk");
19+});
+47−0
1+/**
2+ * What Settings, Deployments says a project is, from its last build: its
3+ * kind and what it was built with (`Static site · Astro`, `Container ·
4+ * Dockerfile`), and what running it costs, in a line. No imports beyond
5+ * types, so it can be tested under Node.
6+ */
7+
8+import type { BuildAs, DetectedKind } from "@g1t/contracts";
9+
10+export const KIND_LABELS: Record<DetectedKind, string> = {
11+ static: "Static site",
12+ html: "Plain HTML",
13+ workers: "Workers project",
14+ container: "Container",
15+};
16+
17+export const KIND_COSTS: Record<DetectedKind, string> = {
18+ static: "Serving its files runs no code, so it adds no requests or CPU time. Builds are metered.",
19+ html: "Its files are served as they are and run no code, so serving adds no requests or CPU time. Builds are metered.",
20+ workers: "Its code runs on every request: requests and CPU time are metered, and so are builds.",
21+ container:
22+ "Its container runs only while it is awake: from the first request until it has had none for a few minutes, metered by the minute at its size, with what it sends. Builds are metered.",
23+};
24+
25+/** `Static site · Astro`, `Container · Dockerfile`, or the kind alone when nothing names what it was built with. */
26+export function detectedLabel(kind: DetectedKind, framework: string | null | undefined, names: Record<string, string>): string {
27+ const built = framework ? (names[framework] ?? null) : null;
28+ if (!built) return KIND_LABELS[kind];
29+ // A server g1t wrote a Dockerfile for says so.
30+ const written = kind === "container" && framework !== "dockerfile" ? `${built}, with a Dockerfile g1t wrote` : built;
31+ return `${KIND_LABELS[kind]} · ${written}`;
32+}
33+
34+/** The Build as choices, as the select shows them. */
35+export const BUILD_AS_OPTIONS: { value: BuildAs; label: string }[] = [
36+ { value: "auto", label: "Auto: found from its files" },
37+ { value: "static", label: "Static site" },
38+ { value: "workers", label: "Workers" },
39+ { value: "docker", label: "Docker" },
40+];
41+
42+/** `1/16 vCPU, 256 MiB, 2 GB disk`. */
43+export function sizeLabel(size: { vcpu: number; memoryGib: number; diskGb: number }): string {
44+ const vcpu = size.vcpu >= 1 ? String(size.vcpu) : `1/${Math.round(1 / size.vcpu)}`;
45+ const memory = size.memoryGib >= 1 ? `${size.memoryGib} GiB` : `${Math.round(size.memoryGib * 1024)} MiB`;
46+ return `${vcpu} vCPU, ${memory}, ${size.diskGb} GB disk`;
47+}
+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

This change is too large to show in full.