Skip to content

Deploying evo.polaris ​

The app is static files: no build step, no server side, nothing to configure. Whatever serves it only has to hand out the contents of site/ over HTTPS, and that is all the live copy at polaris.evomedia.net is.

HTTPS is a hard requirement, not a nicety ​

Three things this app depends on are secure-context APIs, and all three fail on plain http://:

APIWhat breaks without TLS
Geolocation"Use my location" does nothing at all
DeviceOrientationthe live compass arrows never appear
Service workerno offline support, which is the normal case in a field

They fail silently — no console error a casual look would catch, no message to the user. A phone visiting this host is supposed to get its position and its heading from the browser with no typing whatsoever, and that only happens over TLS. localhost is exempt from the rule, which is exactly why npm run serve works and hides the problem during development.

A new hostname takes two steps, not one. A web server will not start with a certificate that does not exist yet, and the certificate cannot be issued until the name already answers the certificate authority's challenge over plain HTTP. So the name is served over HTTP first, the certificate is issued, and only then is HTTPS configured for it.

Only site/ ships ​

What gets published is the site/ folder, never the repository root, and that is on purpose. The repository holds test fixtures, build scripts and package.json, which have no business on a public web server. An exclude list could keep them off, but an exclude list fails open: forget an entry and it ships. Publishing one folder fails closed: forget a file and it is merely missing, which is obvious on the first page load.

The file types a server has to allow ​

Some servers answer only for an allow-list of file extensions and refuse everything else — the live host does. This app needs:

html | css | js | json | svg | webmanifest | png | webp

json is the one that is easy to miss. The 9,096-star catalogue ships as site/src/data/stars.json, and a list copied from a typical static site will not include it. The catalogue then sits on disk at the right path with the right bytes while every request for it is refused. In a browser that is an empty sky chart. From the command line it can read as the connection closing abruptly, which looks like a TLS or network fault — and an extension list is the last place anyone thinks to look.

png carries the link-preview card, the iPhone home-screen icon and the install sheet's screenshots; webp carries the Milky Way, the planet surfaces and the constellation figures. The app ships no JPEG. A new file type means a new entry in the list before the file ships, or it is a file on disk that every browser is refused.

Verifying it actually landed ​

Merged is not deployed, and deployed is not working. Check the running site, not the deploy script's exit code:

bash
curl -sI https://polaris.evomedia.net | head -3
curl -s https://polaris.evomedia.net/build-version.json
curl -s https://polaris.evomedia.net/src/data/stars.json | head -c 60

The second names the build that is actually being served. The third is the real test of the server: it is the request an allow-list without json would refuse, and the app would load with an empty sky chart.

Cache busting on release ​

The service worker is network-first for the app shell and cache-first only for the star and magnetic data. And the page reloads itself once when a new worker takes over. A returning visitor's page is drawn from the old worker's cache before the browser notices a new sw.js; the new worker installs, evicts the old cache and takes control, and the page keeps showing what it already loaded — so every deploy reached a returning visitor only on their second reload, and nothing said so ("perseus didn't land in 1.25" — it had). A first visit has no previous controller and is left alone. Cache-first for everything is how a static site pins every returning visitor to the first build they ever loaded, so a deploy would reach nobody until they cleared site data.

Move VERSION in site/sw.js whenever a precached file changes — per change, not per release — then run npm run precache-stamp. Old caches are dropped on activate, keyed by that string. Nothing used to enforce it: edit a precached file, forget the key, and the deploy reached everyone who had never visited and nobody who had. Now the stamp records a digest of every precached file beside the key it was taken at, and the test suite fails when a file has changed and the key has not.

The release stamp itself — build-version.json and src/version.js — is exempt, because the release writes it rather than any change. Watching it turned main red after every release until the next feature happened to restamp, which is how it went unnoticed; a test now checks that every file the release writes is one the guard skips.

Release packages ​

Every release is packed into the repository's releases/ folder as evo.polaris-v{version}.zip, with a .sha256 beside it. The zip holds site/ — the whole app, byte for byte what is deployed, and all anyone needs to run it — plus the licence, the readme and a CHECKSUMS.txt, all under one folder named for the version:

bash
sha256sum -c evo.polaris-v0.0.1.0.37.zip.sha256    # the zip
sha256sum -c CHECKSUMS.txt                         # each file, once unzipped

Nobody has to remember to make one. The version script packs the release every time it stamps a version, and the release commit carries its own zip. It is reproducible — entries sorted, every timestamp the zip format's earliest, nothing about the machine in it — so the same tree always packs to the same bytes and the checksum means something. It was checked with tools that share nothing with the code that wrote it: unzip -t finds no errors, PowerShell's Expand-Archive extracts every file, and sha256sum -c passes on the zip and on every file inside.

To run one, serve its site/ folder from any static web server over HTTPS, or localhost — for the secure-context reasons at the top of this page.

Documentation hub for Evomedia.net LLC products.