Apache vs Nginx
Choice: Apache 2.4.62
Rationale: .htaccess support allows URL routing changes without root access. The template system depends on per-directory rewrite rules — Apache handles this cleanly with RewriteCond and RewriteRule. Performance difference vs Nginx is negligible at this scale. Memory overhead of 50–100MB is acceptable within our 921MB budget.
Flat JSON over a Database
Choice: songs.json + poems.json as the content layer
Rationale: Eliminating a database removes the largest attack surface entirely. JSON files are readable, diffable, and version-controlled alongside the rest of the site. No query overhead, no connection pooling, no migrations. A bash script generates /api/stats.json for server telemetry — the same philosophy applied to monitoring.
Single Template per Content Type
Choice: song-template.html and poems-template.html, routed via .htaccess
Rationale: Adding a new song or poem means editing one JSON file. No HTML file is created per piece of content. Apache rewrites /songs/bad-fortune.html to /song-template.html?id=bad-fortune — the template fetches the JSON, finds the entry by key, and renders the page client-side. 301 redirects handle legacy URL paths.
sessionStorage for Status Bar Caching
Choice: Synchronous IIFE restores cached weather, KP, and CPU values before the first render
Rationale: API calls to Open-Meteo and NOAA take 200–800ms. Without caching, the status bar flickers with dashes on every page load. The IIFE runs synchronously during HTML parse, restoring last-known values from sessionStorage instantly — then async fetches update them in the background. Result: the status bar appears populated even on cold navigation.
Monospace Typography
Choice: System monospace stack — no web fonts
Rationale: No font downloads means no render-blocking requests and no third-party tracking. The constraint also fits: monospace is the natural environment for code, terminals, and technical writing. The site reads like a document rather than a product.
Real-time Telemetry Polling
Choice: 30-second client polling of 60-second server updates (CPU) · 5-minute polling for weather and KP index
Rationale: CPU temperature changes meaningfully over 30–60 seconds under varying load. Weather and geomagnetic activity move slowly — 5-minute polling is honest. More frequent calls would waste Pi cycles and NOAA bandwidth without surfacing meaningful change. The telemetry page extends this with 24-hour rolling charts stored in localStorage.
Stripe for Payments
Choice: Hosted checkout links, no Stripe SDK loaded on-site
Rationale: A Pi on a home connection should not be processing card data. Stripe's hosted checkout handles PCI compliance entirely off-server. The implementation is three URL constants and a window.open() call — no client-side library, no webhook surface, no card data ever touches Derry.