Seven small websites

Five documentation sites, a blog and a front door, and none of them is large. The host builds the documentation sites from source with Sphinx on each push. The blog is built at home with Zola and the front door at home with Frozen-Flask, and for those two the finished directory is committed and served as it arrived. On a documentation build the host pulls a Docker image and pinned packages from PyPI. For the blog and the front door it pulls nothing, because the build has already happened on the workstation.

Site

Built with

Built where

What the host receives

Documentation, x5

Sphinx

statichost, on push

source, and three lines of configuration

Blog

Zola

workstation

the public/ directory, committed

Front door

Frozen-Flask

workstation

the project/build directory, committed

The entire configuration for a documentation site is three lines: the image to build in, the command to run, and the directory to publish. The same three lines run on the workstation and produce the same output, so nothing about the build exists only at the host. The fonts were the one fetch the move took out of a build. The theme wants Roboto from Google, its cache is committed in each repository, and a build with the network unplugged still writes all the font files. The deployment notes have the diagram and the dead-proxy test.

Names and addresses

The name is purplelantern.eu, registered through Infomaniak in Geneva, with the zone in Infomaniak’s DNS and DNSSEC switched on. The sites are served by statichost in Stockholm from Hetzner hardware in Helsinki and Nuremberg, with no CDN and nothing in front of the origin. The source is at CodeFloe, the games and labs at Codeberg, and the mail at Proton. Domain, zone and site are held by three different companies, so that losing the host costs one record change and losing the DNS provider moves the zone while the domain stays where it is. The apex carries two addresses copied from the host’s documentation, because a CNAME cannot sit next to the SOA record, and that record gets compared with the documentation now and then. Finding out who is under the host took three documents, and the hosting notes have them.

In the browser

A visitor’s browser fetches the site and nothing else: fonts come from the site, search runs locally, and the default-src 'self' header enforces it. The exception is the contact form on the front door, which posts to Formward in Stockholm behind three layers of spam protection that need no US script. The declaration is short.

Empty boxes

Several things are absent by decision. There is no CI, because the checks run at home before the push exists, and no mirror, because a full clone already holds what a mirror would. Commits are unsigned, previews unused, and the company sells no subscriptions and takes no donations. Two absences are not decisions yet. Nothing outside the provider’s own network is watching the sites, and there is no hardware key, so the second factor on each account that takes one is still an authenticator app owned by a US company. The checklist keeps both in view.

If statichost vanished overnight, the repositories are on the workstation, two of them already contain their site, the three lines run locally for the other five, the DNS is at Infomaniak, and any host that accepts a directory would do. The work would take an afternoon, with most of it spent waiting for DNS to propagate.


Granny Weatherwax’s cottage has one door. Everybody in Lancre knows which way it opens, and nobody has ever gone through it uninvited.