Journey
MilestonedeployCI/CDCloudflare

Ship the website: Git → CI/CD → Pages

The domain now points at Cloudflare's edge — at nothing. This step is what goes behind that front door, and the decision underneath it.

Rent a server, or just push files?

The obvious move is to rent a computer — a Hostinger VPS — install nginx, get a certificate, and serve the site from there. We have one sitting ready. We didn't use it for the website. Here's why.

A server earns its keep when there's code to run on every request — a database to query, a session to check, a page to assemble. Our site has none of that. It's prerendered: every page is built ahead of time into plain HTML, CSS and JavaScript files. There's nothing to run — only files to hand out.

Hostinger VPS + nginx

  • A computer you rent, running 24/7
  • You patch the OS, renew certs, watch uptime
  • You scale it yourself when traffic spikes
  • Right when you run server-side code

Cloudflare Pages

  • Push files; they land on the global edge
  • HTTPS, scaling, DDoS — handled for you
  • Served from the city nearest each visitor
  • Right for a static, prerendered site

A single-page, statically-rendered site needs no SSR — nothing rendering it fresh on every request — so a box idling 24/7 to hand out static files is the wrong tool, and a CDN serves those same files faster. So the website went to Cloudflare Pages. The VPS isn't wasted — it's reserved for a future api.pangaea.id, where real server code will live.

How a change goes live

We never upload files by hand. The whole thing is a push:

git push→ mainpull requestbuild + typecheck✓ checked — not deployedGitHub Actionsnpm citypecheckbuild → dist/wrangler pages deploy dist/Cloudflare Pagesfanned out to the global edgelive at pangaea.idbad deploy? roll back to any previous one — 1 click
Only a merge to main runs the deploy — a pull request runs the same build + typecheck as a gate, but never ships.
  • Push to main — that's the trigger.
  • GitHub Actions wakes up — installs dependencies, runs the typecheck, and builds the static site into a dist/ folder (the same npm run build we run locally).
  • wrangler uploads dist/ to Cloudflare Pages, which fans it out to every edge.
  • Minutes later it's live worldwide. A bad deploy? Roll back to any previous one in a single click — Pages keeps the history.

Pull requests get the build + typecheck gate but never deploy — only merging to main ships. (What each push also does — ringing the search engines' doorbell — earned its own entry.)

The full wiring — the API token, the two secrets, creating the Pages project, the "project not found" gotcha — is in the companion walkthrough CI/CD: GitHub Actions → Cloudflare Pages →.

Live

Domain pointed, site shipped — https://pangaea.id was real. What actually happens in the half-second between typing that and seeing the page is a neat little story of its own: What happens when you type a URL →.

Sources

  1. Cloudflare Pages — static & full-stack hosting
  2. cloudflare/wrangler-action — deploy from GitHub Actions