backup: 2026-06-07 01:31
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
|||||||
|
# Emacs temp files
|
||||||
|
*~
|
||||||
|
#*#
|
||||||
|
.#*
|
||||||
|
|
||||||
|
# LaTeX export artifacts
|
||||||
|
*.aux
|
||||||
|
*.log
|
||||||
|
*.out
|
||||||
|
*.toc
|
||||||
|
*.fls
|
||||||
|
*.fdb_latexmk
|
||||||
|
*.synctex.gz
|
||||||
|
*.tex
|
||||||
|
auto/
|
||||||
|
|
||||||
|
# Org export outputs (derived from .org source)
|
||||||
|
*.html
|
||||||
|
*.pdf
|
||||||
|
*.docx
|
||||||
|
*.odt
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
:PROPERTIES:
|
||||||
|
:ID: bf4dde56-0967-4374-94ed-771301e47c66
|
||||||
|
:END:
|
||||||
|
|
||||||
|
#+title: azos
|
||||||
|
#+filetags: :project: :knowledge:
|
||||||
|
|
||||||
|
* Architecture
|
||||||
|
|
||||||
|
azos is a NixOS/home-manager configuration repo with a two-tier feature system:
|
||||||
|
|
||||||
|
- =azos-core/= — git submodule containing shared, reusable features (base, editor, claude-memory, claude-skills, dev, etc.)
|
||||||
|
- =features/= — machine-specific features (claude, encryption, hyprland, audio, etc.)
|
||||||
|
- =home-manager/home.nix= — home-manager entry point; manually lists all modules to import
|
||||||
|
- =_machines/= — per-machine NixOS configs; passes =suiteModules= as =specialArgs=
|
||||||
|
|
||||||
|
Feature auto-discovery is via =import-tree= in each flake.nix. Features from both
|
||||||
|
=azos-core/features/= and =azos/features/= are collected into =config.flake.modules=.
|
||||||
|
|
||||||
|
** Module registration pattern
|
||||||
|
|
||||||
|
Each feature's =default.nix= registers itself:
|
||||||
|
|
||||||
|
#+begin_src nix
|
||||||
|
config.flake.modules.homeManager.<name> = { lib, config, pkgs, ... }: {
|
||||||
|
options.azos.<name>.enable = lib.mkOption { ... };
|
||||||
|
config = lib.mkIf config.azos.<name>.enable { ... };
|
||||||
|
};
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Modules are then imported in =home-manager/home.nix= via:
|
||||||
|
|
||||||
|
#+begin_src nix
|
||||||
|
imports = [ suiteModules.homeManager.<name> ... ];
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Option namespace
|
||||||
|
|
||||||
|
=azos.<feature-name>.<option-name>=
|
||||||
|
|
||||||
|
Dependencies between features use =lib.mkDefault true= to auto-enable:
|
||||||
|
|
||||||
|
#+begin_src nix
|
||||||
|
azos.claude-memory.enable = lib.mkDefault true;
|
||||||
|
azos.claude-skills.enable = lib.mkDefault true;
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** File deployment
|
||||||
|
|
||||||
|
- Static files: =home.file."path".source = ./file;=
|
||||||
|
- Generated text: =home.file."path".text = "...";=
|
||||||
|
- Runtime scripts (e.g. merging JSON): =home.activation.<name> = lib.hm.dag.entryAfter ["writeBoundary"] ''...'';=
|
||||||
|
|
||||||
|
* Conventions
|
||||||
|
|
||||||
|
- azos-core features belong to the submodule; machine-specific features live in the outer repo
|
||||||
|
- Extensible options follow the pattern established by =azos.claude.globalSkills= and =azos.claude.globalMdSections=: attrsets any module can contribute to, deployed by the owning feature
|
||||||
|
- Emacs config is literate org: =azos-core/features/editor/emacs/config.org=
|
||||||
|
- Emacs base config: =azos-core/features/base/emacs/config.org=
|
||||||
|
- agent-shell defaults to Claude Code on lauretta via =(setq agent-shell-preferred-agent-config 'claude-code)= in =features/lauretta/emacs/config.org=; this symbol skips agent selection entirely (no prompt)
|
||||||
|
|
||||||
|
* Gotchas
|
||||||
|
|
||||||
|
- =azos-core= is a git submodule — =git add= must be run inside it separately from the outer repo
|
||||||
|
- Nix flakes only evaluate git-tracked files; new files must be staged (=git add=) before =nix build= will see them
|
||||||
|
- =import-tree= auto-discovers features but only sees tracked files — same constraint
|
||||||
|
- The machine name is =lauretta=; machine config is at =_machines/lauretta.nix=
|
||||||
|
|
||||||
|
* Key Files
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------+---------|
|
||||||
|
| =azos-core/features/claude-memory/default.nix= | org-roam MCP server integration |
|
||||||
|
| =azos-core/features/claude-skills/default.nix= | global skills + CLAUDE.md deployment |
|
||||||
|
| =azos-core/features/claude-skills/skills/todo.md= | per-project TODO management skill |
|
||||||
|
| =azos-core/features/claude-skills/skills/project-brain.md= | org-roam second brain skill |
|
||||||
|
| =azos/features/claude/default.nix= | installs claude-code, enables claude-memory + claude-skills |
|
||||||
|
| =azos/home-manager/home.nix= | home-manager entry point, imports all modules |
|
||||||
|
| =azos-core/features/editor/emacs/config.org= | literate Emacs config (org-roam at line ~452) |
|
||||||
|
| =azos/azos-core= | git submodule pointing to shared feature library |
|
||||||
|
| =features/lauretta/emacs/config.org= | lauretta-specific Emacs overrides (agent-shell, LLM, beacon, caldav) |
|
||||||
|
| =~/.claude/settings.json= | Claude Code global permissions; read-only org-roam MCP tools are always-allowed here |
|
||||||
|
|
||||||
|
* org-roam Setup
|
||||||
|
|
||||||
|
- Directory: =~/roam/=
|
||||||
|
- Database: =~/.emacs.d/org-roam.db= (sqlite-builtin connector)
|
||||||
|
- MCP server: =org-roam-mcp= registered in =~/.claude.json= via home-manager activation
|
||||||
|
- org-agenda now includes =~/roam/= so TODOs in roam files appear in agenda
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
:PROPERTIES:
|
||||||
|
:ID: 30f0f6fe-da90-496c-afaf-5d26ea471bbf
|
||||||
|
:END:
|
||||||
|
#+title: 2026-06-06
|
||||||
|
* Researching
|
||||||
|
** Have to do the thing
|
||||||
|
** Started other projects
|
||||||
|
* Setting up knowledge base
|
||||||
|
** Setting up org roam mcp for my
|
||||||
|
* Good luck
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
:PROPERTIES:
|
||||||
|
:ID: c87d8901-bbee-4397-bff1-af8432b4f66e
|
||||||
|
:END:
|
||||||
|
|
||||||
|
#+title: homey
|
||||||
|
#+filetags: :project: :knowledge:
|
||||||
|
|
||||||
|
** Architecture
|
||||||
|
|
||||||
|
NixOS homelab on Raspberry Pi 4 (8 GB). Domain: zakobar.com. Static IP: 192.168.1.100. nixpkgs pin: nixos-25.05.
|
||||||
|
|
||||||
|
Container runtime: Podman via =virtualisation.oci-containers=. All containers join the =homey= podman network (created by =podman-homey-network.service= in =common.nix=). Inter-container DNS via container names; Caddy proxies via =127.0.0.1:<port>=.
|
||||||
|
|
||||||
|
Reverse proxy: Caddy with Cloudflare DNS-01 wildcard cert for =*.zakobar.com=. Built via =pkgs.caddy.withPlugins= with =github.com/caddy-dns/cloudflare@v0.2.4= (resolved hash: =sha256-pRrLBlYRaAyMYwPXeTy4WqWNRu/L9K6Mn2src11dGh8==). Each vhost generates a pair: HTTPS vhost + =http://= vhost for cloudflared loopback. Authelia =forward_auth= uses =/api/authz/forward-auth= (v4.38+ endpoint, not legacy).
|
||||||
|
|
||||||
|
Auth stack: OpenLDAP ← Authelia (TOTP 2FA). Authelia config is rendered entirely at build time from Nix strings. A =NIXOS_CONFIG_HASH= env var on the container forces a restart whenever the config changes (bind-mounts resolve symlinks at start, so the running container would otherwise keep the old config).
|
||||||
|
|
||||||
|
Monitoring: Prometheus (9090) + node_exporter (9100) + systemd_exporter (9558) + Grafana (3002). Node Exporter Full dashboard pre-provisioned (fetchurl hash resolved: =sha256-1DE1aaanRHHeCOMWDGdOS1wBXxOF84UXAjJzT5Ek6mM=, ID 1860 rev 37). Grafana proxy auth: Authelia → Remote-User header → Caddy maps to X-WEBAUTH-USER → Grafana auto-signs-in. All reaching Grafana are confirmed admins (Authelia enforces two_factor + admins group).
|
||||||
|
|
||||||
|
Uptime Kuma sync: a Python =oneshot= service runs after container start. Hash-gated — only re-syncs when the monitor JSON changes. Supports =keyword= (keyword monitor type) and =maxretries= fields beyond the basic =name/url/interval=.
|
||||||
|
|
||||||
|
Attic (self-hosted Nix binary cache): cache name =main=, public key =main:9SZt/6plBU7jjQzz90J7O011I13hmJvOMYouxNqExNQ==, endpoint =https://attic.zakobar.com/main=. Setup completed 2026-05-30. NAR content not backed up — reproducible from source. Tokens are stateless JWTs; regenerate with same =atticadm= command if lost.
|
||||||
|
|
||||||
|
Eurovision Vote: Django app sourced from external flake =github:anerisgreat/eurovote=, wrapped by =modules/services/eurovote.nix=. Uses DynamicUser + StateDirectory so systemd owns =/var/lib/eurovote/=; no tmpfiles entry needed.
|
||||||
|
|
||||||
|
Backup: Restic daily at 03:00 to S3 (Backblaze B2, bucket =zakobar-home-backup=). Pre-hook: Nextcloud maintenance mode on + pg_dump. Post-hook: maintenance mode off. Manual offload: =restic copy= to local disk. NAR content and media excluded.
|
||||||
|
|
||||||
|
Reliability hardening in =hosts/pi-main/default.nix=:
|
||||||
|
- Hardware watchdog: =bcm2835_wdt= kernel module, systemd watchdog runtimeTime=300s / rebootTime=360s
|
||||||
|
- WiFi power save disabled: brcmfmac driver drops connections under low traffic; disabled via =iw= on interface up
|
||||||
|
- Network watchdog: timer every 2 min (starts 5 min after boot), pings gateway, restarts wpa_supplicant, reboots if still dead after 30s
|
||||||
|
- zramSwap: zstd, 25% RAM (~2 GB) — breathing room for PHP upload spikes
|
||||||
|
- Nix build-dir: =/mnt/data/nix-build= — avoids small tmpfs filling during large builds
|
||||||
|
|
||||||
|
Bootstrap: =pi-main-bootstrap= config builds an SD image (=sd-image-aarch64.nix=) for first flash.
|
||||||
|
|
||||||
|
** Conventions
|
||||||
|
|
||||||
|
=homeyConfig= specialArgs (passed to every module): =domain=, =organization=, =timezone=. Never hardcode domain strings.
|
||||||
|
|
||||||
|
=users.mutableUsers = false= — all user config must be declared in Nix.
|
||||||
|
|
||||||
|
Secret injection pattern: =LoadCredential= stages sops-decrypted file into =$CREDENTIALS_DIRECTORY= before Exec*; shell script reads and exports. Ephemeral env files written to =/run/= and cleaned up in =ExecStopPost= / =postStop=.
|
||||||
|
|
||||||
|
Authelia =accessControlRules=: sorted by =priority= at build time (lower = first). Authelia stops at first match, so more-specific rules must have lower priority. Ranges: 0=bypass, 10–19=blanket bypass, 20–49=admin two_factor+deny pairs, 50–64=one_factor open, 65–79=per-path (resources + subject combos).
|
||||||
|
|
||||||
|
=accessControlRules= option is declared unconditionally (not inside =mkIf cfg.enable=) so any module can contribute rules even when Authelia is disabled. Same pattern for =homey.monitoring.monitors=.
|
||||||
|
|
||||||
|
Attic token generation: run =atticadm make-token= inside the container. Tokens are stateless; losing one means just regenerating it with the same command.
|
||||||
|
|
||||||
|
DynamicUser services (Eurovision Vote): secrets must be mode =0444= (not =0400=) because DynamicUser gets a random UID that cannot be pre-assigned as owner.
|
||||||
|
|
||||||
|
Caddy Cloudflare plugin secrets: uses =LoadCredential= + =ExecStart= override (clears list with empty string first, then sets the real start command) to export =CLOUDFLARE_API_TOKEN= before exec-ing caddy.
|
||||||
|
|
||||||
|
** Gotchas
|
||||||
|
|
||||||
|
hdparm APM udev rule was removed — USB-SATA bridges often don't support APM commands and hdparm hangs indefinitely, causing boot-time crashes. =hdparm= is still available as a package for manual use.
|
||||||
|
|
||||||
|
=storage.nix= config is gated on =lib.mkIf (cfg.device != "")= — if =homey.storage.device= is empty string, the mount and all tmpfiles rules are skipped. Useful during initial setup.
|
||||||
|
|
||||||
|
Grafana login form disabled (=disable_login_form = true=) — recovery requires re-enabling it in the Nix config. All proxy-auth users are auto-assigned Admin role (safe because Authelia already restricts to admins group).
|
||||||
|
|
||||||
|
Nextcloud preview generation: a separate =oneshot= service =nextcloud-generate-previews= (declared in =hosts/pi-main/default.nix=) fills missing thumbnails after first start. Must be triggered manually or via timer.
|
||||||
|
|
||||||
|
Authelia config bind-mount gotcha: NixOS resolves the symlink to the nix store path at container start. Without =NIXOS_CONFIG_HASH= env var, a config change would not take effect until manual container restart.
|
||||||
|
|
||||||
|
WiFi network name: =Zakobar=. sops secret key: =wifi/psk=. The secret file must contain exactly one line: =wifi_psk=<password>=. The =ext:wifi_psk= format is wpa_supplicant's literal substitution syntax, not an env var.
|
||||||
|
|
||||||
|
Attic: writing ephemeral TOML config (not a real file in the store) via =ExecStartPre= shell script that writes to =/run/attic-config.toml=. JWT secret interpolated into the TOML at runtime.
|
||||||
|
|
||||||
|
** Key Files
|
||||||
|
|
||||||
|
- =flake.nix= — module list, =mkHost= builder, =homeyConfig= specialArgs, =rpi4Headless= hardware snippet
|
||||||
|
- =hosts/pi-main/default.nix= — enabled services, static IP, WiFi, reliability hardening, Attic substituter config
|
||||||
|
- =hosts/pi-main-bootstrap/default.nix= — SD card bootstrap image
|
||||||
|
- =modules/caddy.nix= — =virtualHosts= option, dual vhost generation, Authelia forward_auth snippet
|
||||||
|
- =modules/services/authelia.nix= — access control rule rendering, =accessControlRules= option (unconditional)
|
||||||
|
- =modules/services/uptime-kuma.nix= — =homey.monitoring.monitors= option (unconditional), sync script
|
||||||
|
- =modules/services/attic.nix= — Nix binary cache, JWT token config, netrc injection for Nix daemon
|
||||||
|
- =modules/services/attic-setup.md= — post-deploy steps, token commands, client config, setup history
|
||||||
|
- =modules/services/eurovote.nix= — DynamicUser wrapper for external flake module
|
||||||
|
- =modules/monitoring.nix= — Prometheus + Grafana, proxy auth wiring, Node Exporter Full dashboard
|
||||||
|
- =modules/common.nix= — Nix settings, podman network creation, sops global config
|
||||||
|
- =modules/storage.nix= — external HD mount, =extraDirs= option
|
||||||
|
- =modules/backup.nix= — Restic, pre/post hooks, =extraPaths= option
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
:PROPERTIES:
|
||||||
|
:ID: d9a69a66-2f85-447d-8e86-31cf0af67397
|
||||||
|
:END:
|
||||||
|
|
||||||
|
#+title: personal-site
|
||||||
|
#+filetags: :project: :todo:
|
||||||
|
|
||||||
|
* TODO Create run-log page that will be managed by this repo where I will log runtimes from weekly runs
|
||||||
|
* TODO Finish editing existing blog entries
|
||||||
Reference in New Issue
Block a user