How this blog is built
Markdown files in a Git repo, built with Astro and served from S3 and CloudFront.
This blog is a folder of Markdown files. Publishing a post means pushing a commit. There’s no CMS, no database, and no server to keep running.

The pieces
- Astro turns Markdown into static HTML at build time. Pages ship with no JavaScript.
- GitHub Actions builds the site on every push to
mainand uploads the output. - S3 stores the files in a private bucket. Nothing reads from it directly.
- CloudFront serves the site over HTTPS from edge locations and caches everything it can.
Writing a post
Each post is a folder. The folder name becomes the URL, and images live next to the text that uses them:
src/content/posts/
how-this-blog-is-built/
index.md
pipeline.png
The post starts with a few lines of frontmatter:
---
title: How this blog is built
description: One sentence for the post list and link previews.
date: 2026-10-04
---
Images use normal Markdown with a relative path. At build time Astro resizes them, converts them to WebP, and gives each file a content hash in its name, so CloudFront can cache it for a year without serving a stale copy.
Caching
HTML pages are cached at CloudFront until the next deploy clears them, and browsers check for a new version on every visit. Images, fonts, and CSS have hashed file names, so browsers keep them for a year.