Looking beyond the clouds, together. https://handbook.tala.family
  • Python 55.6%
  • Nushell 16.3%
  • Just 14.7%
  • Rust 8.5%
  • Shell 2.4%
  • Other 2.5%
Find a file
2026-10-25 12:04:47 +01:00
.agents/skills
.forgejo/workflows
atproto
borealis
clusters/anastasia/apps/dns
completions
deployment
handbook
kubernetes
reports
scripts
.gitattributes
.gitignore
.sops.yaml
AGENT.md
BLEUCIEL_MIGRATION.md
BOREALIS.md
ENV.md
justfile
KUBERNETES.md
NAMING.md
NETWORK.md
OBSERVABILITY.md
OPENCLOUD.md
PIXELFED.md
quadlet-project.nu
QUADLET.md
README.md
rootful.list
SECRETS.md
TODO.md
ZFS.md

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 .env files into age/sops or a Vault instance. Decrypt at deploy time only.
  • Rootless containers: Narrow rootful.list to 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.