Static site on a public host: the second public host, and the control that draws the layer boundary #56
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
allod/archetypes#56
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Stand up a static site on a rented internet-facing host, as the second public host in the fleet and the experiment that decides the layer boundary in allod/archetypes#55.
Primary goals:
Why this one, and why now
allod/archetypes#55 argues that internet-facing machines split into a public-host base and a stateful-service layer, and that the axis is what must be carried across a recreation. A static site carries nothing: it is a build artifact of a repository, so recreating it is a rebuild, exactly like a dev guest.
That makes it the cheap case that tests the claim. If it turns out to need something from the stateful list, the two-layer model is wrong and the split should be drawn elsewhere. If it needs only the base, the boundary is measured rather than asserted, and the builder can be written against two real machines instead of one.
Building a second stateful service first would confirm nothing, because the shared lifecycle is already visible in the first one.
What it needs
What it must not need
No backup client, no restore tool, no state-directory marker gating service startup, no secrets that must survive a rebuild, and no version pin driven by data compatibility. Each of these appearing anyway is a finding, and belongs in the report back to allod/archetypes#55.
Scope
In scope: the machine definition, its DNS and TLS, and the enumerated diff against a stateful public deployment.
Open and blocking a first commit: which repository owns this. It is not a profile — profiles compose a machine's user environment, and a service machine definition is a different kind of thing. Candidates are a small repository per service consumed as a flake input, or a shared repository for stateless public hosts. That decision is part of the same question allod/archetypes#55 asks, so it should be made deliberately rather than by whichever directory is convenient first.
Not in scope: generalizing anything. This issue produces one machine and one diff; the builder is written afterwards, against both machines.
Result: the experiment ran, and the two-layer model held
Settled 2026-08-28. A stateless public host definition exists and builds. All five prohibitions held — no backup client, no restore tool, no state-directory gate, no secrets that must survive a rebuild, no version pin driven by data compatibility — and each absence is asserted by a check rather than merely observed.
The measurement is
DIFF.mdin that repository: 262 lines, four categories,path:lineon both sides. Eight rows differ because one host carries irreplaceable state, six because Forgejo is Forgejo, and eleven were identical. Theservices.opensshblocks came out byte-identical despite being written independently, which is the strongest single piece of evidence that a shared base was real rather than a coincidence of style.Two findings worth carrying forward. The stateful host routes its root
authorized_keysthrough agenix alongside four secrets that genuinely must survive; copying that here would have added secret management to a machine with no secrets and falsely "proved" the stateless host needed the stateful layer. And "carries nothing" has a rate limit: Caddy's ACME account key is regenerable and unpinned by clients, but Let's Encrypt caps duplicate certificates, so the criterion is irreversibility rather than the presence of a state directory.Two things this issue does not cover
The site serves placeholder content. The machine ships an
index.htmlandstyle.csswritten for the experiment. The realvnprc/hashpool-websiterepository was never wired in — it lives on the forge and was not cloned locally, so the search for existing content found nothing and fell through to a stub. Replacing it touches one file, by design: the module takes a path and does not care how it was produced.The repository home is still undecided, and it blocks a first push. The recommendation is a repository of its own: this is a definition for a whole separate machine, and tucking it inside an existing repository means that repository rebuilds whenever the website changes and its history entangles with something unrelated.
Superseded scope
This issue framed one machine as a control experiment. The experiment is finished. How static sites should actually be organised — one host profile, a builder per generator, an entry per site, and CI-driven deploys — is a separate design and belongs in its own issue rather than here.
Completed. The control experiment reported its measured result on 2026-08-28: the stateless public host needed the public-host base and none of the stateful lifecycle layer. The reusable result is now on master:
nixosModules.publicHostat3ba8082, followed by the directory-backed static-site module, Zola builder, adversarial content checks, and first-boot VM in #58 (e6a3ee4). The remaining production organisation and CI deployment work stays tracked in #57; the unfinished stateful layer/builder question stays in #55.