Skip to content

Part 11½ · Case Study — Shipping This Site to the Edge

The Part 11 capstone shipped Snip, a running HTTP service, down the heavyweight path: a container, a Kubernetes cluster, a canary rollout, an SLO-gated promotion. That is the right path when your artifact is a process that must keep running. But a huge share of what teams actually deploy is not a running process at all — it is static output: a docs site, a marketing site, a dashboard’s front-end, a blog. This Part is the other capstone. It takes a real, non-hypothetical artifact — the very book you are reading right now — and ships it from a commit to a global edge CDN.

This is not a toy. The first-principle monorepo publishes nine independent static sites (this DevOps book is one of them) to Cloudflare Pages. Everything in this Part is the actual configuration that deploys it: the same _headers file that sets the CSP on this page, the same cf-deploy.sh you could run right now, the same GitHub Actions workflow that builds it on every push.

The book’s recurring thread does not change just because the artifact is static. Keep asking it on every page: what manual, error-prone step does this remove — and how does it make production safer? What does change is how many of those manual steps existed in the first place. When there is no server process to run, whole categories of the Part 11 pipeline evaporate:

THE CAPSTONE (Part 11) THIS PART (11½)
───────────────────── ───────────────
Dockerfile, non-root, distroless → (no runtime image — output is files)
Kubernetes Deployment + probes → (no process to health-check)
Argo Rollout canary 10→50→100% → instant atomic swap + preview URLs
ServiceMonitor + alert on SLOs → (no server metrics; CDN + RUM instead)
autoscaling on CPU/QPS → (the CDN is already global; nothing to scale)
secrets for the running app → one deploy-time API token, nothing at runtime

That is the whole lesson of this Part in one table: choosing a static-edge deployment model deletes work you would otherwise have to do correctly. The skill is knowing when that model applies (and, just as importantly, when it does not — see the honest limits on the static-edge model page).

The specimen: what we are actually deploying

Section titled “The specimen: what we are actually deploying”
FactValue
Repofirst-principle — a Bun workspace + Turborepo monorepo
Sites9 independent Astro + Starlight docs sites in apps/*
HostCloudflare Pages — one Pages project per app
This bookapps/devops → project fp-devopshttps://fp-devops.pages.dev
Buildbunx turbo run build → each app emits static files to apps/<app>/dist
Deploybunx wrangler pages deploy dist --project-name=fp-<app>
Autha project-scoped Cloudflare API token (see .cloudflare.env.example)

Nine sites, one repo, one build graph, one deploy command per site — and a helper, scripts/cf-deploy.sh, that wraps all of it. By the end of this Part you will be able to point at each of those files and say which manual step it killed.

Read in order — this is the path a commit to this repo takes to reach your browser.

#PageWhat it explainsDraws on
2The Static-Edge ModelWhy “deploy” means copy files to a CDN, not run a process — and what that deletesWhy Containers, WASM & the Edge
3The Build: One Repo, Nine SitesThe Bun + Turborepo build graph that turns source into dist/ foldersCI, Artifacts
4Cloudflare Pages & WranglerGit-integration vs direct upload; the deploy script; scoped-token authDeployment Strategies, Immutable Infra
5Headers, CSP & CachingThe _headers file: security headers, the CSP, and the WASM-search fixHTTP & TLS, Shift-Left Security
6CI & Preview DeploysGitHub Actions builds every push; every PR gets its own preview URLPipelines, Feedback Loops
7RevisionThe whole path recapped

Start with the model, because every later page follows from it: The Static-Edge Model.

  1. Part 11 and Part 11½ are both “commit → production” capstones. What is the single most important difference in the artifact being shipped, and why does it change everything downstream?
  2. Name three concrete pieces of the Part 11 pipeline that this Part does not need, and say why each one becomes unnecessary.
  3. The specimen is nine sites in one repo, deployed as nine Cloudflare Pages projects. Why one project per app instead of one project for the whole repo?
  4. Restate the book’s recurring thread and apply it to a single sentence about this Part.
Show answers
  1. Part 11 ships a running process (a service that must stay up); Part 11½ ships static output (files). Because there is no process to keep alive, everything that exists to run, scale, health-check, and roll back a process — the image, the Deployment, probes, autoscaling, canary analysis — has no job to do. The unit of deployment is a folder of files, not a container.
  2. Any three of: the Dockerfile/runtime image (the output is files, not a program to run); the Kubernetes Deployment + probes (nothing is running to health-check); the Argo canary + SLO analysis (a static swap is atomic and instant, so there is no gradual traffic shift to gate); autoscaling (the CDN already serves globally; there is no per-instance capacity to grow); runtime secrets (the site holds no secrets at runtime — only the deploy needs a token).
  3. Each app is an independent site with its own URL, its own _headers, its own build output, and its own reason to deploy. One project per app means an edit to the Bitcoin book redeploys only Bitcoin, each site gets its own <name>.pages.dev URL and preview deploys, and a broken build in one book can never take down another. It is the blast-radius argument applied to deploys.
  4. What manual, error-prone step does this remove, and how does it make production safer? — Applied here: choosing a static-edge model removes the entire job of running, scaling, and health-checking a server, replacing it with copying immutable files to a CDN that was already global.