- Python 55.6%
- Nushell 16.3%
- Just 14.7%
- Rust 8.5%
- Shell 2.4%
- Other 2.5%
Borealis Anastasia
Anastasia is a single-node personal cloud server. It is the current running instance of what is converging toward Essence Borealis Server — a packaged, declarative, single-node personal cloud OS built on Fedora, Podman quadlets, ZFS, Tailscale, and Prometheus.
This repository contains the deployment definitions and tooling for all containerized services running on the machine.
Architectural Principles
One naming convention, three manifestations. The deployment source tree, ZFS dataset hierarchy, and systemd unit names all follow the same <fqdn>/<shortname>/<service>/<component> structure. See NAMING.md.
Podman quadlets as the current deployment primitive. No docker-compose. Quadlet files are systemd-native container definitions. A Nushell projection script converts the hierarchical source tree into flat systemd units, rewriting references along the way. See QUADLET.md. A provisional Kubernetes track now exists as a Borealis experiment, but it is not yet the live operating model. See BOREALIS.md and KUBERNETES.md.
ZFS as the storage primitive. Snapshots every 15 minutes, grid-based pruning, push replication to a TrueNAS NAS over Tailscale. The dataset hierarchy mirrors the naming convention. See ZFS.md.
Tailscale-first networking. Zero public ports except 80/443 on the public gateway. All private services are Tailscale-only, accessed through a Caddy reverse proxy that shares the Tailscale container's network namespace. See NETWORK.md.
Snapshot lifecycle ownership. Each zrepl job owns the full lifecycle — snapshotting, pruning, and (if applicable) replication — for a disjoint set of datasets. The unique job manages local-only datasets; the replicated job owns off-site datasets. No two jobs touch the same dataset's snapshots, preventing race conditions between independent pruners. See ZFS.md.
Observability as a first-class concern. Prometheus scrapes ZFS health, replication status, and its own availability. Alertmanager sends email alerts and a daily dead-man's switch. See OBSERVABILITY.md.
Honest secrets management. Environment files co-located with service definitions, gitignored, deployed alongside quadlets. Current state documented with a clear roadmap toward proper secrets management. See ENV.md.
Quick Start
just deploy # Project all files to /etc/containers/systemd/ + reload
just status # systemd status of all managed services
just status jad.tl/img/immich # Status of a specific service stack
just restart jad.tl/img/immich # Restart all containers in a stack
just restart '*-tailscale' # Restart by glob pattern
just logs jad.tl/md/hedgedoc # Follow logs for a service stack
just enable jad.tl/feed/wallabag # Add [Install] WantedBy= + deploy (boot on start)
just disable jad.tl/wget # Remove [Install] section + deploy
just diff # Show what changed vs deployed
just lint # Run quadlet syntax validation
just check-refs # Validate cross-references between container files
Service commands accept patterns: source paths (jad.tl/img/immich), globs ('*-tailscale'), top-level prefixes (tala.family), exact flat names, all, or . (CWD-relative). See QUADLET.md for the full pattern reference.
Repository Layout
deployment/ Hierarchical source tree (quadlets + sidecars)
gateway/ Reverse proxy layer (public + private)
jad.tl/ Personal services (img, git, md, nc, src, ...)
tala.family/ Family services (memories, auth, net, ...)
quadlet-project.nu Projection engine (Nushell)
justfile Developer interface (just recipes)
rootful.list Glob patterns for rootful routing
completions/ Fish shell completions for just recipes
Current Instance
| Property | Value |
|---|---|
| Hostname | Anastasia |
| OS | Fedora 43 Workstation |
| Container runtime | Podman (quadlets) |
| ZFS pool | tank (unencrypted, mounted at /mnt/tank/) |
| Domains | jad.tl (personal), tala.family (family) |
| Backup target | Wahch (TrueNAS SCALE, via zrepl over Tailscale) |
| Monitoring | Prometheus + Alertmanager (native systemd services) |
Documentation
| Document | Contents |
|---|---|
| NAMING.md | Naming convention and hierarchy design |
| QUADLET.md | Projection system and developer workflow |
| BOREALIS.md | Emerging Borealis vision, vocabulary, and open questions |
| KUBERNETES.md | Experimental Kubernetes substrate track for Anastasia |
| ZFS.md | Storage layout, snapshots, and replication |
| NETWORK.md | Gateway architecture and Tailscale networking |
| OBSERVABILITY.md | Prometheus, alerting, and exporters |
| ENV.md | Configuration, secrets, and future roadmap |
Roadmap
- bootc: Immutable base OS image with CI-controlled updates. The host becomes a declarative artifact — container definitions, ZFS layout, and observability config are all version-controlled, and the base OS is rebuilt from a Containerfile.
- OIDC everywhere: Standardize authentication across all services via a single OIDC provider. Per-app claims for quota and access rights.
- Secrets vault: Extract secrets from
.envfiles into age/sops or a Vault instance. Decrypt at deploy time only. - Rootless containers: Narrow
rootful.listto only services that genuinely need root (gateway, headscale). Run everything else rootless. - Recovery procedures: Document bare-metal rebuild from Wahch backups, single-dataset restore, and backup verification. See AGENT.md for the proposal.