Learn ← All posts
Post

A site with no build step

site · python · http

A folder of files, one small Python server, and no build tool to keep updated.

This site is plain HTML and CSS with a little JavaScript for the theme toggle. No framework, no bundler, no dependency tree. The server in front of it is a few hundred lines of Python, standard library only.

Why no framework

A site this size does not need one, and every layer I don't add is a layer I don't have to patch, upgrade or debug. The parts I did want from a framework — caching, compression, headers, clean 404s — turn out to be a few dozen lines each.

What the server does

  • serves public/ and nothing else; .. and dotfile access return 404
  • gzip for text over 512 bytes
  • ETag (hash of the body, cached by mtime) and Last-Modified, with 304 replies
  • security headers on every response: CSP, X-Content-Type-Options, Referrer-Policy, HSTS, frame-ancestors 'none'
  • maps the bare domain to www with a 301 — including on HEAD, because a redirect that carries a body on a HEAD request makes proxies complain
  • a real 404 page with status 404, not a friendly page served at 200
  • /healthz for a one-line check

The caching trap

HTML is served private, no-store, because the response varies by client IP and must never land in a shared cache. Static assets get a normal max-age.

The catch is the CDN edge in front: it caches CSS and JS for four hours and ignores the origin's five minutes. Change a stylesheet and the browser receives new HTML with old CSS — the layout looks broken and nothing in the logs says why. The fix is a version query on every asset link (styles.css?v=14), bumped whenever the file changes. It isn't elegant. It is honest about how the edge behaves.

Owning the boring parts

Caching, headers and redirects are small, well-understood problems. Having written them myself, I can follow the whole path from request to response without opening anyone else's source.