lonehandstudio.com served its first real page at 21:14 WEST on 31 August 2026. Before that it served a GoDaddy Website Builder page nobody in this project made, titled "Lone Hand Studio", tagline "Crafting Unique Adventures", carrying a working contact form and Google reCAPTCHA behind no privacy notice.
The deploy took about four minutes once it started. Getting to the point where it could start took a day, and four separate things nearly stopped it. Each one is the kind of fault that looks like a different fault, which is why they are all written down here.
1. The manifest would have shipped a site with no images
The publish manifest is an explicit list rather than a directory, so that a working directory never becomes a docroot. It listed two draft PNGs from assets/images/drafts/, under a comment saying "Both are referenced by index.html and by nothing else."
Every page references lone-hand-hero.{jpg,webp}, town-section.{jpg,webp} and lone-hand-og.jpg. No page has ever referenced a drafts/ PNG. The manifest was wrong in both directions at once: it shipped two unreferenced megabyte files and shipped none of the five files the site actually asks for.
Deployed as written, every image on the site would have 404'd.
The list is now derived from the pages themselves, with the derivation command written into the file so it stops being maintained by hand.
2. A gate that could never pass, because it matched itself
The deploy script's first gate refuses to transfer while a placeholder literal survives anywhere under website/. It ran a recursive grep for two placeholder strings across that directory — and the script lives in that directory, and contained both strings verbatim in its own grep pattern.
So the gate found itself, reported FAIL, and would have kept reporting FAIL after every placeholder in the project was gone.
3. systemctl reload caddy cannot work on this server
The production Caddyfile sets admin off. Caddy's reload works by posting the new config to a local admin API, so with the endpoint off there is nothing to post to:
Error: sending configuration to instance: performing request:
Post "http://<admin endpoint>/load": connect: connection refused
Every config change on that box needs a restart, which drops connections for a second or two across eleven sites. That is not a Lone Hand fact, it is a fleet fact, and it had never been written down.
4. The one that was my own fault
The restart then failed anyway, with a permission error pointing at the new site's log file. It read like a config fault. It was not.
Running caddy validate with elevated privileges opens every configured log destination to check it — and as root, it creates the file, owned by root, mode 600. Caddy runs as the caddy user and cannot open a file like that. So the validation step that existed to prevent a bad restart was the thing that caused one.
-rw------- 1 root root 0 Aug 31 18:25 <log dir>/lonehandstudio.log
Remove the file, restart, and Caddy creates it correctly. The config had validated clean the whole time.
Two rollbacks, and why they cost nothing
The Caddy config was backed up with a timestamp before anything touched it. Two restart attempts failed, and both times the rollback restored the backup and brought Caddy back. Every one of the eleven sites on that server stayed reachable, verified from outside after each failure. Two failures, no downtime that anyone could have observed.
The thing the runbook got wrong
The deploy runbook said the GoDaddy Website Builder site had to be unpublished by hand from the dashboard before the DNS change, quoting an infrastructure note: "GoDaddy domain forwarding overrides A records… the API can't toggle that."
That note is about forwarding. This was a Website Builder site, which is a different mechanism, and nobody had tested whether the distinction mattered. It does. The API accepted a plain A record over GoDaddy's special "WebsiteBuilder Site" value, and the authoritative nameserver returned the new address immediately.
The runbook had assigned a human a step that turned out to be unnecessary, on the strength of a note about something else. The correction is in the runbook now.
What actually happened, with times
| Time (WEST) | Event |
|---|---|
| 18:24 | Docroot created, Caddyfile backed up |
| 18:25 | First restart attempt fails — the root-owned log file |
| 18:31 | Second attempt fails the same way; rollback, all sites verified up |
| 18:32 | Log file removed, restart succeeds, site block live |
| 21:09 | Nine files transferred, modes set |
| 21:10 | A record written; authoritative nameserver updated at once |
| 21:14 | Certificate issued, https://lonehandstudio.com/ returns 200 |
Four minutes from DNS to a working HTTPS site. Roughly three hours from the first attempt to that point, and every minute of the gap was one of the four faults above.
What the site does not have yet
The images are exported below their specified sizes, because the source frames are 1024 pixels wide and every deliverable size asks for 1200 or more. Nothing is upscaled; each file is the largest honest crop of its ratio. Fixing it means regenerating at a larger size, which is deterministic and cheap, and it has not been done.
Fourteen subscribe links point at a Substack home page with no source parameter, so channel attribution is impossible today. While one channel exists that is adequate. It becomes wrong the moment a second one launches, and the subscribers collected before the fix cannot be split retroactively.
Neither of those stopped the launch. Both are written here so that when they are fixed, the record says how long they stood.
Later: The Studio Staffs Itself, And Finds Its Own Seatbelt Does Not Latch