Skip to content

Repository files navigation

MiniPC-Deployer

The deploy repository for the Owner's headless homelab box (the AWOW AK41 always-on core): a zero-touch, always-on Docker stack — split-horizon DNS (Technitium), reverse proxy + TLS (Caddy), the NagLight life-tracker behind Google sign-in (oauth2-proxy), Actual Budget, LAN-only observability, and the bash backup service — plus an opt-in tier-2 catalog (photos, media, music, podcasts, home automation, passwords, …) behind compose profiles, off by default — with an unattended Ubuntu autoinstall image and full LAN remote management. This repo holds configuration only (compose, Caddy, autoinstall, provisioning); the application code lives in its own repos (NagLight, Finance-Auditor, …).

Public-facing repo (Q10.6): only *.example templates are tracked. No real secret, password, hash, email, or LAN detail is ever committed. Copy each *.example to its real name and fill it in locally.

The stack

Everything lives under stack/ — start with stack/README.md:

Service Role Auth
Technitium split-horizon LAN DNS + recursion + blocklists admin login
Caddy reverse proxy + automatic TLS
oauth2-proxy Google sign-in for the tracker Google OAuth
tracker (NagLight) the multi-user life tracker via oauth2-proxy
Actual Budget finances basic_auth
Uptime-Kuma · Dozzle · (ntfy) LAN-only observability LAN-only
Finance-Auditor daily finance audit pipeline (triggers Actual's bank sync, posts de-identified status to the tracker) — profile-gated until its own G-Final bridge-internal only
tier-2 opt-in catalog Immich/PhotoPrism · Jellyfin · Navidrome · Audiobookshelf · Vaultwarden · Home Assistant/Mosquitto · Syncthing · FreshRSS/Mealie/Homepage · diun — compose profiles, off by default (stack/README.md §9) per-service

Remote management of the headless box (SSH, Cockpit, the reimage ladder) is in REMOTE_MANAGEMENT.md.

Run it

There is no single "run" command — this repo produces a deploy image, not an app. To bring the stack up on a Docker host, follow stack/README.md: resolve the tracker image with scripts/ensure-local-images.sh (SR-006 chain: present → sibling ../NagLight build → declared TRACKER_PUBLIC_IMAGE) → docker compose up -d. To see the whole thing connect up virtually with zero real secrets, run the V1 sim (sim/README.md) — every external interface has a fictional, committed stand-in (Dex for Google, internal CA for ACME, Samba fixtures for Mini-serv). The root run.{cmd,sh,command} launchers are inert (this is not a launchable product).

Validate it

python scripts/check.py            # config-coverage + doc + registry gates (G1)
python scripts/validate_config.py  # env/Caddy/file coverage + YAML parse

Three progressively-more-real gates precede flashing the real AWOW:

Gate What Status
V1 — sim/ full stack on WSL2/Docker vs. a mock OIDC provider (Dex stands in for Google); split-horizon DNS, multi-user isolation, and the bash backup service + restore drill all exercised for real — plus mock-shim call-contract legs for drive power (run-drivepower-sim.sh) and docker-volume sources (run-volume-sim.sh, SR-013) GREEN — all checks pass
V2 — launcher (Personal repo, MINI_PC_Setup/) the Mini-serv rebuild launcher validated in Windows Sandbox (real task-import/reg/share rungs) GREEN
V3 — vmtest/ the REAL autoinstall booted in a local Hyper-V VM — every container baked into the ISO payload (Q10.9 B+), zero registry pulls at first boot scripted + smoke-tested; the boot itself is the Owner's step (needs elevation + the Hyper-V feature)

Dev-box container runtime (WSL2 + docker-ce) is installed and verified — see docs/status.md for the full ledger, including exactly which images are pinned and their digests.

Configuring the REAL box (not the sim)

vmtest/'s scripts (build-seed.sh, etc.) are VM-test-only — they substitute throwaway SIM secrets and an ephemeral SSH key on purpose, so never flash vmtest/.out/*.iso onto real hardware. To build the actual deploy image:

  1. Fill in a real stack/.env from .env.example (every knob is documented there and in stack/README.md §2 — mind the QUOTING RULE in its header: values with spaces must be double-quoted) and put your real SSH public key into stack/autoinstall/user-data (§"Build the USB"). Two opt-in decisions live here too: COMPOSE_PROFILES (which tier-2 services come up at first boot, stack/README §9) and the commented volume: lines in the backup config (stack/backup/backup.env.example) so the box's own state — the finances — joins the backup (SR-013).
  2. Filling .env today is still a manual step. The automated secret-handoff design in Personal\SECRET_HANDOFF.md (a sibling repo; extends the Owner's existing DPAPI credential pattern) was ratified 2026-07-25, but the tooling is not written yet — so hand-fill for now. Once built it materializes .env from Personal's credential store, and pathing values come from Personal\deploy\storage-map.md.
  3. Run vmtest/export-images.sh (it reads the real pinned tags in .env.example, not sim values) so the real USB also carries every core container image baked in (Q10.9 B+) — see stack/README.md §3. Tier-2 opt-in images are excluded from the bake by default; pass EXTRA_PROFILES="…" to include an enabled set (SR-012).
  4. After first boot, the one-time in-app authentications (not .env values): the Google OAuth client above is env-side, but Actual's SimpleFIN bank sync is configured inside Actual's own UI and stored in the actual_data volume (stack/README §2 manual steps). What survives a container update vs a reimage — credentials never live in containers; they live in volumes + .env, both recoverable — is spelled out in REMOTE_MANAGEMENT.md "State & credentials".

Development

This repo follows a gated, requirement-traced process. The working brief is AGENTS.md; the method is docs/process.md. Start with the code map in docs/architecture.md and the current state in docs/status.md.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages