All posts
Server room with rows of illuminated rack hardware — quiet, ordered infrastructure doing its work
The Garage · Building Things

How This Gets to You

A reader — she asked not to be named — wrote to say she was thinking about starting her own site. She wanted to know how this one works technically, but not the full tutorial. Just enough to understand whether the project was reasonable for someone without a computer science degree.

I told her I'd write it up properly, because the honest answer is more encouraging than the internet makes it look.

So: here is how this site works, told as simply as I can manage.

Start With the Simplest Truth

A website is files.

That sounds too obvious to be useful, but stay with it for a moment. When your browser opens this page, it is doing the same thing it does when you open a document on your own computer — reading a file and rendering its contents. The file is HTML. The browser knows how to read HTML the same way Microsoft Word knows how to read a .docx. The "web" part just means the file lives on a computer somewhere else instead of your own hard drive.

So the first question is: on which computer? And the second is: how does your browser find it?

Everything else — S3, CloudFront, GitHub Actions — is just a sequence of increasingly good answers to those two questions.

What the Diagram Shows

There are two journeys happening when you interact with this site. The first is yours as a reader — you type a URL, and eventually words appear. The second is mine as a writer — I save a file, and eventually it's available to you anywhere in the world. The diagram below shows both.

WHEN YOU VISIT WHEN I WRITE Your browser DNS Route 53 DNS nearest edge CloudFront CDN · global edge cache miss Amazon S3 static files </> VS Code or admin CMS push GitHub code repo triggers GitHub Actions build + deploy

Both flows end at the same place: Amazon S3. Everything else is about how you get there, and how fast.

The Reader's Side

Route 53 is the phone book. When you type thepolyphoniclife.com, your computer has to translate that human-readable name into a numeric address that machines understand. Route 53 is AWS's version of the service that does this translation — the Domain Name System. It runs in milliseconds and you never see it happen.

CloudFront is the global delivery network. AWS runs over 450 edge locations around the world — servers positioned close to where people are. When a reader in Tokyo opens this page, they're not fetching files from a data center in Virginia. They're fetching a cached copy from a server in Tokyo or Osaka. The page loads in milliseconds instead of seconds. AWS calls this a CDN — a Content Delivery Network. CloudFront's free tier covers almost any personal site; you'd need millions of monthly readers before it cost anything significant.

Amazon S3 is the filing cabinet. S3 stands for Simple Storage Service, which is accurate. It's a place to put files. You upload an HTML file, and anyone with the URL can request it. That's basically all this site is — a collection of HTML, CSS, and JavaScript files sitting in an S3 bucket, delivered to readers by CloudFront.

When you request a page, CloudFront checks its edge cache. If it has a recent copy, it sends that. If not — a "cache miss" — it fetches the file from S3, serves it to you, and keeps a copy for the next person who asks.

The Writing Side

GitHub is version control — the full edit history of every file, since the first commit. It also happens to be where the files live before they're deployed.

GitHub Actions is the automation layer. Every time I push a change — a new post, an edited style, a fixed bug — GitHub Actions wakes up and runs a small script: build the Pagefind search index, sync the updated files to S3, tell CloudFront to clear its cache so readers see the new version immediately. This takes about 90 seconds. I push; 90 seconds later the page is live everywhere in the world.

I don't run that script manually. I don't think about S3 buckets or cache invalidations. I write, I push, it happens. The automation does the last mile every time.

The admin side of this site — the CMS I use to write and manage posts — is also just HTML files in the same S3 bucket, served under /admin/. There's no separate server, no database yet. Everything, including the content manager, is static files. It sounds like a constraint. In practice it's a feature.

How to Build Your Own

Here is the same thing as a checklist, high-level, in the order I'd do it. I'm skipping the exact commands — those belong in documentation, not a post — but this is the shape of the project.

1
Register a domain

About $13/year for a .com via AWS Route 53. Route 53 automatically creates the DNS zone for you. You can also use Namecheap or Cloudflare Registrar if you prefer.

2
Create an S3 bucket

Name it after your domain. Make it private — CloudFront will be the only thing that reads from it. Upload a simple index.html to test.

3
Create a CloudFront distribution

Point it at your S3 bucket, enable HTTPS, set your domain as an alternate name, and attach an SSL certificate (AWS issues these for free via ACM). Set the default root object to index.html. Add a custom error response: 404 → index.html, status 200 — this lets direct post URLs work.

4
Create a GitHub repository

Free for public repos. This is where your site files will live and where your deploy history will be tracked.

5
Write your site

HTML, CSS, and JavaScript — no framework required. I use no React, no Next.js, no build pipeline for the site itself. An index.html, a styles.css, a few JavaScript files. The browser renders them. That's it.

6
Set up a deploy workflow

A single YAML file in .github/workflows/ tells GitHub Actions what to run on every push: sync your files to S3, invalidate CloudFront's cache. The whole workflow is about 30 lines. AWS's OIDC integration means you don't have to store long-lived credentials anywhere.

7
Point your domain to CloudFront

Update your DNS records to point to CloudFront's domain (something like d1234.cloudfront.net). If you used Route 53, this is an alias record — a few clicks in the console.

8
Write

The infrastructure is done. The rest is just making something worth reading.

What It Actually Costs

At the traffic a personal site gets — a few hundred to a few thousand readers a month — this entire stack costs somewhere between zero and a dollar a month. Route 53 is $0.50/month for the hosted zone. S3 storage for a site this size is under a cent. CloudFront has a generous free tier. The SSL certificate is free.

The bill I actually pay, each month, to run this site at current traffic: about sixty cents. Mostly the DNS zone.

The Spirit of It

The thing I didn't expect when I built this: how much it feels like going with the internet rather than against it.

The web was designed to serve files. HTTP is fundamentally a file transfer protocol. When you put static HTML on S3 and let CloudFront deliver it, you're using the internet the way the internet was built to be used — moving bytes from one computer to another, as efficiently as possible. The system wants to do this. It's been doing it for thirty years. You're not fighting anything.

Most of the complexity people add to websites is real work solving real problems — user accounts, personalized content, live data, transactions. When you need those things, you build them. But if you're writing? If you have things to say and want people to be able to read them? You don't need any of that. You need files. A place to put them. A way to get them to people quickly.

This is that way.

If you're thinking about building your own — start. The first version doesn't have to be this version. Start with an index.html and one thing you want to say. Get that in front of people. The infrastructure will catch up to the writing, if the writing is worth it. And the writing is always what's worth it.