NixOS host · single-node k3s · 192.168.8.100

Omega facility
schematic

Cross-section of the home server: public edge, split-horizon DNS, Traefik, Authelia, and every kubenix namespace on the cluster.

Dwg. ω-01 · rev. live tree
Cluster issuer · Cloudflare DNS-01
Default policy · two-factor

01 Process stack

LAN clients go straight to 192.168.8.100. Public HTTP is a relay: Cloudflare (orange) → Fly.io (flyio.wsosnowski.pl) → Tailscale → Traefik on omega. Traefik then hands off to Authelia, the SSO bridge, or the app’s own login.

PUBLIC PATH · CLOUDFLARE → FLY.IO → TAILSCALE → OMEGA CLOUDFLARE orange proxy + DNS FLY.IO flyio.wsosnowski.pl TAILSCALE into omega tailscale0 LAN discworld · NM CUBBIT / SMTP restic · garage · Scaleway SPLIT-HORIZON DNS → 192.168.8.100 NM DNSMASQ Host + LAN clients. Wildcards + extraHosts. COREDNS Cluster zones. Forward else → 192.168.1.1 PUBLIC DNS CNAME → flyio (proxied). Registry grey. EDGE ON OMEGA TRAEFIK :80 / :443 · ingressClass traefik · cert-manager ClusterIssuer default CERT-MANAGER DNS-01 · four zones K3S API node ports 1000–52000 IDENTITY AUTHELIA auth.techtailors.net auth.wsosnowski.pl FORWARD-AUTH · 2FA SSO BRIDGE sso.techtailors.net mint sso.wito.dev · sso.slopkit.dev COOKIE ON FOREIGN ZONES WORKLOADS One namespace per kubenix service. App login, Authelia, or SSO-bridge authz. postgres · mariadb · redis · garage · local-path
Request path Authelia cookie domains SSO bridge (wito.dev / slopkit.dev) Native / internal

02 Split-horizon DNS

LAN and cluster resolvers pin the home zones to 192.168.8.100. Public records live in Cloudflare and almost all CNAMEs go to flyio.wsosnowski.pl (proxied). Fly then reaches omega over Tailscale. Nested VM names are the exception: DNS-only A to 83.6.22.108, because a proxied Fly CNAME breaks those certificates.

Wildcard → 192.168.8.100

techtailors.net

GitLab, registry, pages, Garage, Lemmy, Mira, auth, SSO mint.

Wildcard → 192.168.8.100

wsosnowski.pl

Homepage and most homelab apps. Never wildcard all of wito.dev.

Wildcard + extraHosts

vm / local.wito.dev

Sandbox VMs. Extra hosts only: agent, kit, ssh, sso.

Public, not whole-zone

Cloudflare → Fly

Proxied CNAME to flyio.wsosnowski.pl. Registry stays DNS-only. Nested *.vm uses origin A.

CoreDNS serves the same zones inside the cluster and forwards everything else to 192.168.1.1. CI pods also get host_aliases for registry, gitlab, and minio so jobs that skip cluster DNS still hit omega.

03 Auth logic

Authelia owns two cookie domains. Apps on a third zone cannot see those cookies, so Traefik sends them through the SSO bridge: mint a session on techtailors, then set a cookie on wito.dev or slopkit.dev.

Same-zone ForwardAuth

  1. Traefik chains authelia-proto then authelia forward-auth to :9091/api/authz/forward-auth.
  2. Missing session → browser goes to auth.wsosnowski.pl or auth.techtailors.net.
  3. File backend, argon2id, SMTP via Scaleway TEM. Default policy is two-factor. Auth hosts themselves bypass.
  4. Session cookie is scoped to the parent domain. Used by homepage, Grafana, n8n, OpenCode.

Foreign-zone bridge

  1. App ingress uses authelia-proto + sso-bridge-authz.
  2. Bridge /authz looks for its own session cookie. Miss → mint at sso.techtailors.net (Authelia-gated).
  3. Set-cookie endpoints: sso.wito.dev, sso.slopkit.dev.
  4. Hermes, web-ssh, OpenHands. GitLab, Nextcloud, Plex and the *arr stack keep native logins.

04 Service catalog

Every kubenix registry entry, plus host-plane jobs that are not in the cluster. Click a plate for hostname, auth, and dependencies.

05 Dependencies

Runtime edges only: who talks to whom. Ingress to Traefik is implied for every public host and is omitted so the graph stays readable. Click a hub or a catalog plate to focus one service.

Needs
Focus
Needed by

06 Host plane

NixOS 26.05 stable, impermanence, doas. k3s waits on LUKS mounts. Storage classes are owned by kubenix, not the k3s local-storage addon.

NixOS on the metal

  1. k3s server--disable=local-storage, custom resolv.conf, wide node-port range.
  2. mount-encrypted-disks — disko mount of /mnt/storage/{fast,slow}/essential before k3s.
  3. Podman dockerCompat socket for GitLab CI image builds (no dind).
  4. GitLab shell runner — Nix tag, shared with discworld.
  5. restic — essential volumes → Cubbit home-server-essential.
  6. disk-health-ntfy, Cloudflare Access home-IP updater, Tailscale, OpenSSH, autoUpgrade from /persist/git/nix-configs#omega.

Data plane

  1. local-path-provisioner in kube-system maps fast/slow × essential/disposable plus the k3s default path.
  2. db-operator + PostgreSQL, MariaDB, Redis. Apps get Database CRs, not SOPS passwords.
  3. Garage at static.techtailors.net (also repo.slopkit.dev). s3-operator mints buckets.
  4. k8up in-cluster. Garage objects also rclone-mirrored to Cubbit.
  5. KubeVirt sandbox VMs in ns vms (ubuntu-lts, nixos), SSH via vm-router / Guacamole.