Colophon
What this website is made of.
Everything here lives in Uile, an Elixir umbrella that owns the data and answers over a Unix socket. Underneath is an append-only op-log in SQLite, so the website reads the same store I write to from a terminal, and a change on one machine replays on all of them. Nothing gets compiled into static HTML ahead of time; a page is put together when you ask for it.
Writing happens through a set of small Rust command-line tools, one per kind of thing:
- atlas for typed documents, which is what you’re reading now. Articles and recipes so far.
- logbook for dated entries: notes, checkins, bookmarks, quotes, photos, video, audio.
- assets for media, including a magic-wormhole ingest so a photo can get from my phone into the store without a cable.
A document is private until it’s placed. atlas place puts it somewhere in a single-parent hierarchy, and a page appears on the website only once it’s reachable from a root. That’s the entire publishing mechanism: not a draft flag, a position in a tree.
The web layer is deliberately plain: a Plug.Router over Bandit, rendering HEEx templates on the server. It borrows Phoenix’s template engine and nothing else: no endpoint, no LiveView socket, no stateful components, and no JavaScript on the page at all. A Rust NIF comes in through Rustler where Elixir isn’t the right tool for the job. There’s an Atom feed, and a map of checkins.
The whole fleet runs Debian, and every piece ships to it as a .deb from an apt repository I host, with the Release file signed by a Yubikey.
Before all of this, the site was a pile of static HTML compiled by a tool I wrote called Wattle. That approach lasted right up until I wanted the writing to live somewhere other than my laptop.