jupiterOS

Automation & AI

jupiterOS

One declarative computer for a seven-machine home fleet.

Problem

7 machines: four kiosks, a ZFS storage server, a build and serving host, and a cloud builder. I had set them all up by hand. Configuration drifted, nothing was reproducible, and a dead disk meant days of manual rebuild.

Diagnosis

The machines differ in hardware, not in intent. The real fix was not a better manual, it was one source of truth: describe every host declaratively so any of them can be rebuilt from a repository, and let CI verify changes before they land.

Action

  • One NixOS flake describing all 7 hosts, each named after a moon of Jupiter: amalthea, metis, thebe and adrastea (the kiosks), europa (the NAS), callisto (build and serve), pallene (the cloud builder)
  • 31 service modules shared across hosts: MQTT, PostgreSQL, netboot, Cloudflare tunnel, Headscale, MeshCentral, monitoring and more
  • Secrets encrypted with sops/age; each host decrypts only what it needs
  • 14 GitHub Actions workflows, one per build target, so a change that breaks a machine fails in CI
  • A binary cache on europa so every host shares builds instead of recompiling
  • ZFS storage with snapshots; callisto boots its root over iSCSI from europa; the kiosks netboot with iPXE
  • Runbooks, architecture decision records, a style guide and incident notes written as the work happened

Outcome

  • A new host is now a config away: describe it, build it, done
  • Any machine can be rebuilt from the repository
  • Secrets never sit in plaintext
  • Four repurposed terminals run as daily-use kiosks instead of landfill
  • About 1,100 commits between June and September 2026, with AI doing the typing under my direction

What I'd do differently

Pending

Reflection to be written by Jupiter.

Clock
--:--:--—Local time