A website for a family member
My brother-in-law does a lot of woodworking and needed a website to show off his amazing skills. The website should cost nothing to keep alive (except the domain name), he should be able to update it himself without ever learning what Git is, and on the rare day he wants something bigger changed it should be as painless as possible. On top of all that I wanted it secure, fast, and stable, so that it will keep working for years. The whole thing sits on Cloudflare’s free tier with the source code on GitHub, and so far the running cost is exactly the price of the domain and nothing else.
Description
The site is a plain old static Hugo build, shipped as a Cloudflare Worker. A wrangler.jsonc points Cloudflare at a build.sh (which pins the Hugo, Go, Dart Sass, and Node versions so future-me isn’t debugging a mystery version bump), and the generated public/ directory gets served as static assets, 404 page and all. The repo is wired to Cloudflare, so every push rebuilds and redeploys on its own; about a minute after a change lands, it’s live. No servers, no bill, nothing to patch at 2am. (The hugo website nicely describes how to set this all up.)
Photos don’t live in the repo (nobody wants a Git history full of 4MB JPEGs). They go to Cloudflare R2, which is an S3-compatible object storage with a generous free-tier. A dedicated bucket is exposed through a custom subdomain, so images are served straight from R2, and a CORS policy lets the admin console upload to it directly from the browser.
That “admin console” is the bit my brother actually cares about: Sveltia CMS, a Git-backed editor living at /admin. He gets one link and a “Login with GitHub” button, and that’s the entire surface area he ever sees. Behind the curtain, a tiny sveltia-cms-auth Worker does the OAuth handshake against a GitHub OAuth App locked to his domain. Once he’s in, he can tweak the site settings (tagline, contact details, footer), edit the main pages, and run the show on the work/projects section: adding jobs, reordering them, writing up descriptions, and drag-dropping whole photo galleries that fly straight to R2. He hits Publish, the CMS quietly commits to GitHub, Cloudflare rebuilds, and his change is live a minute later.
GitHub repo ──► Cloudflare Worker ──► timstimber.com (the website)
▲ │
│ commits │ /admin
│ ▼
auth Worker ◄── "Login with GitHub" ── Sveltia CMS editor
│
▼
Cloudflare R2 (the photos)
I also wanted to give him the option to make larger changes that go beyond making changes in the CMS. For those, he just writes a GitHub issue describing what he’s after in plain English. An “agent automation” I set up spins up a coding agent whch implements the changes and creates a merge request. For now I still manually merge those myself, just because I like to quickly review those changes before they hit the real site (and partly because I don’t fully trust the robots yet).