Compare commits

..
Author SHA1 Message Date
beatzaplentyandClaude Sonnet 5 71d052e737 Migrate live secrets to sops-nix (Milestone 2)
Audited the working tree and full git history for committed secrets
(gitleaks + trufflehog + manual grep, see secrets-inventory.md, kept
local/gitignored per the spec). Found: a password hash shared by root
and the nixos user across every host, two live Beszel monitoring
tokens, and a GitHub fine-grained PAT embedded in a home-manager
nix.conf.

Migrates all of them to sops-nix:
- .sops.yaml + secrets/*.yaml, encrypted for admin + the age keys
  derived (via ssh-to-age) from each live host's existing SSH host
  key — no new key material transferred to any machine.
- users.users.{root,nixos}.hashedPasswordFile replaces the inline
  hashedPassword shared by every target.
- The GitHub PAT moves from a home-manager-managed, store-visible
  nix.conf to a sops.templates-rendered file included via nix.conf's
  native !include, system-wide instead of per-user.
- Beszel TOKEN moves from `environment` (store-visible) to
  `environmentFile` (runtime-only via sops.templates); the dead
  commented-out docker token is removed from the tree entirely.

Added a tracked pre-commit hook (gitleaks protect --staged, wired via
core.hooksPath) so a secret can't be committed by accident again, and
documented the sops workflow in README.md.

Structural verification only: all 17 flake targets evaluate, and
`nix build --dry-run --no-link` succeeds for the three currently
deployed hosts. Per CLAUDE.md, actual `nixos-rebuild switch` — the
step that confirms secrets decrypt and services start on a real
machine — is left for manual verification.

Git history still contains the original plaintext secrets; scrubbing
history (Milestone 3) and rotating every credential (Milestone 4) are
separate, deliberately gated steps per remove-sensetive-info-refactor.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 12:46:39 +10:00
beatzaplentyandClaude Sonnet 5 e76486efbe Refactor flake targets into platform x build-type matrix
Generates all nixosConfigurations from mkTarget(platform, buildType,
hostPath) instead of hand-written per-host blocks, so adding a new
platform or build type is a one-line addition. Per-machine identity
(hostname, hostId, secrets, stateVersion) moves into hosts/<name>/host.nix;
platform-specific config (hardware, boot, networking) into
modules/platforms/*.nix; build-type config (minimal/server/docker/gui/
nix-cache/pxe-boot) into modules/build-types/*.nix.

Old flat targets (nixos, docker, server, nix-cache, nix-minimal, pxe-boot)
are replaced by the 17-target <platform>-<buildtype> matrix; each new
target was verified to evaluate before its old counterpart was removed.
CI workflows and docs/aliases now discover hosts dynamically via
nixosConfigurations attrNames and /etc/flake-target instead of hardcoded
lists, so they can't drift from flake.nix again.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 12:03:33 +10:00
beatzaplentyandClaude Sonnet 5 302c3b671f Sync host lists with flake.nix and add CLAUDE.md
Remove the nonexistent kuma host and add the missing linode-minimal
host across README, AGENTS.md, docs, and CI eval workflows so they
match flake.nix's nixosConfigurations. Also add CLAUDE.md with
architecture/safety guidance for future Claude Code sessions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 09:48:05 +10:00
beatzaplenty 0900ff25ae updated to efi boot and resolved module paths 2026-07-19 06:27:22 +10:00
beatzaplenty 79d2ed0314 remove swap label 2026-07-18 08:14:39 +10:00
beatzaplenty 8932e52d72 updated to efi boot 2026-07-18 07:52:30 +10:00
beatzaplenty 4822f0b290 updated proxmox disko configuration 2026-07-18 05:54:32 +10:00
beatzaplenty f8de4c8abc removed fileSystems definition for disko config 2026-07-17 11:42:29 +10:00
beatzaplenty ca18a9d29d update configuration 2026-07-17 09:18:24 +10:00
beatzaplenty 7d113e302f update grub config 2026-07-15 13:23:09 +10:00
beatzaplenty bc68d8cf17 disabled disko module 2026-07-15 13:10:09 +10:00
beatzaplenty 4728982c05 updated mounts 2026-07-15 12:59:08 +10:00
beatzaplenty 8734b23746 updated mounts 2026-07-15 12:57:45 +10:00
beatzaplenty 5f52cb0cd7 disabled disko in linode-minimal 2026-07-15 12:47:35 +10:00
beatzaplenty f4139eec13 updated bios partition definition 2026-07-15 11:44:03 +10:00
beatzaplenty afc57e3755 remove grub mount point 2026-07-15 11:29:52 +10:00
beatzaplenty d7cad12720 remove bios type 2026-07-15 11:25:25 +10:00
beatzaplenty bab83d1aad added bios partition 2026-07-15 11:22:21 +10:00
beatzaplenty da0cd225be removed duplicate boot entry 2026-07-15 11:08:50 +10:00
beatzaplenty de4b4302c9 add boot loader path 2026-07-15 11:05:12 +10:00
beatzaplenty 45fe770569 remove file systems. they are defined in disko 2026-07-15 10:29:10 +10:00
beatzaplenty 3797c8885e updated disko config 2026-07-15 09:59:37 +10:00
beatzaplenty 2fb6b1de00 update linode host folder name to linode-minimal 2026-07-15 09:38:12 +10:00
beatzaplenty a2f817b098 add linode disko config 2026-07-15 09:36:04 +10:00
beatzaplenty d9015e87d3 updated flake 2026-07-15 09:28:33 +10:00
beatzaplenty 5dc41e2866 added disko configuration to remove disk formatting from auto installer 2026-07-15 07:30:32 +10:00
beatzaplenty 0aae9c3bcf Merge branch 'main' of https://gitea.lan.ddnsgeek.com/beatzaplenty/nixos 2026-07-14 20:52:05 +10:00
beatzaplenty 2a426615cb update hardware config 2026-07-14 20:50:21 +10:00
beatzaplenty 7be80e7ab6 Update hosts/nix-minimal/configuration.nix 2026-07-13 14:07:57 +00:00
beatzaplenty d8d2718289 update module path 2026-07-13 19:49:45 +10:00
beatzaplenty e577fda538 updated flake.lock 2026-07-13 19:44:35 +10:00
beatzaplenty ffd2705ee3 revert 2026-07-13 19:22:10 +10:00
beatzaplenty 54e11853b5 update module path 2026-07-13 19:19:39 +10:00
beatzaplenty 5fcaa6ae87 update disko path 2026-07-13 19:17:43 +10:00
beatzaplenty a5ef1aa519 added disko configuration 2026-07-13 19:10:21 +10:00
beatzaplenty a919252a47 create linode flake 2026-07-13 17:46:12 +10:00
beatzaplenty 3fda26e46c update common home path 2026-07-13 16:07:17 +10:00
beatzaplenty d48e4d4f10 moved common into modules 2026-07-13 16:03:48 +10:00
beatzaplenty d5c13bc2d2 remove hardware configuration 2026-07-13 15:50:24 +10:00
beatzaplenty fe83640776 change path 2026-07-13 14:29:29 +10:00
beatzaplenty 03066d716d fix syntax 2026-07-13 14:10:38 +10:00
beatzaplenty bcf57246e0 enable beszel agent debugging 2026-07-13 14:09:33 +10:00
beatzaplenty 9fb6d9da13 update path 2026-07-13 14:04:36 +10:00
beatzaplenty 24dd5adfed change paths 2026-07-13 13:57:37 +10:00
beatzaplenty 489ed11406 update extra filesystems 2026-07-13 13:49:58 +10:00
beatzaplenty f77a26402f update path 2026-07-13 13:44:50 +10:00
beatzaplenty 9eb219360e fix syntax 2026-07-13 13:37:59 +10:00
beatzaplenty a3fe69a89c added extra filesystems 2026-07-13 13:36:36 +10:00
beatzaplenty aa7a98f884 remove commented lines 2026-07-13 13:23:42 +10:00
beatzaplenty af48b1aef6 remove raspi docker data mount 2026-07-13 12:48:14 +10:00
beatzaplenty 33522a4613 permit root login 2026-07-13 12:39:58 +10:00
beatzaplenty 217564ffc4 fix path 2026-07-13 12:15:00 +10:00
beatzaplenty 8e571c7592 add docker backup share 2026-07-13 12:12:58 +10:00
beatzaplenty 7ea203e22d added raspi-backup share 2026-07-13 11:44:45 +10:00
beatzaplenty 567e2536b1 updated server configuration 2026-07-13 05:55:40 +10:00
beatzaplenty f3c6f13e89 add boot include to zfs mount module 2026-07-13 03:33:09 +10:00
beatzaplenty b9b3d06810 fix path typo 2026-07-13 02:56:20 +10:00
beatzaplenty efa0ee26fe modularized locale settings 2026-07-13 02:43:08 +10:00
beatzaplenty 0c68f54e1f remove commented lines 2026-07-13 02:26:46 +10:00
beatzaplenty c9b449d60e add pkgs 2026-07-13 02:16:05 +10:00
beatzaplenty a495de3f83 fix syntax 2026-07-13 02:14:49 +10:00
beatzaplenty 6cc79e0c36 fix syntax 2026-07-13 02:14:21 +10:00
beatzaplenty 4078230052 removed port from firewall 2026-07-13 02:05:13 +10:00
beatzaplenty 06dc25c983 modularized rpcbind enable and added to server config 2026-07-13 02:00:55 +10:00
beatzaplenty aa2af2d169 updated module paths 2026-07-13 01:53:32 +10:00
beatzaplenty 1788faf093 updated flake.lock 2026-07-13 01:45:44 +10:00
beatzaplenty 33584d9a02 fix typo 2026-07-13 01:44:05 +10:00
beatzaplenty b25d9db82b clean up commented lines 2026-07-13 01:42:28 +10:00
beatzaplenty 94df02515d removed let statement 2026-07-13 01:34:19 +10:00
beatzaplenty 8b49deb1d7 modularized docker health to gotify service 2026-07-13 01:29:45 +10:00
beatzaplenty fac343fa76 modularized nextcloud cron job 2026-07-13 01:25:16 +10:00
beatzaplenty 9f59ed4426 modularized raspi mount 2026-07-13 01:12:43 +10:00
beatzaplenty 1f2dc03486 update log path 2026-07-13 01:09:34 +10:00
beatzaplenty da75a23700 modularized traefik log rotatation config 2026-07-13 01:05:44 +10:00
beatzaplenty 3d42dee0bf update path 2026-07-13 01:00:03 +10:00
beatzaplenty 9fef163850 updated module directory structure 2026-07-13 00:56:19 +10:00
beatzaplenty c64e4ad7d5 enable tailscale module 2026-07-13 00:46:07 +10:00
beatzaplenty aeaa1f6479 modularized tailscale service 2026-07-13 00:44:29 +10:00
beatzaplenty bca8c2f9df move docker system packages to docker-service module 2026-07-13 00:36:52 +10:00
beatzaplenty 153b2f0cfa added pkgs include 2026-07-13 00:32:06 +10:00
beatzaplenty c1ba633bff modularized docker service 2026-07-13 00:30:10 +10:00
beatzaplenty 62edbd203d removed promotheus exporter 2026-07-12 19:09:46 +10:00
beatzaplenty fa3d91303c added beszel agent 2026-07-12 18:21:03 +10:00
beatzaplenty 59a01b35bf added beszel agent 2026-07-12 18:08:44 +10:00
beatzaplenty cf78588f00 added beszel port to firewall 2026-07-12 17:07:42 +10:00
beatzaplenty 7156c343bb remove beszel agent from docker and create module 2026-07-12 15:48:18 +10:00
beatzaplenty 32b65b0894 add semi colons 2026-07-10 08:01:58 +10:00
beatzaplenty 5046cae7b1 fix nix syntax 2026-07-10 08:00:37 +10:00
beatzaplenty 0286bb4dfa syntax change 2026-07-10 07:56:16 +10:00
beatzaplenty cf9bb14d4b updated beszel syntax 2026-07-10 07:51:54 +10:00
beatzaplenty 6d53a62f85 added beszel agent 2026-07-10 07:40:26 +10:00
beatzaplenty 4bf1ec450a removed tailscale 2026-07-08 13:24:43 +10:00
beatzaplenty 8bafae6eb2 added new public key for server 2026-07-08 13:09:28 +10:00
beatzaplenty 32323aee06 typo 2026-07-08 13:00:26 +10:00
beatzaplenty bd117a8dd5 added tailscale exit node module and enabled on server 2026-07-08 12:48:52 +10:00
beatzaplenty 12f6703e0f updated /mnt/docker permissions 2026-07-07 03:31:19 +10:00
beatzaplenty 56bf912c4d updated NFS shares and deleted individual share modules 2026-07-07 03:09:56 +10:00
beatzaplenty 0649c48b96 remove prune task 2026-07-07 00:28:15 +10:00
beatzaplenty d871f2a45d removed --force from docker prune service command 2026-07-07 00:20:10 +10:00
beatzaplenty 74bdbd8c9a added test share 2026-07-07 00:03:22 +10:00
gitea-actions 258d471b21 chore: update flake.lock 2026-07-06 06:14:46 +00:00
beatzaplenty a86300f094 Update hosts/docker/configuration.nix
added systemd job to prune docker data
2026-07-04 09:02:18 +00:00
beatzaplenty f8886b2215 Update hosts/docker/configuration.nix 2026-07-02 11:35:55 +00:00
beatzaplenty e538222c24 Update hosts/docker/configuration.nix
updated sym links to config shared storage
2026-07-02 09:34:00 +00:00
beatzaplenty 004529aa88 Update modules/nix/docker-data.nix 2026-07-02 01:37:55 +00:00
beatzaplenty 35352cc9b2 Update hosts/server/configuration.nix 2026-07-01 22:28:36 +00:00
beatzaplenty 70d459de15 Update hosts/server/configuration.nix 2026-07-01 22:17:33 +00:00
beatzaplenty 60886c6a64 Update hosts/server/configuration.nix 2026-07-01 21:58:20 +00:00
beatzaplenty 564f8548ec Update hosts/server/configuration.nix 2026-07-01 21:53:01 +00:00
beatzaplenty 36c3c48474 Update hosts/server/configuration.nix 2026-07-01 21:50:42 +00:00
beatzaplenty c29d8f9df7 Update hosts/server/configuration.nix 2026-07-01 21:32:24 +00:00
beatzaplenty b82c868b7a moved docker data mounts into one module 2026-07-01 20:58:19 +10:00
beatzaplenty 6f6e9a5a11 Update hosts/docker/configuration.nix 2026-07-01 10:29:30 +00:00
beatzaplenty 1b588d0ea0 Add modules/nix/mount-docker-databases.nix 2026-07-01 10:28:34 +00:00
beatzaplenty 3212d80b63 Update hosts/server/configuration.nix 2026-07-01 10:27:05 +00:00
beatzaplenty e28d953b8d Update hosts/server/configuration.nix
add ,crossmnt option to volumes NFS export
2026-07-01 09:47:53 +00:00
beatzaplenty 566135bbbb Update common/home.nix 2026-07-01 08:59:21 +00:00
beatzaplenty 8af805241e Update modules/nix/mount-docker-volumes.nix 2026-07-01 08:46:38 +00:00
beatzaplenty d3c26d7e9e Update modules/nix/mount-docker-config.nix
updated mount path
2026-07-01 08:46:12 +00:00
git 63f5acb18f updated config for new ZFS/NFS shares 2026-07-01 16:59:55 +10:00
beatzaplenty 074ed2cbe1 Update hosts/docker/configuration.nix 2026-07-01 05:57:13 +00:00
beatzaplenty 1cb6bdae2f Add modules/nix/mount-docker-config.nix 2026-07-01 05:56:26 +00:00
beatzaplenty bf74783623 Update hosts/server/configuration.nix 2026-07-01 05:42:19 +00:00
beatzaplenty c31606922e Update hosts/server/configuration.nix 2026-07-01 05:29:17 +00:00
git a2f2af77b6 updated lock file 2026-07-01 13:47:33 +10:00
beatzaplenty 7aa4c56660 Update flake.nix 2026-06-30 23:06:26 +00:00
beatzaplenty 100923e1a9 Update hosts/server/configuration.nix 2026-06-30 21:59:48 +00:00
beatzaplenty 0e105923da Update hosts/server/configuration.nix 2026-06-30 21:55:42 +00:00
beatzaplenty 2d1cd0674c Update hosts/server/configuration.nix 2026-06-30 21:51:37 +00:00
beatzaplenty abd0b83cb2 Update hosts/server/configuration.nix 2026-06-30 21:48:02 +00:00
beatzaplenty 6ad9b5ffa4 Update hosts/server/configuration.nix 2026-06-30 21:40:38 +00:00
beatzaplenty 88a9d4dd78 Update hosts/server/configuration.nix 2026-06-30 21:34:55 +00:00
beatzaplenty 472c18922c Update hosts/server/configuration.nix 2026-06-30 21:22:20 +00:00
beatzaplenty 33cd951205 Update hosts/server/configuration.nix 2026-06-30 21:15:41 +00:00
beatzaplenty 903e5243a7 Update hosts/server/configuration.nix 2026-06-30 21:01:31 +00:00
beatzaplenty 3c5081506b Update hosts/server/configuration.nix 2026-06-30 20:55:53 +00:00
beatzaplenty edb898d27b Update hosts/server/configuration.nix 2026-06-30 20:49:46 +00:00
beatzaplenty c32341b2d5 Update hosts/server/configuration.nix 2026-06-30 20:39:52 +00:00
beatzaplenty 745bbe0732 Update hosts/server/configuration.nix 2026-06-30 20:35:01 +00:00
beatzaplenty 48c5e5c094 Update hosts/server/configuration.nix 2026-06-30 20:23:40 +00:00
beatzaplenty 287f42cd81 Update hosts/server/configuration.nix 2026-06-30 20:09:51 +00:00
beatzaplenty 8434e90aec Update hosts/docker/configuration.nix 2026-06-28 08:42:37 +00:00
beatzaplenty 5141123b34 Update hosts/docker/configuration.nix 2026-06-28 08:39:41 +00:00
beatzaplenty 84488de426 clean up docker version config 2026-06-28 17:48:04 +10:00
beatzaplenty ed2d86bead add overlay for docker version for flake.nix 2026-06-28 17:31:02 +10:00
beatzaplenty 1b6ffd9117 revert bd9aef4624
revert Update flake.nix
2026-06-28 07:27:53 +00:00
beatzaplenty bd9aef4624 Update flake.nix 2026-06-28 07:26:51 +00:00
beatzaplenty 16d345262d updated configuration 2026-06-28 16:55:40 +10:00
beatzaplenty ee30e40ce4 Update hosts/docker/configuration.nix 2026-06-28 06:40:12 +00:00
beatzaplenty 79d24c7497 update docker version 2026-06-28 16:08:46 +10:00
beatzaplenty dcf1c8e780 allowed old docker version 2026-06-28 15:52:38 +10:00
beatzaplenty 27470bd854 updated flake.lock 2026-06-28 15:32:14 +10:00
git 72b58093b1 update lock file 2026-06-27 13:41:28 +10:00
beatzaplenty 688904321a Update flake.lock 2026-06-27 03:38:55 +00:00
beatzaplenty 2fb0928ff5 Update hosts/docker/configuration.nix 2026-06-27 03:33:49 +00:00
beatzaplenty d424a70110 Update flake.lock.old 2026-06-27 03:12:17 +00:00
beatzaplenty 60faf681b3 Update hosts/docker/configuration.nix 2026-06-27 03:02:37 +00:00
beatzaplenty 4fb1a6a204 Update hosts/docker/configuration.nix 2026-06-27 02:50:33 +00:00
beatzaplenty a61f88d4a3 Update hosts/docker/configuration.nix 2026-06-24 02:00:32 +00:00
gitea-actions 923ac6c178 chore: update flake.lock 2026-06-22 06:13:04 +00:00
beatzaplenty cc986d1ab7 Update common/configuration.nix 2026-06-14 16:32:20 +00:00
beatzaplenty 1fd0adee54 updated pxe config 2026-06-02 19:00:30 +10:00
beatzaplenty b0d480adb8 updated server root folders 2026-06-02 18:33:13 +10:00
beatzaplenty e78dd516a6 updated ipxe configuration 2026-06-02 18:05:39 +10:00
beatzaplenty 4e30618954 added tftp server 2026-06-02 12:03:00 +10:00
beatzaplenty 3259391451 updated documentation 2026-06-01 18:22:05 +10:00
beatzaplenty 31b57930c6 created pxe-boot configuration 2026-06-01 17:34:51 +10:00
gitea-actions 0e29abd0ac chore: update flake.lock 2026-06-01 06:13:00 +00:00
beatzaplenty 038103391d Update hosts/server/configuration.nix 2026-06-01 01:42:25 +00:00
beatzaplenty 7f719eb6a9 Update hosts/server/configuration.nix 2026-06-01 01:24:04 +00:00
beatzaplenty 47fdce6193 Update hosts/server/configuration.nix 2026-06-01 00:09:59 +00:00
gitea-actions e68b4f8d14 chore: update flake.lock 2026-05-25 06:13:47 +00:00
gitea-actions c47052fc21 chore: update flake.lock 2026-05-21 19:58:06 +00:00
beatzaplenty 59a2e65bf5 updated authorized keys 2026-05-12 13:28:33 +10:00
beatz174-bit 4a928707f6 Merge pull request #4 from beatz174-bit/chore/update-flake-lock
chore: update flake.lock
2026-05-12 13:02:58 +10:00
beatz174-bit 5be2bdb170 chore: update flake.lock 2026-05-12 02:58:23 +00:00
beatz174-bit 4abe01c0cb Merge pull request #3 from beatz174-bit/codex/implement-flake.lock-automation-in-nixos-26sknf
Add scheduled flake.lock updater and NixOS evaluation workflows (GitHub + Gitea) and docs
2026-05-12 12:40:56 +10:00
beatz174-bit d838784dd5 Merge branch 'main' into codex/implement-flake.lock-automation-in-nixos-26sknf 2026-05-12 12:40:49 +10:00
beatz174-bit e95a4b5f4d fix(ci): quote PR title fields in update workflow 2026-05-12 12:38:28 +10:00
beatz174-bit 247d8fc96b Merge pull request #2 from beatz174-bit/codex/implement-flake.lock-automation-in-nixos
ci: add scheduled flake.lock updates and NixOS evaluation checks
2026-05-12 12:31:10 +10:00
beatz174-bit 5f63a48731 ci: automate flake lock updates and host evaluation 2026-05-12 12:28:37 +10:00
beatzaplenty 8d26f62b57 updated docker container monitoring script path 2026-05-12 12:07:59 +10:00
beatzaplenty 089190ef23 updated authorized keys 2026-05-12 11:55:56 +10:00
beatzaplenty d36380b79a updated authorized keys 2026-05-12 11:53:43 +10:00
beatzaplenty 8dd20f6ced updated authorized keys 2026-05-12 11:24:54 +10:00
beatz174-bit 926df3d334 Merge pull request #1 from beatz174-bit/codex/refactor-nix-cache-for-binary-cache-and-remote-builder
Add Nix cache / remote-builder modules, wire hosts, and harden maintenance scripts
2026-05-12 11:09:50 +10:00
beatz174-bit 26eec71b8c Fix pure eval and harden nix script bootstrap 2026-05-12 11:09:23 +10:00
beatzaplenty 554f484593 update setup script 2026-05-12 07:15:12 +10:00
beatzaplenty 7de7c76597 Add codex environment scripts, README and AGENTS 2026-05-12 07:02:43 +10:00
beatzaplenty a36805d8dd Update hosts/docker/configuration.nix 2026-04-27 12:09:31 +00:00
beatzaplenty 0e244b2bc7 Update hosts/docker/configuration.nix 2026-04-27 12:05:04 +00:00
beatzaplenty 61f8ffb35e Update hosts/docker/configuration.nix 2026-04-27 12:00:36 +00:00
beatzaplenty b5c8e43688 Update hosts/docker/configuration.nix 2026-04-27 11:54:57 +00:00
beatzaplenty bd674bc5d9 Update hosts/docker/configuration.nix 2026-04-14 23:29:01 +00:00
beatzaplenty 97fceee985 Update hosts/docker/configuration.nix 2026-04-14 23:15:55 +00:00
beatzaplenty 0fe04bd956 Update hosts/docker/configuration.nix 2026-04-14 23:05:01 +00:00
beatzaplenty 6862fb6455 Update hosts/docker/configuration.nix 2026-04-13 21:58:10 +00:00
beatzaplenty 4632c14191 Update hosts/docker/configuration.nix 2026-04-02 00:07:32 +00:00
beatzaplenty 54b795aba8 Update hosts/docker/configuration.nix 2026-04-01 23:38:07 +00:00
beatzaplenty a0cc52c3cc Update common/configuration.nix 2026-03-31 21:16:59 +00:00
beatzaplenty 0cdeba3b7a Update common/configuration.nix 2026-03-31 21:11:00 +00:00
beatzaplenty 4bf0e14663 Update hosts/server/configuration.nix 2026-03-27 19:52:58 +00:00
beatzaplenty 4444f4e70d Update hosts/server/configuration.nix 2026-03-27 19:48:50 +00:00
beatzaplenty 4b4b7834d6 Update hosts/docker/configuration.nix 2026-02-25 00:20:50 +00:00
beatzaplenty 4ddef559a4 Update hosts/docker/configuration.nix 2026-02-25 00:17:39 +00:00
beatzaplenty 33b596d254 Update hosts/docker/configuration.nix 2026-02-25 00:16:37 +00:00
beatzaplenty 105d20b94c Update common/home.nix 2026-02-17 16:00:33 +00:00
beatzaplenty 7d88bb7332 Update flake.nix 2026-02-17 15:59:35 +00:00
beatzaplenty 0711d0aae6 Update hosts/docker/configuration.nix 2026-02-17 15:57:26 +00:00
beatzaplenty d08f55af3a Update hosts/docker/configuration.nix 2026-02-17 15:56:47 +00:00
beatzaplenty 03cd8e5755 Update hosts/docker/configuration.nix 2026-02-17 15:53:06 +00:00
beatzaplenty 3b15296cf0 Update hosts/docker/configuration.nix 2026-02-17 15:52:05 +00:00
beatzaplenty aba8f7605d Update hosts/docker/configuration.nix 2026-02-17 15:50:06 +00:00
beatzaplenty 7880f54068 Update hosts/docker/configuration.nix 2026-02-17 15:40:04 +00:00
beatzaplenty d4e67d5785 Update hosts/docker/configuration.nix 2026-02-17 11:44:58 +00:00
beatzaplenty a73061909e Update hosts/docker/configuration.nix 2026-02-16 09:22:16 +00:00
beatzaplenty d07236986c Update hosts/docker/configuration.nix 2026-02-16 09:14:46 +00:00
beatzaplenty 667348bc98 Update hosts/nix-cache/configuration.nix 2026-02-09 10:05:23 +00:00
beatzaplenty c5509c420b Update hosts/server/configuration.nix 2026-02-09 10:00:53 +00:00
beatzaplenty f1dcabd579 modified: hosts/docker/configuration.nix 2025-12-20 13:06:57 +10:00
beatzaplenty ca5914062e modified: hosts/server/configuration.nix 2025-12-18 12:24:04 +10:00
beatzaplenty 025937ec6d modified: hosts/server/configuration.nix 2025-12-18 12:22:59 +10:00
beatzaplenty 4594242d1d modified: hosts/server/configuration.nix 2025-12-18 12:16:06 +10:00
beatzaplenty 832e2bb39d modified: hosts/server/configuration.nix 2025-12-18 12:06:39 +10:00
beatzaplenty b7f5ae83cb modified: hosts/server/configuration.nix 2025-12-18 10:51:11 +10:00
beatzaplenty 2dc246b4ec modified: hosts/kuma/configuration.nix 2025-12-17 14:57:34 +10:00
beatzaplenty 9deddd14e6 modified: flake.nix
new file:   hosts/kuma/configuration.nix
2025-12-17 14:34:23 +10:00
beatzaplenty 10ca67ac23 modified: flake.nix 2025-12-17 14:31:09 +10:00
beatzaplenty e4f726839f modified: flake.nix 2025-12-17 14:30:15 +10:00
beatzaplenty fb9f6185ec Update hosts/docker/configuration.nix 2025-12-16 12:01:55 +00:00
beatzaplenty a4e303fa34 Update hosts/docker/configuration.nix 2025-12-16 11:56:53 +00:00
beatzaplenty c3259ad3a2 Update hosts/docker/configuration.nix 2025-12-16 11:53:51 +00:00
beatzaplenty fd2d9d8aeb Update hosts/docker/configuration.nix 2025-12-16 11:52:41 +00:00
beatzaplenty bbaf012329 Update flake.nix 2025-12-16 11:42:35 +00:00
beatzaplenty e18b3bb76e Update flake.nix 2025-12-16 11:41:38 +00:00
beatzaplenty df6515ad6a Update flake.lock 2025-12-16 11:34:53 +00:00
beatzaplenty c731705075 Update flake.nix 2025-12-16 10:56:47 +00:00
beatzaplenty aa376a2448 Add flake.lock 2025-12-16 10:51:45 +00:00
beatzaplenty 141491233c modified: hosts/docker/configuration.nix 2025-07-23 18:23:25 +10:00
beatzaplenty 3d6b55df79 modified: hosts/docker/configuration.nix 2025-07-23 18:09:12 +10:00
beatzaplenty 84cd3a1a83 modified: hosts/nixos/home.nix 2025-07-22 17:21:30 +10:00
beatzaplenty 60f17723ba modified: hosts/nixos/home.nix 2025-07-22 17:19:13 +10:00
beatzaplenty da267255b0 modified: hosts/nixos/home.nix 2025-07-22 17:16:42 +10:00
beatzaplenty 17b45fd23e modified: hosts/nixos/home.nix 2025-07-22 17:15:33 +10:00
beatzaplenty 9cb5f9627c modified: hosts/nixos/home.nix 2025-07-22 17:13:40 +10:00
beatzaplenty 25b4c6cdd2 modified: hosts/nixos/home.nix 2025-07-22 17:11:46 +10:00
beatzaplenty 9575986b93 modified: hosts/nixos/home.nix 2025-07-22 17:07:16 +10:00
beatzaplenty 15f90bc2f2 modified: hosts/nixos/home.nix 2025-07-22 16:55:51 +10:00
beatzaplenty 119be5aca0 modified: hosts/nixos/home.nix 2025-07-22 16:47:21 +10:00
beatzaplenty 84a9a12f4d modified: hosts/nixos/home.nix 2025-07-22 16:44:34 +10:00
beatzaplenty f979f61be1 modified: hosts/nixos/home.nix 2025-07-22 16:37:38 +10:00
beatzaplenty b455028547 modified: hosts/nixos/home.nix 2025-07-22 16:29:29 +10:00
beatzaplenty c424cb1cb0 modified: hosts/nixos/home.nix 2025-07-22 16:22:14 +10:00
beatzaplenty 9d0b736a51 modified: hosts/nixos/home.nix 2025-07-22 16:12:08 +10:00
beatzaplenty 7a590a2d99 modified: hosts/nixos/home.nix 2025-07-22 16:10:58 +10:00
beatzaplenty 513c286a4a modified: hosts/nixos/home.nix 2025-07-22 16:09:06 +10:00
beatzaplenty 5e778c9045 modified: hosts/nixos/home.nix 2025-07-22 16:04:27 +10:00
beatzaplenty 274544a212 modified: hosts/nixos/home.nix 2025-07-22 15:57:39 +10:00
beatzaplenty 859f30a56c modified: hosts/nixos/home.nix 2025-07-22 15:55:05 +10:00
beatzaplenty 0b91b68333 modified: hosts/nixos/home.nix 2025-07-22 15:50:48 +10:00
beatzaplenty 27122baec0 modified: hosts/nixos/home.nix 2025-07-22 15:33:23 +10:00
beatzaplenty 0a8af8d8e4 modified: hosts/nixos/home.nix 2025-07-22 15:18:27 +10:00
beatzaplenty 2ca2f74bbc modified: flake.nix
modified:   hosts/nixos/configuration.nix
2025-07-22 14:29:45 +10:00
beatzaplenty fa9c3f5572 modified: hosts/nixos/configuration.nix 2025-07-22 14:22:49 +10:00
beatzaplenty be8fefd9f8 modified: hosts/nixos/home.nix 2025-07-22 14:21:34 +10:00
beatzaplenty 79fb3799a9 modified: flake.nix
modified:   hosts/nixos/home.nix
2025-07-22 14:15:15 +10:00
beatzaplenty bb1a4d8a3e modified: flake.nix 2025-07-22 14:10:44 +10:00
beatzaplenty f5dcb13b86 modified: flake.nix 2025-07-22 14:09:08 +10:00
beatzaplenty 41a6800c58 modified: flake.nix 2025-07-22 14:05:43 +10:00
beatzaplenty f9a6ada47b modified: hosts/nixos/home.nix 2025-07-22 14:02:14 +10:00
beatzaplenty 941aff5048 modified: flake.nix
modified:   hosts/nixos/home.nix
2025-07-22 13:59:42 +10:00
beatzaplenty ccf11fa673 modified: flake.nix 2025-07-22 13:47:56 +10:00
beatzaplenty d42336b288 modified: flake.nix 2025-07-22 13:37:24 +10:00
beatzaplenty 66453b3396 modified: flake.nix 2025-07-22 13:33:45 +10:00
beatzaplenty a4fc3d9b3b modified: flake.nix 2025-07-22 13:31:05 +10:00
beatzaplenty 66d8680b26 modified: common/home.nix
modified:   hosts/nix-minimal/configuration.nix
2025-07-21 16:16:47 +10:00
beatzaplenty ac21c48b52 deleted: auto-installer/flake.nix
deleted:    auto-installer/installer.nix
	modified:   hosts/nix-minimal/configuration.nix
	modified:   prepare.sh
2025-07-21 13:39:03 +10:00
beatzaplenty d4d1fc795b Added minimal build for iso testing and building
modified:   flake.nix
	new file:   hosts/nix-minimal/configuration.nix
2025-07-21 12:13:07 +10:00
beatzaplenty a4566a6f80 modified: auto-installer/installer.nix 2025-07-21 12:08:08 +10:00
beatzaplenty 551cf90cdd modified: auto-installer/installer.nix 2025-07-21 10:33:21 +10:00
beatzaplenty 8e896e9067 modified: auto-installer/installer.nix 2025-07-21 10:18:29 +10:00
beatzaplenty b3bc217586 modified: auto-installer/installer.nix 2025-07-21 10:11:02 +10:00
beatzaplenty 59f75cd31c modified: auto-installer/installer.nix 2025-07-21 09:58:34 +10:00
beatzaplenty cdfe2943ed modified: auto-installer/installer.nix 2025-07-21 09:54:23 +10:00
beatzaplenty c3ed7ccf46 modified: auto-installer/installer.nix 2025-07-21 09:36:26 +10:00
beatzaplenty 61bd88fd15 modified: auto-installer/installer.nix 2025-07-21 09:27:04 +10:00
beatzaplenty b7d572c40e modified: auto-installer/installer.nix 2025-07-21 09:19:07 +10:00
beatzaplenty 431f769af8 modified: auto-installer/installer.nix 2025-07-21 08:51:03 +10:00
beatzaplenty 1f8dfe54da modified: auto-installer/installer.nix 2025-07-21 08:38:46 +10:00
beatzaplenty 66ab3a3977 modified: auto-installer/installer.nix 2025-07-21 02:11:34 +10:00
beatzaplenty 264dae9a92 Merge branch 'main' of https://gitea.lan.ddnsgeek.com/beatzaplenty/nixos 2025-07-21 01:59:28 +10:00
beatzaplenty da55436abb modified: auto-installer/installer.nix 2025-07-21 01:58:06 +10:00
beatzaplenty fbd36b28ea Merge branch 'main' of https://gitea.lan.ddnsgeek.com/beatzaplenty/nixos 2025-07-21 01:48:57 +10:00
beatzaplenty a93fe3cc3c modified: .gitignore 2025-07-21 01:47:56 +10:00
beatzaplenty ad82ffcfc1 modified: auto-installer/installer.nix 2025-07-21 01:47:12 +10:00
beatzaplenty 4f4699d334 modified: auto-installer/installer.nix 2025-07-21 01:32:06 +10:00
beatzaplenty 8667552141 modified: .gitignore 2025-07-21 00:53:34 +10:00
beatzaplenty 059dd4c333 modified: auto-installer/installer.nix 2025-07-21 00:52:51 +10:00
beatzaplenty 3c3d6ccfa7 modified: auto-installer/installer.nix 2025-07-21 00:27:38 +10:00
beatzaplenty 075d1f77b7 modified: auto-installer/installer.nix 2025-07-21 00:26:47 +10:00
beatzaplenty 1241a8e9ae modified: auto-installer/installer.nix 2025-07-21 00:25:39 +10:00
beatzaplenty ddfcaa0c68 modified: auto-installer/installer.nix 2025-07-21 00:24:06 +10:00
beatzaplenty 49f0a156c3 modified: auto-installer/installer.nix 2025-07-21 00:21:09 +10:00
beatzaplenty f6a1bdb0cf modified: .gitignore 2025-07-21 00:14:59 +10:00
beatzaplenty d5d83c78e1 modified: .gitignore 2025-07-21 00:13:55 +10:00
beatzaplenty f385a420db new file: auto-installer/flake.nix
new file:   auto-installer/installer.nix
2025-07-21 00:10:48 +10:00
beatzaplenty b3eed0d061 modified: hosts/nixos/configuration.nix 2025-07-20 22:54:08 +10:00
beatzaplenty 7cb3429139 modified: hosts/nixos/configuration.nix 2025-07-20 22:53:23 +10:00
beatzaplenty b3c2033fb2 modified: flake.nix 2025-07-20 22:52:44 +10:00
beatzaplenty ad4f69c05e modified: flake.nix 2025-07-20 22:45:37 +10:00
beatzaplenty bc29cfc5ef modified: flake.nix 2025-07-20 22:44:31 +10:00
beatzaplenty d9f520c959 added winapps flake to nixos pc
modified:   flake.nix
2025-07-20 22:40:14 +10:00
beatzaplenty 7d155d6413 modified: hosts/nixos/configuration.nix 2025-07-20 22:27:41 +10:00
beatzaplenty 1a742a35c6 modified: hosts/nixos/configuration.nix 2025-07-20 22:25:46 +10:00
beatzaplenty 5ef1bef1c0 added software
modified:   hosts/nixos/configuration.nix
2025-07-20 22:24:44 +10:00
beatzaplenty 7f5d03c06c modified: hosts/nixos/configuration.nix 2025-07-20 22:11:59 +10:00
beatzaplenty 0e650af351 modified: hosts/nixos/configuration.nix 2025-07-20 22:07:25 +10:00
beatzaplenty b4cdf89e71 modified: hosts/nixos/configuration.nix 2025-07-20 21:59:56 +10:00
beatzaplenty 9a65f15b58 modified: hosts/nixos/configuration.nix 2025-07-20 21:55:22 +10:00
beatzaplenty 1da2471a4a modified: hosts/nixos/configuration.nix 2025-07-20 21:50:57 +10:00
beatzaplenty e171715448 modified: hosts/nixos/configuration.nix 2025-07-20 21:50:10 +10:00
beatzaplenty 3c8c57d2f9 modified: hosts/nixos/configuration.nix 2025-07-20 21:48:47 +10:00
beatzaplenty 175ea8c7c9 enabled keyring
modified:   hosts/nixos/configuration.nix
2025-07-20 21:47:47 +10:00
beatzaplenty 54dbee8543 move vscode to config from home manager
modified:   hosts/nixos/configuration.nix
	modified:   hosts/nixos/home.nix
2025-07-20 21:40:22 +10:00
beatzaplenty 29a5c6c4e8 enable allow unfree software
modified:   hosts/nixos/configuration.nix
2025-07-20 21:27:27 +10:00
beatzaplenty 9b9ec47150 added vscode
modified:   hosts/nixos/home.nix
2025-07-20 21:25:36 +10:00
beatzaplenty 8e08a5adef moved aliases to common file and imported to all home.nix variants
new file:   common/aliases.nix
	modified:   common/home.nix
	modified:   hosts/nixos/home.nix
2025-07-20 21:15:31 +10:00
beatzaplenty 3eff3b000b modified: common/home.nix 2025-07-16 21:11:07 +10:00
beatzaplenty ac40a14d79 modified: hosts/nix-cache/configuration.nix 2025-07-16 20:34:45 +10:00
beatzaplenty f81abfb31d modified: common/configuration.nix 2025-07-16 20:31:41 +10:00
beatzaplenty 28db091ea0 modified: common/configuration.nix
modified:   hosts/nix-cache/configuration.nix
2025-07-16 20:24:23 +10:00
beatzaplenty 8e9ba91536 modified: common/home.nix 2025-07-16 20:06:55 +10:00
beatzaplenty fee0f1ef14 modified: flake.nix 2025-07-16 20:03:18 +10:00
beatzaplenty b80550d91b modified: flake.nix 2025-07-16 19:57:42 +10:00
59 changed files with 550 additions and 1412 deletions

No files matched your search

+3 -3
View File
@@ -6,9 +6,9 @@ result-*
# Ignore automatically generated direnv output # Ignore automatically generated direnv output
.direnv .direnv
# Locally-generated SSH host keys staged for transfer to a new machine auto-installer/flake.lock
# during install (see scripts/prepare-host-key.sh) — never commit these. auto-installer/result
host-keys/ auto-installer/nixos-auto.iso
# Temporary Milestone 1 audit checklist (remove-sensetive-info-refactor.md) # Temporary Milestone 1 audit checklist (remove-sensetive-info-refactor.md)
# - working notes only, never committed, deleted once every row is rotated. # - working notes only, never committed, deleted once every row is rotated.
-7
View File
@@ -3,9 +3,6 @@ keys:
- &docker age19gfn2yedg76dmztm4hncr7vf3r3c9j0qpt4rap7y7gersjk4m3ks2lhd0e - &docker age19gfn2yedg76dmztm4hncr7vf3r3c9j0qpt4rap7y7gersjk4m3ks2lhd0e
- &server age1ll6hj5ggruetgjwjfnplpn5xtq35uhlcdflksx3xmnjm6s3uad9sz70jkf - &server age1ll6hj5ggruetgjwjfnplpn5xtq35uhlcdflksx3xmnjm6s3uad9sz70jkf
- &nix-cache age120le4a5l8dh3lyfgvmj3d9ksmej6ajs5mer5y7r0vfg3x9fn69dqf8xgzu - &nix-cache age120le4a5l8dh3lyfgvmj3d9ksmej6ajs5mer5y7r0vfg3x9fn69dqf8xgzu
- &lxc-minimal age1qz9d4ka4xgexujyd247s7lp737sulp5fhxl5d65fj2ykvc4j4edqrsdks8
- &nix-minimal age120whqj96g26lsgy4udvgsn8dc9lumh8jeu3a564fx79rjr5lxffqmrljuu
- &lxc-nix-cache age164px2a8e48ptsf9ngtan38aa6jls4jdl26mzrgzf6sn3vcvt49hqjrgr8w
creation_rules: creation_rules:
# Shared across every currently-deployed host: root/nixos password hash, # Shared across every currently-deployed host: root/nixos password hash,
@@ -19,16 +16,12 @@ creation_rules:
- *docker - *docker
- *server - *server
- *nix-cache - *nix-cache
- *lxc-minimal
- *nix-minimal
- *lxc-nix-cache
- path_regex: secrets/nix-cache\.yaml$ - path_regex: secrets/nix-cache\.yaml$
key_groups: key_groups:
- age: - age:
- *admin - *admin
- *nix-cache - *nix-cache
- *lxc-nix-cache
- path_regex: secrets/server\.yaml$ - path_regex: secrets/server\.yaml$
key_groups: key_groups:
+32 -52
View File
@@ -52,76 +52,56 @@ There is no test suite — "correctness" here means the flake evaluates and
## Architecture ## Architecture
`flake.nix` is the single entry point. It generates one `flake.nix` is the single entry point. It defines one `nixosConfigurations.<host>`
`nixosConfigurations.<platform>-<buildtype>` attribute per target via the attribute per machine, each built the same way:
`mkTarget` function, composed from:
``` ```
nixosSystem { nixosSystem {
modules = [ modules = [
disko.nixosModules.disko disko.nixosModules.disko
sops-nix.nixosModules.sops ./hosts/<host>/configuration.nix # host-specific config
./modules/common/configuration.nix ./modules/hardware-configuration/vm/<proxmox|linode>.nix
./modules/platforms/${platform}.nix # what it runs on
./modules/build-types/${buildType}.nix # what it's for
hostPath # hosts/<name>/host.nix — per-machine identity
home-manager.nixosModules.home-manager { ... } home-manager.nixosModules.home-manager { ... }
] ++ (client-only modules, for every buildType except "nix-cache" itself) ];
} }
``` ```
Platforms: `linode`, `proxmox`, `lxc`. Build types: `minimal`, `nix-cache`, Hosts currently defined in `flake.nix`: `nixos`, `docker`, `server`,
`server`, `docker`, `gui`, `pxe-boot`. Not every combination is built — e.g. `nix-cache`, `nix-minimal`, `pxe-boot`, `linode-minimal`. Treat `flake.nix` as
`pxe-boot` has no `linode` variant (PXE/DHCP/TFTP need LAN L2 adjacency a the source of truth for which hosts exist — `README.md`, `AGENTS.md`,
Linode VPS doesn't have). Treat `flake.nix`'s `generatedTargets` as the source
of truth for which hosts exist — `README.md`, `AGENTS.md`,
`docs/flake-lock-automation.md`, and the CI eval workflows `docs/flake-lock-automation.md`, and the CI eval workflows
(`.github/workflows/check-nixos.yml`, `.gitea/workflows/check-nixos.yml`) list (`.github/workflows/check-nixos.yml`, `.gitea/workflows/check-nixos.yml`) list
hosts by hand (or, for the CI workflows, evaluate the flake dynamically) and hosts by hand and can drift from it, so re-check them against `flake.nix` when
can drift from it, so re-check them against `flake.nix` when adding or adding or removing a host.
removing a host.
### Composition pattern ### Composition pattern
- `hosts/<name>/host.nix` — per-machine identity **only**: hostname, hostId, Every host's real configuration lives in `hosts/<host>/configuration.nix`,
per-machine secrets, `system.stateVersion`. These files carry no `imports` which is a thin list of `imports` pulling in reusable pieces from `modules/`:
of their own beyond narrow parameterized helpers (see
`modules/beszel/host-token.nix` below) — all shared behavior comes from the - `modules/common/configuration.nix` — base NixOS config imported by (almost)
platform/build-type modules composed in `flake.nix`, not from the host file. every host: locale, users, nix settings, git. Nearly always the first import.
- `modules/platforms/{linode,proxmox,lxc}.nix` — platform-specific config: - `modules/common/home.nix` / `hosts/<host>/home.nix` — Home Manager config for
boot method, guest tooling, and (for linode/proxmox) the hypervisor-specific the `nixos` user; the `nixos` workstation has its own, other hosts share
hardware config, imported directly by the platform module itself `modules/common/home.nix`.
(`../hardware-configuration/vm/{proxmox,linode}.nix`) — **not** wired in
from `flake.nix`. `lxc.nix` has no hardware-configuration counterpart since
containers share the host kernel.
- `modules/build-types/*.nix` — what a system is for:
minimal/server/docker/gui/pxe-boot/nix-cache.
- `modules/common/configuration.nix` — base NixOS config imported by every
host: locale, users, nix settings, git.
- `modules/common/home.nix` / `hosts/nixos/home.nix` — Home Manager config for
the `nixos` user; the `nixos` workstation (`gui` build type) has its own,
other hosts share `modules/common/home.nix`.
- `modules/disko/proxmox.nix` — declarative disk layout (GPT: ESP + swap + - `modules/disko/proxmox.nix` — declarative disk layout (GPT: ESP + swap +
ext4 root) via disko, used by all Proxmox-VM hosts. ext4 root) via disko, used by all Proxmox-VM hosts.
- `modules/boot/efi.nix` — systemd-boot + EFI vars, paired with the disko module. - `modules/boot/efi.nix` — systemd-boot + EFI vars, paired with the disko module.
- `modules/nix-cache/{client,server,remote-builder-client}.nix` — binary cache - `modules/hardware-configuration/vm/{proxmox,linode}.nix` — hypervisor-specific
substituter + SSH remote-builder wiring; see `docs/nix-cache.md` for the hardware config, wired in from `flake.nix` (not from the host file).
full design (per-host local stores, no shared `/nix/store`, and how the - `modules/nix-cache/{client,server}.nix` + `modules/remote-builder-client.nix` —
`nixremote` signing/SSH keys fit together). binary cache substituter + SSH remote-builder wiring; see `docs/nix-cache.md`
- `modules/beszel/host-token.nix` — parameterized helper module for the full design (per-host local stores, no shared `/nix/store`, and how
(`{ name, sopsFile }`) that wires a host's beszel-agent sops secret/template the `nixremote` signing/SSH keys fit together).
and `environmentFile`; used by `hosts/server/host.nix` and - `modules/tailscale/`, `modules/docker/`, `modules/beszel/`,
`hosts/nix-cache/host.nix` to avoid duplicating that boilerplate. `modules/services/*` — single-purpose, single-host feature modules (e.g.
- `modules/tailscale/`, `modules/docker/`, `modules/networking/`, `docker/enable-service.nix`, `services/zfs/enable-service.nix`,
`modules/traefik/`, `modules/services/*` — single-purpose, single-host `beszel/enable-agent.nix` for monitoring). Grep `hosts/*/configuration.nix`
feature modules (e.g. `docker/enable-service.nix`, for the `imports` list to see which modules apply to a given host.
`services/zfs/enable-service.nix`). Grep `modules/build-types/*.nix` for
each build type's `imports` list to see which modules apply where.
New host = new `hosts/<name>/host.nix` + a matching New host = new `hosts/<name>/configuration.nix` + a matching block added to
`mkTarget { platform; buildType; hostPath; }` entry added to `flake.nix`'s `flake.nix`'s `nixosConfigurations`, composed from existing `modules/*` pieces
`generatedTargets`, composed from existing `modules/*` pieces rather than rather than duplicating config.
duplicating config.
### Other docs worth reading before touching these areas ### Other docs worth reading before touching these areas
+2 -5
View File
@@ -46,17 +46,14 @@ nix eval --json .#nixosConfigurations --apply builtins.attrNames | jq -r '.[]'
| Path | Purpose | | Path | Purpose |
| --- | --- | | --- | --- |
| `flake.nix` | Flake inputs, the `mkTarget` platform × build-type generator, and `nixosConfigurations` outputs | | `flake.nix` | Flake inputs, the `mkTarget` platform × build-type generator, and `nixosConfigurations` outputs |
| `variables.nix` | Single source of truth for shared values (LAN domain/CIDR, hostnames, timezone, primary username, storage root, ...) — passed to every module and Home Manager config as the `vars` argument via `specialArgs`/`extraSpecialArgs` |
| `hosts/<name>/host.nix` | Per-machine identity: hostname, hostId, per-machine secrets, `system.stateVersion` | | `hosts/<name>/host.nix` | Per-machine identity: hostname, hostId, per-machine secrets, `system.stateVersion` |
| `hosts/nixos/home.nix` | Workstation-specific Home Manager config (used by the `gui` build type) | | `hosts/nixos/home.nix` | Workstation-specific Home Manager config (used by the `gui` build type) |
| `modules/platforms/` | Platform-specific config: virtualisation guest tools, boot method, hardware config (`linode.nix`, `proxmox.nix`, `lxc.nix`) | | `modules/platforms/` | Platform-specific config: virtualisation guest tools, boot method, hardware config (`linode.nix`, `proxmox.nix`, `lxc.nix`) |
| `modules/build-types/` | Build-type-specific config: what makes a system minimal/server/docker/gui/pxe-boot/nix-cache | | `modules/build-types/` | Build-type-specific config: what makes a system minimal/server/docker/gui/pxe-boot/nix-cache |
| `modules/common/` | Shared NixOS config, Home Manager, aliases imported by every host | | `modules/common/` | Shared NixOS config, Home Manager, aliases imported by every host |
| `modules/nix-cache/` | Binary cache and remote builder client/server modules | | `modules/nix-cache/` | Binary cache and remote builder client/server modules |
| `modules/installer/` | Auto-installer environment (ISO/netboot/Proxmox LXC) — see `docs/auto-installer.md` | | `docs/` | Operational notes for cache, builders, lock updates, and boot services |
| `host-keys/` | Gitignored, locally-generated SSH host keys for the auto-installer — see `docs/auto-installer.md` | | `scripts/` | Codex setup and validation helpers |
| `docs/` | Operational notes for cache, builders, lock updates, boot services, and the auto-installer |
| `scripts/` | Codex setup, validation, and host-key-prep helpers |
## Validation ## Validation
-199
View File
@@ -1,199 +0,0 @@
# Auto-installer
This flake builds a self-contained NixOS installer environment that can
install any host exposed by its own `nixosConfigurations`. It was migrated
from a formerly-separate `nix-auto-installer` repo — everything it did now
lives here.
The installer provides a small NixOS install environment (ISO/netboot/Proxmox
LXC) with SSH access, Git support, and an interactive installation script.
Logging in as any user (root or `nixos`) runs `/etc/auto-install.sh`,
discovers available hosts from this same flake, lets the operator choose a
target, applies that host's Disko storage configuration, installs NixOS, and
reboots.
**This applies to every `nixosConfigurations` target except `lxc-*` hosts —
see "LXC hosts" immediately below for why those are different.**
## LXC hosts
`lxc-*` targets (`lxc-minimal`, `lxc-nix-cache`, `lxc-server`, `lxc-docker`,
`lxc-gui`, `lxc-pxe-boot`) are **not** installed via `auto-install.sh` — the
interactive menu deliberately excludes them. Don't try to select one there;
`nixos-install` would bind-mount `/` onto `/mnt` (LXC containers have no raw
disk to partition) and then refuse to touch the filesystem it's currently
running on — it's designed to protect exactly this case, so it just fails.
`modules/platforms/lxc.nix` imports nixpkgs' own
`virtualisation/proxmox-lxc.nix` module, which gives every `lxc-*` host a
`config.system.build.tarball` output — a complete, directly Proxmox-importable
container image, no install step at all:
```sh
nix build .#nixosConfigurations.lxc-minimal.config.system.build.tarball
```
Then, on the Proxmox host, `pct restore` (or the GUI's "Create CT" → upload
template flow) that tarball directly as a new container. First boot runs
`boot.postBootCommands` (registers the Nix store DB and system profile) —
there's no separate activation step to run yourself.
Host keys still need pre-seeding the same way as any other host (see "Host
keys" below) — the sops-nix activation-vs-first-boot race is identical
regardless of how the image reaches the machine. `NIXOS_HOST_KEYS_DIR=...
nix build ... --impure` bakes the matching key into the tarball the same way
it does for the ISO/PXE installer images.
## Layout
- `modules/installer/common.nix` — shared by every installer target: SSH
access, users, the generated `/etc/auto-install.sh` script, and the
`programs.bash.loginShellInit` hook that runs it on login.
- `modules/installer/iso.nix` — ISO/netboot-specific: imports the stock
`installation-cd-minimal.nix` module plus `common.nix`. Also used, paired
with `netboot-minimal.nix`, to build the PXE netboot variant (see
`docs/pxe-boot.md`).
- `modules/installer/proxmox-lxc.nix` — Proxmox LXC-specific: disables
bootloader options (containers don't need one) plus `common.nix`.
- `modules/installer/host-keys.nix` — optionally bakes pre-generated SSH
host keys into the image; see "Host keys" below.
- `scripts/prepare-host-key.sh` — admin-workstation pre-flight tool, see
"Creating a New Machine" below.
Flake outputs:
```nix
nixosConfigurations.installer # ISO/netboot installer image
nixosConfigurations.proxmox-lxc # Proxmox LXC-based installer image
packages.x86_64-linux.iso # installer ISO/netboot image
packages.x86_64-linux.lxc # Proxmox LXC installer tarball
packages.x86_64-linux.pxe # netboot-ipxe + netboot-initrd + netboot-kernel, bundled
packages.x86_64-linux.all # all three of the above, bundled
```
```sh
nix build .#iso
nix build .#lxc
nix build .#pxe
nix build .#all
```
The `pxe` variant is also built automatically as part of the `pxe-boot` host
itself (`modules/pxe-boot/stage-installer-artifacts.nix`) and served over
iPXE — see `docs/pxe-boot.md`.
## Host keys
`sops-nix` derives each host's decryption key from its own
`/etc/ssh/ssh_host_ed25519_key`, generated at **activation** time — before
systemd would otherwise generate one on first boot. Without pre-seeding this
key, secrets (including the root/nixos login password) fail to decrypt on a
genuinely fresh install.
Generated host keys live in `host-keys/` at the repo root (`ssh_host_ed25519_key`
+ `.pub` pairs per hostname). This directory is **gitignored on purpose** —
private key material must never be committed — which also means flakes can't
see it through a normal relative path. `modules/installer/host-keys.nix`
reads it through `builtins.getEnv`, which Nix silently returns as an empty
string under normal (non-`--impure`) evaluation, so the module is a no-op —
safe by default, including in CI — unless explicitly opted into:
```sh
NIXOS_HOST_KEYS_DIR="$(pwd)/host-keys" nix build .#iso --impure
```
When built this way, every key currently in `host-keys/` is baked into the
image at `/etc/host-keys/<hostname>_ssh_host_ed25519_key(.pub)`, and
`auto-install.sh` automatically installs whichever one matches the flake
target selected at install time — no manual per-host scp step needed.
**Trade-off, accepted deliberately for this LAN-only setup:** baking keys in
means every key present in `host-keys/` at build time becomes readable by
anyone who can reach the built image — including, for the PXE variant, anyone
who can reach the `pxe-boot` host's unauthenticated HTTP server. This is
considered acceptable here because `pxe-boot` sits behind LAN-only network
infrastructure, not the open internet. If that ever changes, reconsider this
default.
`auto-install.sh` still supports the older manual path as a fallback: if a
host's key isn't baked in (`/etc/host-keys`), it checks `/root/host-keys`
next, where you can `scp` a key in after boot, same as before this migration.
## Storage
Disk partitioning is handled by Disko — the installer has no hardcoded
`parted`/`mkfs`/`mkswap`/`mount` commands. Each host defines its own layout
via `disko.devices`; a host without one is installed in place via bind-mount
(this is how every LXC container target works, since they have no raw block
device to partition).
## Installer process
`/etc/auto-install.sh`:
1. Queries `nixosConfigurations` from this flake over the network (`git+https://<lanDomain>/beatzaplenty/nixos.git`) — this happens at *install* time, not build time, so a generic installer image always sees whatever hosts are currently committed, without needing a rebuild.
2. Presents them as a menu; confirms the choice.
3. Skips the `nix-cache` substituter when installing a `nix-cache` host itself (consistent with that host's own runtime config).
4. Runs `disko --mode destroy,format,mount` if the target has a Disko config, otherwise bind-mounts `/` onto `/mnt`.
5. Installs the target's SSH host key from `/etc/host-keys` or `/root/host-keys` (see "Host keys" above).
6. Runs `nixos-install --flake <url>#<choice> --no-root-password`.
7. Cleans up and reboots.
## Creating a new machine
Do this instead of jumping straight to a plain install whenever the target
host consumes any sops-nix secret — as of this writing, that's every host
(`modules/common/configuration.nix` puts the root/nixos password hash and the
GitHub token behind sops-nix for all of them).
1. **On your admin workstation**, decide the new machine's flake target name
(`<platform>-<buildtype>`, e.g. `proxmox-server`) and generate + register
its host key:
```sh
./scripts/prepare-host-key.sh <hostname>
```
This generates `host-keys/<hostname>_ssh_host_ed25519_key(.pub)` and
prints the `.sops.yaml` snippet to add, which secrets files to
re-encrypt it into, and the next steps below.
2. **Edit `.sops.yaml`** with the printed snippet, then re-encrypt every
secrets file you added the new host to:
```sh
nix-shell -p sops --run 'sops updatekeys secrets/common.yaml'
```
3. **Commit and push.** The flake build the installer uses has to see the
new recipient before you install, or decryption fails on first boot
regardless of the next step.
4. **Build the installer image with keys baked in** (or reuse an already-serving `pxe-boot` host, which does this automatically once redeployed):
```sh
NIXOS_HOST_KEYS_DIR="$(pwd)/host-keys" nix build .#iso --impure
```
5. **Boot it on the target machine**, log in, select the new host's flake
target from the menu, confirm. `auto-install.sh` finds the baked-in key,
runs Disko + `nixos-install`, and reboots.
6. **Verify after reboot:**
```sh
ssh <new-host> ls /run/secrets/
```
If that's empty or login fails, the host's age key most likely wasn't in
`.sops.yaml` (or wasn't re-encrypted into the secrets file it needs) when
`nixos-install` ran — fix `.sops.yaml`/`secrets/*.yaml`, push, then re-run
`nixos-install --flake .#<hostname> --no-root-password` from a rescue
environment against the existing `/mnt`, or just redo the install.
## Safety
This installer is destructive: `disko --mode destroy,format,mount` erases
any disk defined by the selected host's Disko configuration. Always verify
the selected host profile and target machine before confirming.
+2 -2
View File
@@ -8,8 +8,8 @@ This repository configures `nix-cache` as a **binary cache server** and a **remo
- Every machine still keeps and uses its own local `/nix/store`. - Every machine still keeps and uses its own local `/nix/store`.
- Clients prefer `http://nix-cache` for substitutes and keep `https://cache.nixos.org/` as fallback. - Clients prefer `http://nix-cache` for substitutes and keep `https://cache.nixos.org/` as fallback.
- Clients can offload builds to `nix-cache` through SSH (`nix.distributedBuilds`). - Clients can offload builds to `nix-cache` through SSH (`nix.distributedBuilds`).
- Client hosts import `modules/nix-cache/client.nix` and, when remote building is enabled, `modules/nix-cache/remote-builder-client.nix`. - Client hosts import `modules/nix/cache-client.nix` and, when remote building is enabled, `modules/nix/remote-builder-client.nix`.
- The `nix-cache` host imports `modules/nix-cache/server.nix`. - The `nix-cache` host imports `modules/nix/cache-server.nix`.
## Binary cache signing keys (on nix-cache) ## Binary cache signing keys (on nix-cache)
+2 -9
View File
@@ -52,15 +52,8 @@ The generated menu currently exposes entries for:
- iPXE shell - iPXE shell
- Reboot - Reboot
The NixOS installer entry chain-loads `/srv/pxe/http/nixos/netboot.ipxe`, Kernel and initrd artifacts for the NixOS installer entry must be placed under
which is nixpkgs' own generated netboot iPXE script (correct `init=`/`initrd=` `/srv/pxe/http/nixos` by an operator or a separate build process.
kernel parameters included) rather than a hand-rolled boot line — that script
in turn expects its kernel/initrd siblings in the same directory. All three
files (`bzImage`, `initrd`, `netboot.ipxe`) are built from this flake's own
`modules/installer/iso.nix` netboot image (the same one `nix build .#pxe`
produces) and staged automatically by
`modules/pxe-boot/stage-installer-artifacts.nix` via `systemd.tmpfiles.rules`
— no manual operator step required.
The SystemRescue entry expects the source ISO at: The SystemRescue entry expects the source ISO at:
+6 -65
View File
@@ -23,8 +23,6 @@
let let
system = "x86_64-linux"; system = "x86_64-linux";
inherit (nixpkgs) lib; inherit (nixpkgs) lib;
pkgs = nixpkgs.legacyPackages.${system};
vars = import ./variables.nix;
# Generates a nixosConfiguration from a platform (what it runs on) and # Generates a nixosConfiguration from a platform (what it runs on) and
# a build type (what it's for), plus the per-identity host.nix that # a build type (what it's for), plus the per-identity host.nix that
@@ -48,24 +46,23 @@
home-manager = { home-manager = {
useGlobalPkgs = true; useGlobalPkgs = true;
useUserPackages = true; useUserPackages = true;
extraSpecialArgs = { inherit vars; };
users.nixos = import homeFile; users.nixos = import homeFile;
}; };
} }
] ++ lib.optionals (buildType != "nix-cache") [ ] ++ lib.optionals (buildType != "nix-cache") [
./modules/nix-cache/client.nix ./modules/nix-cache/client.nix
./modules/nix-cache/remote-builder-client.nix ./modules/remote-builder-client.nix
]; ];
specialArgs = { inherit inputs vars netbootSystem; }; specialArgs = { inherit inputs; };
}; };
# Generated platform x build-type matrix. pxe-boot has no linode # Generated platform x build-type matrix. pxe-boot has no linode
# variant (PXE/DHCP/TFTP need LAN L2 adjacency, which a Linode VPS # variant (PXE/DHCP/TFTP need LAN L2 adjacency, which a Linode VPS
# doesn't have). # doesn't have).
generatedTargets = { generatedTargets = {
linode-minimal = mkTarget { platform = "linode"; buildType = "minimal"; hostPath = ./hosts/nix-minimal/host.nix; }; linode-minimal = mkTarget { platform = "linode"; buildType = "minimal"; hostPath = ./hosts/linode-minimal/host.nix; };
proxmox-minimal = mkTarget { platform = "proxmox"; buildType = "minimal"; hostPath = ./hosts/nix-minimal/host.nix; }; proxmox-minimal = mkTarget { platform = "proxmox"; buildType = "minimal"; hostPath = ./hosts/proxmox-minimal/host.nix; };
lxc-minimal = mkTarget { platform = "lxc"; buildType = "minimal"; hostPath = ./hosts/nix-minimal/host.nix; }; lxc-minimal = mkTarget { platform = "lxc"; buildType = "minimal"; hostPath = ./hosts/lxc-minimal/host.nix; };
linode-nix-cache = mkTarget { platform = "linode"; buildType = "nix-cache"; hostPath = ./hosts/nix-cache/host.nix; }; linode-nix-cache = mkTarget { platform = "linode"; buildType = "nix-cache"; hostPath = ./hosts/nix-cache/host.nix; };
proxmox-nix-cache = mkTarget { platform = "proxmox"; buildType = "nix-cache"; hostPath = ./hosts/nix-cache/host.nix; }; proxmox-nix-cache = mkTarget { platform = "proxmox"; buildType = "nix-cache"; hostPath = ./hosts/nix-cache/host.nix; };
@@ -87,65 +84,9 @@
lxc-pxe-boot = mkTarget { platform = "lxc"; buildType = "pxe-boot"; hostPath = ./hosts/pxe-boot/host.nix; }; lxc-pxe-boot = mkTarget { platform = "lxc"; buildType = "pxe-boot"; hostPath = ./hosts/pxe-boot/host.nix; };
}; };
# Auto-install environments (migrated from the former nix-auto-installer
# flake): a self-contained NixOS installer that boots, discovers this
# flake's own nixosConfigurations over the network, and runs
# nixos-install against whichever one the operator picks. These are
# deliberately not part of the platform x build-type matrix above —
# they're throwaway boot media, not persistent hosts, so they skip
# disko/sops-nix/home-manager and just need `vars`.
installerTargets = {
installer = nixpkgs.lib.nixosSystem {
inherit system;
modules = [ ./modules/installer/iso.nix ];
specialArgs = { inherit vars; };
};
proxmox-lxc = nixpkgs.lib.nixosSystem {
inherit system;
modules = [ ./modules/installer/proxmox-lxc.nix ];
specialArgs = { inherit vars; };
};
};
# Same installer environment, built as netboot (kernel + initrd +
# iPXE script) instead of an ISO — this is what packages.pxe bundles.
netbootSystem = nixpkgs.lib.nixosSystem {
inherit system;
modules = [
./modules/installer/iso.nix
({ modulesPath, ... }: {
imports = [
(modulesPath + "/installer/netboot/netboot-minimal.nix")
];
})
];
specialArgs = { inherit vars; };
};
in in
{ {
nixosConfigurations = generatedTargets // installerTargets; nixosConfigurations = generatedTargets;
# Buildable auto-installer artifacts (`nix build .#<name>`), migrated
# unchanged from nix-auto-installer's interface.
packages.${system} = rec {
iso = installerTargets.installer.config.system.build.isoImage;
lxc = installerTargets.proxmox-lxc.config.system.build.tarball;
pxe = pkgs.linkFarm "pxe" [
{ name = "netboot.ipxe"; path = netbootSystem.config.system.build.netbootIpxeScript; }
{ name = "initrd"; path = netbootSystem.config.system.build.netbootRamdisk; }
{ name = "kernel"; path = netbootSystem.config.system.build.kernel; }
];
all = pkgs.linkFarm "all" [
{ name = "iso"; path = iso; }
{ name = "lxc"; path = lxc; }
{ name = "pxe"; path = pxe; }
];
};
}; };
} }
+1 -1
View File
@@ -1,4 +1,4 @@
_: { ... }:
{ {
networking.hostName = "docker"; networking.hostName = "docker";
+9
View File
@@ -0,0 +1,9 @@
{ ... }:
{
networking.hostName = "linode-minimal";
# Preserved from the pre-refactor `linode-minimal` target — stateVersion
# must never be bumped on an already-installed machine.
system.stateVersion = "26.05";
}
+9
View File
@@ -0,0 +1,9 @@
{ ... }:
{
networking.hostName = "lxc-minimal";
# No pre-existing deployed machine to preserve — pin explicitly to the
# current release rather than let it silently default.
system.stateVersion = "26.05";
}
+8 -8
View File
@@ -1,19 +1,19 @@
{ vars, ... }: { config, ... }:
{ {
imports = [ networking.hostName = "nix-cache";
(import ../../modules/beszel/host-token.nix {
name = "nix-cache";
sopsFile = ../../secrets/nix-cache.yaml;
})
];
networking.hostName = vars.nixCacheHost; sops.secrets."beszel-token".sopsFile = ../../secrets/nix-cache.yaml;
sops.templates."nix-cache-beszel.env".content = ''
TOKEN=${config.sops.placeholder."beszel-token"}
'';
services.beszel.agent.environment = { services.beszel.agent.environment = {
#DOCKER_HOST = "tcp://docker-socket-proxy:2375"; #DOCKER_HOST = "tcp://docker-socket-proxy:2375";
#HUB_URL = "http://docker.sweet.home:8090";
KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFPR9kwtC4TAeTRu46A7+opZsYpxqkRJ+x/ZyB2GWCeG"; KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFPR9kwtC4TAeTRu46A7+opZsYpxqkRJ+x/ZyB2GWCeG";
}; };
services.beszel.agent.environmentFile = config.sops.templates."nix-cache-beszel.env".path;
# Preserved from the pre-refactor `nix-cache` target — stateVersion must # Preserved from the pre-refactor `nix-cache` target — stateVersion must
# never be bumped on an already-installed machine. # never be bumped on an already-installed machine.
+61 -64
View File
@@ -1,82 +1,79 @@
{ config, pkgs, lib, vars, ... }: { config, pkgs, lib, ... }:
{ {
imports = [ imports = [
../../modules/common/aliases.nix ../../modules/common/aliases.nix
]; ];
home = { home.username = "nixos"; # your actual username
username = vars.primaryUser; home.homeDirectory = "/home/nixos";
homeDirectory = "/home/${vars.primaryUser}"; home.stateVersion = "25.05"; # match your NixOS stateVersion
stateVersion = "25.05"; # match your NixOS stateVersion
# Optional: packages programs.home-manager.enable = true; # mandatory to activate HM
packages = with pkgs; [
git
vim
tmux
nextcloud-client
# vscode
chromium
];
# Optional: set environment vars # Optional: packages
sessionVariables = { home.packages = with pkgs; [
EDITOR = "vim"; git
}; vim
tmux
nextcloud-client
# vscode
chromium
];
file = { # Optional: set environment vars
".local/share/applications/proxmox-chromium-app.desktop".text = '' home.sessionVariables = {
[Desktop Entry] EDITOR = "vim";
Type=Application
Name=Proxmox (Chromium)
Exec=chromium --app=https://pve.${vars.homeDomain}:${toString vars.pveWebPort} --window-size=1920,1080 --window-position=0,0
Icon=${config.home.homeDirectory}/.local/share/icons/proxmox.png
Terminal=false
Categories=Hypervisor;
StartupWMClass=PVE
'';
".local/share/applications/pbs-chromium-app.desktop".text = ''
[Desktop Entry]
Type=Application
Name=Proxmox Backup Server (Chromium)
Exec=chromium --app=https://${vars.pbsIp}:${toString vars.pbsWebPort} --window-size=1920,1080 --window-position=0,0
Icon=${config.home.homeDirectory}/.local/share/icons/proxmox.png
Terminal=false
Categories=backup;
'';
".local/share/applications/proxmox-firefox-app.desktop".text = ''
[Desktop Entry]
Type=Application
Name=Proxmox (Firefox)
Exec=firefox --new-instance https://pve.${vars.homeDomain}:${toString vars.pveWebPort} --profile ProxmoxWebApp --window-size=1920,1080 --class ProxmoxWebApp
Icon=${config.home.homeDirectory}/.local/share/icons/proxmox.png
Terminal=false
Categories=Hypervisor;
StartupWMClass=PVE
'';
".local/share/applications/pbs-firefox-app.desktop".text = ''
[Desktop Entry]
Type=Application
Name=Proxmox Backup Server (Firefox)
Exec=firefox --new-window https://${vars.pbsIp}:${toString vars.pbsWebPort} --profile PbsWebApp --window-size=1920,1080 --class PbsWebApp
Icon=${config.home.homeDirectory}/.local/share/icons/proxmox.png
Terminal=false
Categories=backup;
StartupWMClass=PBS
'';
};
}; };
programs.home-manager.enable = true; # mandatory to activate HM
# Optional: enable bash (or zsh, fish...) # Optional: enable bash (or zsh, fish...)
programs.bash.enable = true; programs.bash.enable = true;
services.nextcloud-client = { services.nextcloud-client = {
enable = true; enable = true;
# Optionally start in background directly # Optionally start in background directly
startInBackground = true; startInBackground = true;
}; };
home.file = {
".local/share/applications/proxmox-chromium-app.desktop".text = ''
[Desktop Entry]
Type=Application
Name=Proxmox (Chromium)
Exec=chromium --app=https://pve.sweet.home:8006 --window-size=1920,1080 --window-position=0,0
Icon=/home/nixos/.local/share/icons/proxmox.png
Terminal=false
Categories=Hypervisor;
StartupWMClass=PVE
'';
".local/share/applications/pbs-chromium-app.desktop".text = ''
[Desktop Entry]
Type=Application
Name=Proxmox Backup Server (Chromium)
Exec=chromium --app=https://192.168.2.108:8007 --window-size=1920,1080 --window-position=0,0
Icon=/home/nixos/.local/share/icons/proxmox.png
Terminal=false
Categories=backup;
'';
".local/share/applications/proxmox-firefox-app.desktop".text = ''
[Desktop Entry]
Type=Application
Name=Proxmox (Firefox)
Exec=firefox --new-instance https://pve.sweet.home:8006 --profile ProxmoxWebApp --window-size=1920,1080 --class ProxmoxWebApp
Icon=/home/nixos/.local/share/icons/proxmox.png
Terminal=false
Categories=Hypervisor;
StartupWMClass=PVE
'';
".local/share/applications/pbs-firefox-app.desktop".text = ''
[Desktop Entry]
Type=Application
Name=Proxmox Backup Server (Firefox)
Exec=firefox --new-window https://192.168.2.108:8007 --profile PbsWebApp --window-size=1920,1080 --class PbsWebApp
Icon=/home/nixos/.local/share/icons/proxmox.png
Terminal=false
Categories=backup;
StartupWMClass=PBS
'';
};
} }
+1 -1
View File
@@ -1,4 +1,4 @@
_: { ... }:
{ {
networking.hostName = "nixos"; networking.hostName = "nixos";
@@ -1,4 +1,4 @@
_: { ... }:
{ {
# Preserves the hostname of the existing, already-deployed machine # Preserves the hostname of the existing, already-deployed machine
+1 -1
View File
@@ -1,4 +1,4 @@
_: { ... }:
{ {
networking.hostName = "pxe-boot"; networking.hostName = "pxe-boot";
+10 -10
View File
@@ -1,22 +1,22 @@
{ vars, ... }: { config, ... }:
{ {
imports = [ networking.hostName = "server";
(import ../../modules/beszel/host-token.nix {
name = "server";
sopsFile = ../../secrets/server.yaml;
})
];
networking.hostName = vars.nfsServerHost;
networking.hostId = "6689f93e"; networking.hostId = "6689f93e";
sops.secrets."beszel-token".sopsFile = ../../secrets/server.yaml;
sops.templates."server-beszel.env".content = ''
TOKEN=${config.sops.placeholder."beszel-token"}
'';
services.beszel.agent.environment = { services.beszel.agent.environment = {
#DOCKER_HOST = "tcp://docker-socket-proxy:2375"; #DOCKER_HOST = "tcp://docker-socket-proxy:2375";
#HUB_URL = "http://docker.sweet.home:8090";
KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFPR9kwtC4TAeTRu46A7+opZsYpxqkRJ+x/ZyB2GWCeG"; KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFPR9kwtC4TAeTRu46A7+opZsYpxqkRJ+x/ZyB2GWCeG";
EXTRA_FILESYSTEMS = "${vars.storageRoot}/docker/volumes"; EXTRA_FILESYSTEMS = "/tank/docker/volumes";
LOG_LEVEL = "debug"; LOG_LEVEL = "debug";
}; };
services.beszel.agent.environmentFile = config.sops.templates."server-beszel.env".path;
# Preserved from the pre-refactor `server` target — stateVersion must never # Preserved from the pre-refactor `server` target — stateVersion must never
# be bumped on an already-installed machine. # be bumped on an already-installed machine.
+6 -6
View File
@@ -1,9 +1,9 @@
{ vars, ... }: { ... }:
{ {
services.beszel.agent.enable = true; services.beszel.agent.enable = true;
services.beszel.agent.environment = { services.beszel.agent.environment = {
#DOCKER_HOST = "tcp://docker-socket-proxy:2375"; #DOCKER_HOST = "tcp://docker-socket-proxy:2375";
HUB_URL = "http://${vars.dockerHost}.${vars.homeDomain}:${toString vars.beszelHubPort}"; HUB_URL = "http://docker.sweet.home:8090";
}; };
} }
-11
View File
@@ -1,11 +0,0 @@
{ name, sopsFile }:
{ config, ... }:
{
sops.secrets."beszel-token".sopsFile = sopsFile;
sops.templates."${name}-beszel.env".content = ''
TOKEN=${config.sops.placeholder."beszel-token"}
'';
services.beszel.agent.environmentFile = config.sops.templates."${name}-beszel.env".path;
}
+1 -1
View File
@@ -1,4 +1,4 @@
_: { ... }:
{ {
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
+5 -5
View File
@@ -1,4 +1,4 @@
{ pkgs, vars, ... }: { pkgs, ... }:
{ {
# Pins the Docker Engine version, carried forward from the pre-refactor # Pins the Docker Engine version, carried forward from the pre-refactor
@@ -13,11 +13,11 @@
imports = [ imports = [
../docker/mount-data.nix ../docker/mount-data.nix
../docker/enable-service.nix ../docker/enable-service.nix
../docker/nextcloud-cron-job.nix
../docker/docker-health-to-gotify.nix
../tailscale/enable-service.nix ../tailscale/enable-service.nix
../traefik/rotate-logs.nix ../rotate-traefik-logs.nix
../raspi/mount-data.nix ../raspi/mount-data.nix
../services/nextcloud-cron-job.nix
../services/docker-health-to-gotify.nix
../services/enable-rpcbind.nix ../services/enable-rpcbind.nix
]; ];
@@ -36,5 +36,5 @@
users.users.nixos.extraGroups = [ "docker" ]; users.users.nixos.extraGroups = [ "docker" ];
services.openssh.settings.PermitRootLogin = "yes"; services.openssh.settings.PermitRootLogin = "yes";
networking.firewall.allowedTCPPorts = [ 80 8080 443 vars.beszelHubPort ]; networking.firewall.allowedTCPPorts = [ 80 8080 443 8090 ];
} }
+27 -43
View File
@@ -2,7 +2,7 @@
{ {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
inputs.nixos-conf-editor.packages.${pkgs.stdenv.hostPlatform.system}.nixos-conf-editor inputs.nixos-conf-editor.packages.${pkgs.system}.nixos-conf-editor
nodejs nodejs
appimage-run appimage-run
seahorse seahorse
@@ -19,55 +19,39 @@
boot.loader.grub.useOSProber = true; boot.loader.grub.useOSProber = true;
services = { services.xserver.enable = true;
xserver = { services.xserver.displayManager.lightdm.enable = true;
enable = true; services.xserver.desktopManager.cinnamon.enable = true;
displayManager = { services.xserver.xkb = {
lightdm.enable = true; layout = "au";
sessionCommands = '' variant = "";
eval $(gnome-keyring-daemon --start --components=secrets,ssh)
export SSH_AUTH_SOCK
'';
};
desktopManager.cinnamon.enable = true;
xkb = {
layout = "au";
variant = "";
};
};
printing.enable = true;
pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
xrdp = {
enable = true;
defaultWindowManager = "cinnamon-session";
openFirewall = true;
};
gnome.gnome-keyring.enable = true;
}; };
security = { services.printing.enable = true;
rtkit.enable = true;
pam.services.login.enableGnomeKeyring = true; security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
}; };
# The networkmanager group only exists when NM is actually enabled — the users.users.nixos.extraGroups = [ "networkmanager" ];
# lxc platform module force-disables it, so don't add the user to a group
# that won't exist there.
users.users.nixos.extraGroups = lib.mkIf config.networking.networkmanager.enable [ "networkmanager" ];
programs.firefox.enable = true; programs.firefox.enable = true;
services.xrdp.enable = true;
services.xrdp.defaultWindowManager = "cinnamon-session";
services.xrdp.openFirewall = true;
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
services.gnome.gnome-keyring.enable = true;
security.pam.services.login.enableGnomeKeyring = true;
services.xserver.displayManager.sessionCommands = ''
eval $(gnome-keyring-daemon --start --components=secrets,ssh)
export SSH_AUTH_SOCK
'';
} }
+2 -5
View File
@@ -1,12 +1,9 @@
{ lib, pkgs, config, ... }: { pkgs, ... }:
{ {
networking.networkmanager.enable = true; networking.networkmanager.enable = true;
# The networkmanager group only exists when NM is actually enabled — the users.users.nixos.extraGroups = [ "networkmanager" ];
# lxc platform module force-disables it, so don't add the user to a group
# that won't exist there.
users.users.nixos.extraGroups = lib.mkIf config.networking.networkmanager.enable [ "networkmanager" ];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
inetutils inetutils
+25 -29
View File
@@ -1,10 +1,10 @@
{ config, lib, pkgs, inputs, vars, ... }: { config, lib, pkgs, inputs, ... }:
let let
pxeRoot = "/srv/pxe"; pxeRoot = "/srv/pxe";
httpRoot = "${pxeRoot}/http"; httpRoot = "${pxeRoot}/http";
tftpRoot = "${pxeRoot}/tftp"; tftpRoot = "${pxeRoot}/tftp";
pxeBaseUrl = "http://${vars.pxeServerIp}"; pxeBaseUrl = "http://192.168.2.247";
bootIpxe = pkgs.writeText "boot.ipxe" '' bootIpxe = pkgs.writeText "boot.ipxe" ''
#!ipxe #!ipxe
@@ -76,7 +76,9 @@ let
choose target && goto ''${target} choose target && goto ''${target}
:nixos :nixos
chain ''${base}/nixos/netboot.ipxe kernel ''${base}/nixos/bzImage ip=dhcp
initrd ''${base}/nixos/initrd
boot
:rescue :rescue
chain ''${base}/systemrescue.ipxe chain ''${base}/systemrescue.ipxe
@@ -89,40 +91,32 @@ let
''; '';
in in
{ {
imports = [
../pxe-boot/stage-installer-artifacts.nix
];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
ipxe ipxe
]; ];
services = { services.nginx = {
nginx = { enable = true;
enable = true;
virtualHosts."pxe-boot" = { virtualHosts."pxe-boot" = {
default = true; default = true;
root = httpRoot; root = httpRoot;
locations."/" = { locations."/" = {
extraConfig = '' extraConfig = ''
autoindex on; autoindex on;
''; '';
};
}; };
}; };
};
# TFTP is only used to deliver the initial iPXE bootloader. After iPXE # TFTP is only used to deliver the initial iPXE bootloader. After iPXE
# starts, all further assets are fetched via nginx over HTTP. # starts, all further assets are fetched via nginx over HTTP.
atftpd = { services.atftpd = {
enable = true; enable = true;
root = tftpRoot; root = tftpRoot;
extraOptions = [ extraOptions = [
"--verbose=5" "--verbose=5"
]; ];
};
openssh.settings.PermitRootLogin = "yes";
}; };
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
@@ -155,6 +149,8 @@ in
}; };
}; };
services.openssh.settings.PermitRootLogin = "yes";
networking.firewall.allowedTCPPorts = [ 80 ]; networking.firewall.allowedTCPPorts = [ 80 ];
networking.firewall.allowedUDPPorts = [ 69 ]; networking.firewall.allowedUDPPorts = [ 69 ];
} }
+7 -7
View File
@@ -1,4 +1,4 @@
{ vars, lib, ... }: { ... }:
{ {
imports = [ imports = [
@@ -6,7 +6,7 @@
../services/zfs/enable-service.nix ../services/zfs/enable-service.nix
]; ];
boot.zfs.extraPools = [ (lib.removePrefix "/" vars.storageRoot) ]; boot.zfs.extraPools = [ "tank" ];
systemd.services.nfs-server = { systemd.services.nfs-server = {
after = [ "zfs-mount.service" ]; after = [ "zfs-mount.service" ];
@@ -16,11 +16,11 @@
services.nfs.server = { services.nfs.server = {
enable = true; enable = true;
exports = '' exports = ''
${vars.storageRoot}/docker/config ${vars.lanCidr}(rw,sync,no_subtree_check,no_root_squash) /tank/docker/config 192.168.2.0/24(rw,sync,no_subtree_check,no_root_squash)
${vars.storageRoot}/docker/volumes ${vars.lanCidr}(rw,sync,no_subtree_check,no_root_squash) /tank/docker/volumes 192.168.2.0/24(rw,sync,no_subtree_check,no_root_squash)
${vars.storageRoot}/docker/databases ${vars.lanCidr}(rw,sync,no_subtree_check,no_root_squash) /tank/docker/databases 192.168.2.0/24(rw,sync,no_subtree_check,no_root_squash)
${vars.storageRoot}/docker/nextcloud-data ${vars.lanCidr}(rw,sync,no_subtree_check,no_root_squash) /tank/docker/nextcloud-data 192.168.2.0/24(rw,sync,no_subtree_check,no_root_squash)
${vars.storageRoot}/raspi/volumes ${vars.lanCidr}(rw,sync,no_subtree_check,no_root_squash) /tank/raspi/volumes 192.168.2.0/24(rw,sync,no_subtree_check,no_root_squash)
''; '';
}; };
+3 -3
View File
@@ -1,4 +1,4 @@
{ config, pkgs, lib, vars, ... }: { config, pkgs, lib, ... }:
let let
# Flake attribute names are now <platform>-<buildtype> (e.g. proxmox-docker) # Flake attribute names are now <platform>-<buildtype> (e.g. proxmox-docker)
@@ -9,13 +9,13 @@ let
sudo nixos-rebuild switch \ sudo nixos-rebuild switch \
--no-write-lock-file \ --no-write-lock-file \
--refresh \ --refresh \
--flake git+https://${vars.lanDomain}/beatzaplenty/nixos.git#$(cat /etc/flake-target) --flake git+https://gitea.lan.ddnsgeek.com/beatzaplenty/nixos.git#$(cat /etc/flake-target)
''; '';
myTestCmd = '' myTestCmd = ''
sudo nixos-rebuild test \ sudo nixos-rebuild test \
--no-write-lock-file \ --no-write-lock-file \
--refresh \ --refresh \
--flake git+https://${vars.lanDomain}/beatzaplenty/nixos.git#$(cat /etc/flake-target) --flake git+https://gitea.lan.ddnsgeek.com/beatzaplenty/nixos.git#$(cat /etc/flake-target)
''; '';
in in
{ {
+29 -42
View File
@@ -1,36 +1,29 @@
{ config, lib, pkgs, vars, ... }: { config, lib, pkgs, ... }:
{ {
imports = imports =
[ [ # Include the results of the hardware scan.
# Include the results of the hardware scan. # ./hardware-configuration.nix
# ./hardware-configuration.nix ../set-locale.nix
./set-locale.nix
]; ];
# Use the GRUB 2 boot loader. # Use the GRUB 2 boot loader.
# boot.loader.grub.enable = true; # boot.loader.grub.enable = true;
#boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only #boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only
networking.networkmanager.enable = true; # Easiest to use and most distros use this by default. networking.networkmanager.enable = true; # Easiest to use and most distros use this by default.
# Recommended over the true default (bypasses ZFS's own import safeguards)
# per the option's own docs; matches hosts/docker/host.nix and
# modules/services/zfs/enable-service.nix, which already set this
# explicitly. Harmless no-op on hosts that don't use ZFS at all.
boot.zfs.forceImportRoot = false;
# Set your time zone. # Set your time zone.
time.timeZone = vars.timeZone; time.timeZone = "Australia/Brisbane";
# Enable QEMU agent # Enable QEMU agent
services.qemuGuest.enable = true; services.qemuGuest.enable = true;
# Enable docker-compose # Enable docker-compose
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
vim vim
btop btop
git git
gcr gcr
]; ];
# Secrets shared by every host, decrypted at activation via each host's # Secrets shared by every host, decrypted at activation via each host's
@@ -39,34 +32,28 @@
# or docs/ for the sops workflow). hashedPassword/hashedPasswordFile need # or docs/ for the sops workflow). hashedPassword/hashedPasswordFile need
# neededForUsers so they're available before the normal secret-activation # neededForUsers so they're available before the normal secret-activation
# step, since user creation happens very early in boot. # step, since user creation happens very early in boot.
sops = { sops.defaultSopsFile = ../../secrets/common.yaml;
defaultSopsFile = ../../secrets/common.yaml; sops.secrets."root-hashedPassword".neededForUsers = true;
sops.secrets."nixos-hashedPassword".neededForUsers = true;
secrets = { sops.secrets."nix-github-token" = { };
"root-hashedPassword".neededForUsers = true;
"nixos-hashedPassword".neededForUsers = true;
"nix-github-token" = { };
};
# nix.conf doesn't support a *File-style option for access-tokens, so the
# token is rendered into a runtime-only file (never touches the Nix store)
# and pulled in via nix.conf's native !include directive.
templates."nix-github-token.conf".content = ''
access-tokens = github.com=${config.sops.placeholder."nix-github-token"}
'';
};
# nix.conf doesn't support a *File-style option for access-tokens, so the
# token is rendered into a runtime-only file (never touches the Nix store)
# and pulled in via nix.conf's native !include directive.
sops.templates."nix-github-token.conf".content = ''
access-tokens = github.com=${config.sops.placeholder."nix-github-token"}
'';
nix.extraOptions = '' nix.extraOptions = ''
!include ${config.sops.templates."nix-github-token.conf".path} !include ${config.sops.templates."nix-github-token.conf".path}
''; '';
#Set root password #Set root password
users.users.root = { users.users.root = {
hashedPasswordFile = config.sops.secrets."root-hashedPassword".path; hashedPasswordFile = config.sops.secrets."root-hashedPassword".path;
}; };
# Define a user account. Don't forget to set a password with ‘passwd’. # Define a user account. Don't forget to set a password with ‘passwd’.
users.users.${vars.primaryUser} = { users.users.nixos = {
isNormalUser = true; isNormalUser = true;
extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
packages = with pkgs; [ packages = with pkgs; [
@@ -74,8 +61,8 @@
]; ];
hashedPasswordFile = config.sops.secrets."nixos-hashedPassword".path; hashedPasswordFile = config.sops.secrets."nixos-hashedPassword".path;
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [
vars.adminSshKey "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCq/Q5LvIXlZwO2kdeAN5nLGZ59nZB7JHYMEszHxmNtGMzv1lM31jiPNsr0z2EKVZhE7OOfa2IF9rhWYD7JUA9G0yzdZ4WTXFNGVVOJoOVH6vAF3XCxoVilOEwTc7h2Wiy+rzd0B28/3spffzQQWJhY6GRQVa8j+6xAGF60Fcvl1vLosYT9Bn2ZbK4TCWOwAn2jqXIieGpZdn/UNZbGOeKRiCvhktDfMAzuQzN/9jMu/oF4pkPn2X1UrsQdNlvp0Ci8md612MozIpncQJyAF1ADhunr3sMx0isUXiqD29R5DS4TftpekqLNLak+zcxFa8N7DcRNp3DcKfJvyTkwQrR4r+b7lFLYOLHLagSso9CzeW/paAS2q9I5SBm/2DtE1diLLg2jZikYcstsu/G5RgvbzbKqjiaMwTdXC3AMvDxQrs7U5pDRZFzoofG3cpODbTm+uy3m0kP70z0M1K45UbDG0p+itnTu9x40JbQEgefbx38AItNvAIx1A8HO4I1VX28= wayne@stream"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICMJhrfFayLBG+gWtO6oAvgambw5nWWgztiTFEaaaVRH debian@surface" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICMJhrfFayLBG+gWtO6oAvgambw5nWWgztiTFEaaaVRH debian@surface"
]; ];
}; };
+42 -46
View File
@@ -1,69 +1,65 @@
{ config, pkgs, lib, vars, ... }: { config, pkgs, lib, ... }:
let let
remote = "root@proxmox-ip:/var/lib/vz/template/iso"; remote = "root@proxmox-ip:/var/lib/vz/template/iso";
localMount = "${config.home.homeDirectory}/proxmox-iso"; localMount = "${config.home.homeDirectory}/proxmox-iso";
in in {
{
imports = [ imports = [
./aliases.nix ./aliases.nix
]; ];
home = { home.username = "nixos"; # your actual username
username = vars.primaryUser; home.homeDirectory = "/home/nixos";
homeDirectory = "/home/${vars.primaryUser}"; home.stateVersion = "25.11"; # match your NixOS stateVersion
stateVersion = "25.11"; # match your NixOS stateVersion
# Optional: packages programs.home-manager.enable = true; # mandatory to activate HM
packages = with pkgs; [
git
vim
tmux
nano
sshfs
];
# Optional: set environment vars programs.bash.enable = true;
sessionVariables = {
EDITOR = "nano";
};
};
programs.home-manager.enable = true; # mandatory to activate HM
programs.bash.enable = true;
# GitHub access-tokens setting used to live here in plaintext; it's now # GitHub access-tokens setting used to live here in plaintext; it's now
# rendered system-wide from a sops-nix secret via nix.extraOptions in # rendered system-wide from a sops-nix secret via nix.extraOptions in
# modules/common/configuration.nix instead (covers the daemon for every # modules/common/configuration.nix instead (covers the daemon for every
# user, not just this one). # user, not just this one).
# systemd.user.services.mount-proxmox-iso = { # Optional: packages
# Unit = { home.packages = with pkgs; [
# Description = "Mount Proxmox ISO dir via SSHFS"; git
# After = [ "network-online.target" ]; vim
# Wants = [ "network-online.target" ]; tmux
# }; nano
sshfs
];
# Service = { # Optional: set environment vars
# Type = "simple"; home.sessionVariables = {
# ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p ${localMount}"; EDITOR = "nano";
# ExecStart = "${pkgs.sshfs}/bin/sshfs -o IdentityFile=${config.home.homeDirectory}/.ssh/id_ed25519,allow_other,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3 root@proxmox-ip:/var/lib/vz/template/iso ${localMount}"; };
# ExecStop = "${pkgs.fuse3}/bin/fusermount3 -u ${localMount}"; # systemd.user.services.mount-proxmox-iso = {
# Restart = "on-failure"; # Unit = {
# }; # Description = "Mount Proxmox ISO dir via SSHFS";
# After = [ "network-online.target" ];
# Wants = [ "network-online.target" ];
# };
# Install = { # Service = {
# WantedBy = [ "default.target" ]; # Type = "simple";
# }; # ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p ${localMount}";
# }; # ExecStart = "${pkgs.sshfs}/bin/sshfs -o IdentityFile=${config.home.homeDirectory}/.ssh/id_ed25519,allow_other,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3 root@proxmox-ip:/var/lib/vz/template/iso ${localMount}";
# ExecStop = "${pkgs.fuse3}/bin/fusermount3 -u ${localMount}";
# Restart = "on-failure";
# };
# Install = {
# WantedBy = [ "default.target" ];
# };
# };
# Optional: enable bash (or zsh, fish...) # Optional: enable bash (or zsh, fish...)
# programs.bash.enable = true; # programs.bash.enable = true;
# Optional: manage dotfiles via symlinks # Optional: manage dotfiles via symlinks
# home.file = { # home.file = {
# ".tmux.conf".source = ./dotfiles/tmux.conf; # ".tmux.conf".source = ./dotfiles/tmux.conf;
# ".config/nvim/init.vim".source = ./dotfiles/init.vim; # ".config/nvim/init.vim".source = ./dotfiles/init.vim;
# }; # };
} }
+1 -1
View File
@@ -1,4 +1,4 @@
_: { ... }:
{ {
disko.devices = { disko.devices = {
+16 -16
View File
@@ -1,23 +1,23 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
# virtualisation.docker.enable = true; # virtualisation.docker.enable = true;
virtualisation.docker = { virtualisation.docker = {
enable = true; enable = true;
package = pkgs.docker; package = pkgs.docker;
# listenOptions = [ # listenOptions = [
# "unix:///var/run/docker.sock" # "unix:///var/run/docker.sock"
# "tcp://0.0.0.0:2375" # "tcp://0.0.0.0:2375"
#]; #];
# daemon.settings = { # daemon.settings = {
# metrics-addr = "0.0.0.0:9323"; # metrics-addr = "0.0.0.0:9323";
# experimental = true; # experimental = true;
# }; # };
}; };
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
docker-compose docker-compose
docker-buildx docker-buildx
]; ];
} }
+50 -52
View File
@@ -1,65 +1,63 @@
{ config, lib, pkgs, vars, ... }: { config, lib, pkgs, ... }:
{ {
fileSystems = { fileSystems."/mnt/docker/config" = {
"/mnt/docker/config" = { device = "server:/tank/docker/config";
device = "${vars.nfsServerHost}:${vars.storageRoot}/docker/config"; fsType = "nfs";
fsType = "nfs";
options = [ options = [
"nfsvers=4.2" "nfsvers=4.2"
"_netdev" "_netdev"
"x-systemd.automount" "x-systemd.automount"
"noatime" "noatime"
]; ];
}; };
"/mnt/docker/databases" = { fileSystems."/mnt/docker/databases" = {
device = "${vars.nfsServerHost}:${vars.storageRoot}/docker/databases"; device = "server:/tank/docker/databases";
fsType = "nfs"; fsType = "nfs";
options = [ options = [
"nfsvers=4.2" "nfsvers=4.2"
"_netdev" "_netdev"
"x-systemd.automount" "x-systemd.automount"
"noatime" "noatime"
]; ];
}; };
"/mnt/docker/volumes" = { fileSystems."/mnt/docker/volumes" = {
device = "${vars.nfsServerHost}:${vars.storageRoot}/docker/volumes"; device = "server:/tank/docker/volumes";
fsType = "nfs"; fsType = "nfs";
options = [ options = [
"nfsvers=4.2" "nfsvers=4.2"
"_netdev" "_netdev"
"x-systemd.automount" "x-systemd.automount"
"noatime" "noatime"
]; ];
}; };
"/mnt/nextcloud-data" = { fileSystems."/mnt/nextcloud-data" = {
device = "${vars.nfsServerHost}:${vars.storageRoot}/docker/nextcloud-data"; device = "server:/tank/docker/nextcloud-data";
fsType = "nfs"; fsType = "nfs";
options = [ options = [
"nfsvers=4.2" "nfsvers=4.2"
"_netdev" "_netdev"
"x-systemd.automount" "x-systemd.automount"
"noatime" "noatime"
]; ];
}; };
"/mnt/raspi-backup" = { fileSystems."/mnt/raspi-backup" = {
device = "${vars.nfsServerHost}:${vars.storageRoot}/raspi/volumes"; device = "server:/tank/raspi/volumes";
fsType = "nfs"; fsType = "nfs";
options = [ options = [
"nfsvers=4.2" "nfsvers=4.2"
"_netdev" "_netdev"
"x-systemd.automount" "x-systemd.automount"
"noatime" "noatime"
]; ];
};
}; };
} }
-22
View File
@@ -1,22 +0,0 @@
{ pkgs, vars, ... }:
{
# Create nextcloud cron scheduled task
systemd.services.nextcloud = {
description = "Nextcloud scheduled task";
script = ''${pkgs.bash}/bin/bash ~/docker/services-up.sh --profile nextcloud exec -u 33 nextcloud-webapp php ./cron.php'';
serviceConfig = {
Type = "oneshot";
User = vars.primaryUser;
};
path = with pkgs; [ docker docker-compose ];
};
systemd.timers.nextcloud = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*:0/5";
Persistent = true;
};
};
}
File renamed without changes.
+22 -28
View File
@@ -5,42 +5,36 @@
{ {
imports = imports =
[ [ (modulesPath + "/profiles/qemu-guest.nix")
(modulesPath + "/profiles/qemu-guest.nix")
]; ];
boot = { boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_scsi" "ahci" "sd_mod" ];
initrd.availableKernelModules = [ "virtio_pci" "virtio_scsi" "ahci" "sd_mod" ]; boot.initrd.kernelModules = [ ];
initrd.kernelModules = [ ]; boot.kernelModules = [ ];
kernelModules = [ ]; boot.extraModulePackages = [ ];
extraModulePackages = [ ]; boot.loader.grub.device = "/dev/sda";
# Enable LISH
kernelParams = [ "console=ttyS0,19200n8" ];
loader = {
grub = {
device = "/dev/sda";
extraConfig = ''
serial --speed=19200 --unit=0 --word=8 --parity=no --stop=1;
terminal_input serial;
terminal_output serial;
'';
forceInstall = true;
# device = "nodev";
};
timeout = 10;
};
};
fileSystems."/" = fileSystems."/" =
{ { device = "/dev/sda";
device = "/dev/sda";
fsType = "ext4"; fsType = "ext4";
}; };
swapDevices = swapDevices =
[{ device = "/dev/sdb"; }]; [ { device = "/dev/sdb"; }
];
# Enable LISH
boot.kernelParams = [ "console=ttyS0,19200n8" ];
boot.loader.grub.extraConfig = ''
serial --speed=19200 --unit=0 --word=8 --parity=no --stop=1;
terminal_input serial;
terminal_output serial;
'';
boot.loader.grub.forceInstall = true;
# boot.loader.grub.device = "nodev";
boot.loader.timeout = 10;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
} }
@@ -5,16 +5,13 @@
{ {
imports = imports =
[ [ (modulesPath + "/profiles/qemu-guest.nix")
(modulesPath + "/profiles/qemu-guest.nix")
]; ];
boot = { boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; boot.initrd.kernelModules = [ ];
initrd.kernelModules = [ ]; boot.kernelModules = [ "kvm-amd" ];
kernelModules = [ "kvm-amd" ]; boot.extraModulePackages = [ ];
extraModulePackages = [ ];
};
# boot.loader.grub.device = "/dev/sda2"; # or "nodev" for efi only # boot.loader.grub.device = "/dev/sda2"; # or "nodev" for efi only
# fileSystems."/" = # fileSystems."/" =
-251
View File
@@ -1,251 +0,0 @@
{ pkgs, lib, vars, ... }:
{
imports = [
./host-keys.nix
];
networking.useDHCP = lib.mkDefault true;
# Recommended over the true default (bypasses ZFS's own import safeguards)
# per the option's own docs. This installer environment has no ZFS pools
# of its own to import, so this is a no-op here — just silences the
# eval-time warning, matching modules/common/configuration.nix.
boot.zfs.forceImportRoot = false;
time.timeZone = vars.timeZone;
# Without this, the installer only ever sees cache.nixos.org, which
# doesn't carry sops-install-secrets (it's built straight from the
# sops-nix flake's own Go source, not part of nixpkgs) — every install
# would otherwise compile it from scratch, which is what ran an 8GB LXC
# container's disk out of space. Push a built copy to nix-cache once
# (from a machine with real disk headroom) and every future install,
# of any type, fetches instead of rebuilding.
nix.settings = {
substituters = [
"http://nix-cache"
"https://cache.nixos.org/"
];
trusted-public-keys = [
"cache.local-1:usoWYanY3Kpq2+kDIS2nhWoLZiRxanmdysdzqCFBHW4="
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
];
};
environment = {
systemPackages = with pkgs; [
git
curl
jq
parted
e2fsprogs
btrfs-progs
util-linux
disko
];
# Write auto-install script to /root
etc."auto-install.sh" = {
text = ''
#!/run/current-system/sw/bin/bash
set -eux
set -euo pipefail
export FLAKE_BASE_URL="git+https://${vars.lanDomain}/beatzaplenty/nixos.git"
echo "Fetching available NixOS hosts from flake..."
# Two categories deliberately excluded from the menu:
# lxc-* — these build a config.system.build.tarball
# meant for `pct restore` on Proxmox
# directly, not an install. Running
# nixos-install against one here would
# bind-mount / onto /mnt and then refuse to
# touch the filesystem it's currently
# running on — see docs/auto-installer.md.
# installer/proxmox-lxc — these *are* the installer image's own
# flake targets, not deployable hosts;
# "installing" one means nixos-install-ing
# a copy of the installer into itself.
mapfile -t options < <(
nix eval --json --no-use-registries --no-accept-flake-config --extra-experimental-features "flakes nix-command" \
"''${FLAKE_BASE_URL}#nixosConfigurations" \
--apply builtins.attrNames \
| jq -r '.[]
| select(startswith("lxc-") | not)
| select(. != "installer")
| select(. != "proxmox-lxc")'
)
if [[ ''${#options[@]} -eq 0 ]]; then
echo "ERROR: No NixOS hosts found in ''${FLAKE_BASE_URL}#nixosConfigurations" >&2
exit 1
fi
echo "Note: lxc-* targets aren't installed this way — build them with"
echo " nix build .#nixosConfigurations.<name>.config.system.build.tarball"
echo "and 'pct restore' the result on Proxmox directly. See docs/auto-installer.md."
echo "Choose the flake profile to install:"
select choice in "''${options[@]}"; do
if [[ -n "$choice" ]]; then
echo "You selected: $choice"
break
else
echo "Invalid selection. Try again."
fi
done
echo "Starting install with flake: ''${FLAKE_BASE_URL}#''${choice}"
# Optional: confirm before proceeding
read -rp "Proceed with installation? (y/N): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Aborted."
exit 1
fi
# A nix-cache host is *the* substituter/remote-builder for every other
# host once installed (its own config explicitly excludes itself from
# using either — see buildType != "nix-cache" in the nixos flake.nix).
# Installing one shouldn't depend on a nix-cache substituter either,
# for the same reason — plus in practice "nix-cache" only resolves over
# Tailscale, which a fresh installer environment was never connected to
# anyway, so it's dead weight even for non-nix-cache installs until
# that's sorted out. Override it away here specifically for nix-cache
# targets to keep install-time behaviour consistent with run-time.
nix_extra_opts=()
if [[ "''${choice}" == *-nix-cache ]]; then
echo "Installing a nix-cache host — skipping the nix-cache substituter."
nix_extra_opts+=(--option substituters "https://cache.nixos.org/")
fi
if nix eval --refresh --json --extra-experimental-features "flakes nix-command" "''${nix_extra_opts[@]}" "''${FLAKE_BASE_URL}#nixosConfigurations.''${choice}.config.disko.devices.disk.main.device" >/dev/null 2>&1; then
disko --mode destroy,format,mount \
--flake "''${FLAKE_BASE_URL}#''${choice}" "''${nix_extra_opts[@]}" --yes
else
# No raw disk to partition — true for every LXC container, which has
# no block device visible from inside it, only its already-mounted
# root filesystem. nixos-install defaults to installing into /mnt; if
# nothing points /mnt at the real root, the new system gets built and
# written to a disconnected empty directory, never actually becomes
# bootable, and the container silently keeps running this installer
# environment forever. Bind-mount / onto /mnt so the install actually
# lands on the filesystem this container boots from.
echo "Selected host has no Disko configuration — installing in place via bind mount."
mount --bind / /mnt
fi
# sops-nix derives this host's decryption key from its own SSH host key
# at *activation* time, which runs before systemd would otherwise
# generate one on first boot. Without pre-seeding it here, secrets
# (including the login password) fail to decrypt on first boot.
# Generate the key with scripts/prepare-host-key.sh first.
#
# Two places a key can come from, checked in order:
# /etc/host-keys — baked into this image at build time (see
# modules/installer/host-keys.nix; only present
# if built with NIXOS_HOST_KEYS_DIR set)
# /root/host-keys — scp'd in manually after boot (older fallback,
# still supported for images built without keys)
mkdir -p /root/host-keys
if [[ -f "/etc/host-keys/''${choice}_ssh_host_ed25519_key" ]]; then
echo "Found baked-in SSH host key for ''${choice}, installing to target..."
install -D -m 0600 "/etc/host-keys/''${choice}_ssh_host_ed25519_key" /mnt/etc/ssh/ssh_host_ed25519_key
install -D -m 0644 "/etc/host-keys/''${choice}_ssh_host_ed25519_key.pub" /mnt/etc/ssh/ssh_host_ed25519_key.pub
elif [[ -f "/root/host-keys/''${choice}_ssh_host_ed25519_key" ]]; then
echo "Found pre-seeded SSH host key for ''${choice}, installing to target..."
install -D -m 0600 "/root/host-keys/''${choice}_ssh_host_ed25519_key" /mnt/etc/ssh/ssh_host_ed25519_key
install -D -m 0644 "/root/host-keys/''${choice}_ssh_host_ed25519_key.pub" /mnt/etc/ssh/ssh_host_ed25519_key.pub
else
echo "WARNING: no SSH host key found for ''${choice} (checked /etc/host-keys and /root/host-keys)"
echo "sops-nix secrets (including the login password) will NOT decrypt on first boot."
echo "Run scripts/prepare-host-key.sh for host ''${choice} on your admin workstation first,"
echo "then either rebuild this image with NIXOS_HOST_KEYS_DIR set, or scp the result to"
echo "/root/host-keys/ on this machine."
read -rp "Continue without a pre-seeded key anyway? (y/N): " skip_key
if [[ ! "$skip_key" =~ ^[Yy]$ ]]; then
echo "Aborted."
exit 1
fi
fi
mkdir -p /mnt/install-tmp
export TMPDIR=/mnt/install-tmp
nixos-install \
--flake "''${FLAKE_BASE_URL}#''${choice}" \
"''${nix_extra_opts[@]}" \
--no-root-password
rm -rf /mnt/install-tmp
# Redundant copy of the host's private key — the real one is now at
# /etc/ssh/ssh_host_ed25519_key. Nothing NixOS-managed ever cleans this
# up on its own since it was written imperatively, not declaratively.
rm -rf /root/host-keys
sleep 10
reboot
'';
mode = "0755";
};
};
programs.git.enable = true;
# Run the installer on first login. Previously this copied an /etc file
# into the nixos user's ~/.bash_profile via an activation script that
# got dropped in a refactor (and only ever worked for that one user
# anyway) — loginShellInit is NixOS's native hook for this, applies to
# any user's login shell (root included), and needs no home-directory
# file-copying/chown.
programs.bash.loginShellInit = ''
if [ -n "$PS1" ] && [ ! -e "$HOME/.auto_install_ran" ]; then
sudo /etc/auto-install.sh
touch "$HOME/.auto_install_ran"
fi
'';
services.openssh.enable = true;
services.openssh.settings = {
PermitRootLogin = "yes";
PasswordAuthentication = true;
};
# nixpkgs' own installer profile (profiles/installation-device.nix, pulled
# in via installation-cd-minimal.nix) sets initialHashedPassword = "" for
# both users — its own passwordless-login convention for install media.
# That's a second, non-null password option alongside our hashedPassword
# below, which NixOS warns about as ambiguous precedence. Force it null
# rather than adopting passwordless login: this image now also boots over
# LAN PXE with PasswordAuthentication enabled, so passwordless root SSH
# would be reachable by anyone on the LAN, not just local console.
users.users.root = {
hashedPassword =
"$6$Kwv9KAyvcurAViQF$H4.u3feqGE7lVoNgkFXhE3n2Pmo//9JYDTCz8ifrVHBxPjwa1xMby7tEZ8Bpt5MXs9Rkx6/YbZWxs5CpH0s/70";
initialHashedPassword = lib.mkForce null;
};
users.users.${vars.primaryUser} = {
isNormalUser = true;
extraGroups = [
"wheel"
];
shell = pkgs.bashInteractive;
hashedPassword =
"$6$Kwv9KAyvcurAViQF$H4.u3feqGE7lVoNgkFXhE3n2Pmo//9JYDTCz8ifrVHBxPjwa1xMby7tEZ8Bpt5MXs9Rkx6/YbZWxs5CpH0s/70";
initialHashedPassword = lib.mkForce null;
openssh.authorizedKeys.keys = [
vars.adminSshKey
];
};
system.stateVersion = "26.05";
}
-37
View File
@@ -1,37 +0,0 @@
{ lib, ... }:
let
# host-keys/ is gitignored (private key material must never be committed),
# which means flakes' git-filtered source tree can never see it via a
# normal relative path — referencing it at all requires stepping outside
# pure evaluation. builtins.getEnv is neutered to "" under normal
# `nix build`/`nix eval` (no error, just empty), so this whole module is a
# silent no-op unless the operator explicitly opts in with --impure and
# the env var set — safe by default, including in CI.
#
# NIXOS_HOST_KEYS_DIR=$(pwd)/host-keys nix build .#iso --impure
#
# See docs/auto-installer.md.
hostKeysDirStr = builtins.getEnv "NIXOS_HOST_KEYS_DIR";
hasHostKeysDir = hostKeysDirStr != "" && builtins.pathExists hostKeysDirStr;
hostKeysDir = /. + hostKeysDirStr;
keyFileNames =
if hasHostKeysDir
then
lib.filter
(name: lib.hasSuffix "_ssh_host_ed25519_key" name || lib.hasSuffix "_ssh_host_ed25519_key.pub" name)
(lib.attrNames (builtins.readDir hostKeysDir))
else [ ];
in
{
environment.etc = lib.listToAttrs (map
(name: {
name = "host-keys/${name}";
value = {
source = hostKeysDir + "/${name}";
mode = "0400";
};
})
keyFileNames);
}
-8
View File
@@ -1,8 +0,0 @@
{ modulesPath, ... }:
{
imports = [
"${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
./common.nix
];
}
-12
View File
@@ -1,12 +0,0 @@
{ modulesPath, ... }:
{
imports = [
./common.nix
(modulesPath + "/virtualisation/proxmox-lxc.nix")
];
# LXC has no bootloader
boot.loader.grub.enable = false;
boot.loader.systemd-boot.enable = false;
}
+2 -2
View File
@@ -1,9 +1,9 @@
{ vars, ... }: { ... }:
{ {
nix.settings = { nix.settings = {
substituters = [ substituters = [
"http://${vars.nixCacheHost}" "http://nix-cache"
"https://cache.nixos.org/" "https://cache.nixos.org/"
]; ];
trusted-public-keys = [ trusted-public-keys = [
@@ -1,28 +0,0 @@
{ pkgs, vars, ... }:
{
# Install the remote builder key on each client host (do not commit private keys):
# sudo install -d -m 0700 /root/.ssh
# sudo install -m 0600 ./nixremote /root/.ssh/nixremote
# sudo ssh -i /root/.ssh/nixremote nixremote@nix-cache nix-store --version
nix = {
distributedBuilds = true;
buildMachines = [
{
hostName = vars.nixCacheHost;
sshUser = vars.remoteBuilderUser;
sshKey = "/root/.ssh/${vars.remoteBuilderUser}";
inherit (pkgs.stdenv.hostPlatform) system;
maxJobs = 4;
speedFactor = 2;
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
}
];
settings = {
builders-use-substitutes = true;
max-jobs = "auto";
};
};
}
+26 -23
View File
@@ -1,4 +1,4 @@
{ config, pkgs, vars, ... }: { config, pkgs, ... }:
{ {
# Generate the binary cache key pair on the nix-cache host: # Generate the binary cache key pair on the nix-cache host:
@@ -9,43 +9,46 @@
# sudo chmod 0600 /etc/nix/cache-priv.pem # sudo chmod 0600 /etc/nix/cache-priv.pem
# sudo chmod 0644 /etc/nix/cache-pub.pem # sudo chmod 0644 /etc/nix/cache-pub.pem
# cat /etc/nix/cache-pub.pem # cat /etc/nix/cache-pub.pem
services = { services.nix-serve = {
nix-serve = { enable = true;
enable = true; secretKeyFile = "/etc/nix/cache-priv.pem";
secretKeyFile = "/etc/nix/cache-priv.pem"; };
};
nginx = { services.nginx = {
enable = true; enable = true;
recommendedProxySettings = true; recommendedProxySettings = true;
virtualHosts.${vars.nixCacheHost} = { virtualHosts."nix-cache" = {
locations."/" = { locations."/" = {
proxyPass = "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}"; proxyPass = "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}";
};
}; };
}; };
openssh.enable = true;
}; };
networking.firewall.allowedTCPPorts = [ 80 ]; networking.firewall.allowedTCPPorts = [ 80 ];
users.groups.${vars.remoteBuilderUser} = { }; users.groups.nixremote = {};
users.users.${vars.remoteBuilderUser} = { users.users.nixremote = {
isSystemUser = true; isSystemUser = true;
group = vars.remoteBuilderUser; group = "nixremote";
createHome = true; createHome = true;
home = "/var/lib/nixremote"; home = "/var/lib/nixremote";
shell = pkgs.bashInteractive; shell = pkgs.bashInteractive;
# Client public keys allowed to use this host as a remote builder — # Provide remote builder public keys here (safe to commit public keys only):
# single source of truth is vars.remoteBuilderAuthorizedKeys (safe to # openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA... client@host" ];
# commit public keys only). #
openssh.authorizedKeys.keys = vars.remoteBuilderAuthorizedKeys; # Avoid absolute keyFiles paths here because they break pure flake evaluation.
openssh.authorizedKeys.keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFDEA1S2ikpObREgbP5uVBWMxIOGbY8B+Wx7VTZK1m6t root@server"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPAYIT9ormlmxZ0SziyDQaUntnKI8HK9/s3Qac1ZKjP2 root@docker"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKKKzoEPl/ZW9KBRHBcp6/ThOngGpwMv5EhkTlgC4aDf root@nixos"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIGtOWOCS+ImHc7NehguoyD7PbonGosKMZqc9+QR3v/h root@nixos"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHxXTQxFnArK5HXG7czeoybZebCGfxpUdusJkPn+BCSp root@server"];
}; };
services.openssh.enable = true;
nix.settings = { nix.settings = {
trusted-users = [ "root" vars.remoteBuilderUser ]; trusted-users = [ "root" "nixremote" ];
experimental-features = [ "nix-command" "flakes" ]; experimental-features = [ "nix-command" "flakes" ];
auto-optimise-store = true; auto-optimise-store = true;
builders-use-substitutes = true; builders-use-substitutes = true;
+4 -34
View File
@@ -1,38 +1,8 @@
{ lib, modulesPath, ... }: { ... }:
{ {
# LXC containers share the host kernel — Proxmox starts them by exec'ing boot.isContainer = true;
# /sbin/init directly, no bootloader/initrd involved — and Proxmox has its
# own container hostname/network provisioning outside Nix. nixpkgs' own
# virtualisation/proxmox-lxc.nix module already handles all of this
# correctly (boot.isContainer, loader.initScript, systemd-networkd) and,
# critically, provides config.system.build.tarball — a directly
# `pct restore`-able container image, no nixos-install/bind-mount needed
# (nixos-install refuses to touch the filesystem it's currently running
# on, which is exactly what bind-mounting / onto /mnt for an installer
# LXC container does).
imports = [
(modulesPath + "/virtualisation/proxmox-lxc.nix")
];
proxmoxLXC = { boot.loader.grub.enable = false;
# host.nix declares each host's real hostname (networking.hostName); boot.loader.systemd-boot.enable = false;
# keep that instead of letting Proxmox's ambient container config win.
manageHostName = true;
# Unprivileged matches how these containers are actually created.
privileged = false;
};
boot.loader = {
grub.enable = false;
systemd-boot.enable = false;
};
# NetworkManager depends on a running udevd to enumerate/classify devices,
# which boot.isContainer disables (see nixpkgs' container-config.nix) —
# that's what broke DHCP-hostname registration in Pi-hole. The imported
# proxmox-lxc.nix module already switches networking to systemd-networkd
# for the same reason; it just doesn't disable NetworkManager itself,
# which modules/common/configuration.nix enables for every host.
networking.networkmanager.enable = lib.mkForce false;
} }
@@ -1,23 +0,0 @@
{ netbootSystem, ... }:
let
# config.system.build.kernel and .netbootRamdisk are directories, not the
# files themselves — nixpkgs' own system.build.kexecTree does the same
# ${...}/<file> dereference for the same reason.
inherit (netbootSystem.config.system.boot.loader) kernelFile;
in
{
# Builds this flake's own installer netboot image (the same one
# `nix build .#pxe` produces) and stages it where menu.ipxe's :nixos
# entry expects it, so the pxe-boot host is self-contained — no manual
# operator step to populate /srv/pxe/http/nixos after deploy.
systemd.tmpfiles.rules = [
# Declared here too (not just in build-types/pxe-boot.nix) so this
# module's C+ rules don't depend on cross-module list-merge ordering —
# tmpfiles' C type needs the target directory to already exist.
"d /srv/pxe/http/nixos 0755 root root -"
"C+ /srv/pxe/http/nixos/${kernelFile} 0644 root root - ${netbootSystem.config.system.build.kernel}/${kernelFile}"
"C+ /srv/pxe/http/nixos/initrd 0644 root root - ${netbootSystem.config.system.build.netbootRamdisk}/initrd"
"C+ /srv/pxe/http/nixos/netboot.ipxe 0644 root root - ${netbootSystem.config.system.build.netbootIpxeScript}/netboot.ipxe"
];
}
+18 -18
View File
@@ -1,26 +1,26 @@
{ vars, ... }: { ... }:
{ {
fileSystems."/mnt/raspi" = { fileSystems."/mnt/raspi" = {
device = "raspberrypi.${vars.tailnetDomain}:/home/raspi/raspi"; device = "raspberrypi.tail13f623.ts.net:/home/raspi/raspi";
fsType = "nfs4"; fsType = "nfs4";
options = [ options = [
"nofail" "nofail"
"_netdev" "_netdev"
"noatime" "noatime"
# Don't mount until first access # Don't mount until first access
"x-systemd.automount" "x-systemd.automount"
# Unmount after 10 min idle # Unmount after 10 min idle
"x-systemd.idle-timeout=600" "x-systemd.idle-timeout=600"
# Give the Pi/Tailscale a little time to appear # Give the Pi/Tailscale a little time to appear
"x-systemd.device-timeout=10s" "x-systemd.device-timeout=10s"
# Explicitly use NFSv4.2 if supported # Explicitly use NFSv4.2 if supported
"nfsvers=4.2" "nfsvers=4.2"
]; ];
}; };
} }
+26
View File
@@ -0,0 +1,26 @@
{ pkgs, ... }:
{
# Install the remote builder key on each client host (do not commit private keys):
# sudo install -d -m 0700 /root/.ssh
# sudo install -m 0600 ./nixremote /root/.ssh/nixremote
# sudo ssh -i /root/.ssh/nixremote nixremote@nix-cache nix-store --version
nix.distributedBuilds = true;
nix.buildMachines = [
{
hostName = "nix-cache";
sshUser = "nixremote";
sshKey = "/root/.ssh/nixremote";
system = pkgs.stdenv.hostPlatform.system;
maxJobs = 4;
speedFactor = 2;
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
}
];
nix.settings = {
builders-use-substitutes = true;
max-jobs = "auto";
};
}
@@ -1,7 +1,7 @@
_: { ... }:
{ {
services.logrotate = { services.logrotate = {
enable = true; enable = true;
settings = { settings = {
@@ -15,6 +15,6 @@ _:
copytruncate = true; copytruncate = true;
}; };
}; };
}; };
} }
@@ -1,4 +1,4 @@
{ pkgs, vars, ... }: { pkgs, ... }:
{ {
systemd.services.docker-health-to-gotify = { systemd.services.docker-health-to-gotify = {
@@ -7,9 +7,9 @@
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
# Run as root so it can read /etc/secrets and access docker socket # Run as root so it can read /etc/secrets and access docker socket
# User = "root"; # User = "root";
#EnvironmentFile = "-/etc/secrets/docker-health-alert.env"; #EnvironmentFile = "-/etc/secrets/docker-health-alert.env";
ExecStart = "${pkgs.bash}/bin/bash /home/${vars.primaryUser}/docker/monitoring/gotify/docker-health-to-gotify.sh"; ExecStart = "${pkgs.bash}/bin/bash /home/nixos/docker/monitoring/gotify/docker-health-to-gotify.sh";
StandardOutput = "journal"; StandardOutput = "journal";
StandardError = "journal"; StandardError = "journal";
}; };
+4 -4
View File
@@ -1,5 +1,5 @@
_: { ... }:
{ {
services.rpcbind.enable = true; services.rpcbind.enable = true;
} }
+22
View File
@@ -0,0 +1,22 @@
{ pkgs, ... }:
{
# Create nextcloud cron scheduled task
systemd.services.nextcloud = {
description = "Nextcloud scheduled task";
script = ''${pkgs.bash}/bin/bash ~/docker/services-up.sh --profile nextcloud exec -u 33 nextcloud-webapp php ./cron.php'';
serviceConfig = {
Type = "oneshot";
User = "nixos";
};
path = with pkgs; [ docker docker-compose ];
};
systemd.timers.nextcloud = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*:0/5";
Persistent = true;
};
};
}
+9 -9
View File
@@ -1,12 +1,12 @@
{ pkgs, boot, ... }: { pkgs, boot, ... }:
{ {
boot.postBootCommands = '' boot.postBootCommands = ''
echo "=== STARTING ZPOOL IMPORT ===" echo "=== STARTING ZPOOL IMPORT ==="
${pkgs.zfs_unstable}/bin/zpool import -a -N -d /dev/disk/by-path ${pkgs.zfs_unstable}/bin/zpool import -a -N -d /dev/disk/by-path
${pkgs.zfs_unstable}/bin/zpool status ${pkgs.zfs_unstable}/bin/zpool status
${pkgs.zfs_unstable}/bin/zfs mount -a ${pkgs.zfs_unstable}/bin/zfs mount -a
${pkgs.zfs_unstable}/bin/zfs list ${pkgs.zfs_unstable}/bin/zfs list
echo "=== ZPOOL IMPORT COMPLETE ===" echo "=== ZPOOL IMPORT COMPLETE ==="
''; '';
} }
+9 -14
View File
@@ -1,21 +1,16 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
boot = { boot.supportedFilesystems = [ "zfs" ];
supportedFilesystems = [ "zfs" ]; boot.zfs.forceImportRoot = false;
zfs = { boot.zfs.package = pkgs.zfs_unstable;
forceImportRoot = false; services.zfs = {
package = pkgs.zfs_unstable;
devNodes = "/dev/disk/by-id";
};
};
services.zfs = {
autoScrub.enable = true; autoScrub.enable = true;
autoSnapshot.enable = true; autoSnapshot.enable = true;
trim.enable = true; trim.enable = true;
}; };
#systemd.services.zfs-import-cache.enable = true; #systemd.services.zfs-import-cache.enable = true;
systemd.services.zfs-mount.enable = true; systemd.services.zfs-mount.enable = true;
} boot.zfs.devNodes = "/dev/disk/by-id";
}
@@ -1,4 +1,4 @@
_: { ... }:
{ {
i18n.defaultLocale = "en_AU.UTF-8"; i18n.defaultLocale = "en_AU.UTF-8";
+2 -2
View File
@@ -1,5 +1,5 @@
_: { ... }:
{ {
services.tailscale.enable = true; services.tailscale.enable = true;
} }
+2 -2
View File
@@ -1,4 +1,4 @@
{ vars, ... }: { ... }:
{ {
services.tailscale = { services.tailscale = {
@@ -6,7 +6,7 @@
extraUpFlags = [ extraUpFlags = [
"--advertise-exit-node" "--advertise-exit-node"
"--advertise-routes=${vars.lanCidr}" "--advertise-routes=192.168.2.0/24"
]; ];
}; };
} }
-75
View File
@@ -1,75 +0,0 @@
#!/usr/bin/env bash
# Generates a new machine's SSH host key ahead of installing it, so
# sops-nix has something to derive an age key from before the target
# ever boots.
#
# Why this is needed: sops-nix derives each host's decryption key from
# its own /etc/ssh/ssh_host_ed25519_key at *activation* time, but that
# activation runs before systemd would otherwise generate this key on
# first boot (sshd-keygen is a normal systemd service gated behind
# multi-user.target; activation scripts run earlier than that). Without
# pre-seeding, secrets — including the root/nixos login password — fail
# to decrypt on the machine's very first boot.
#
# This script only touches your admin workstation and this repo's
# .sops.yaml (it never contacts the target machine). Run it, follow the
# printed next steps, then use the resulting key with the auto-install.sh
# prompt (see modules/installer/common.nix) when you actually install the
# new machine.
set -euo pipefail
repo_root="$(cd "$(dirname "$0")/.." && pwd)"
hostname="${1:?usage: scripts/prepare-host-key.sh <hostname> [path-to-nixos-repo]}"
nixos_repo="${2:-$repo_root}"
sops_yaml="${nixos_repo}/.sops.yaml"
if [[ ! -f "$sops_yaml" ]]; then
echo "ERROR: $sops_yaml not found. Pass the nixos repo path as the 2nd argument." >&2
exit 1
fi
keydir="${repo_root}/host-keys"
mkdir -p "$keydir"
keyfile="${keydir}/${hostname}_ssh_host_ed25519_key"
if [[ -f "$keyfile" ]]; then
echo "ERROR: $keyfile already exists. Remove it first if you want to regenerate." >&2
exit 1
fi
nix-shell -p openssh --run "ssh-keygen -t ed25519 -N '' -C '${hostname}' -f '${keyfile}'" >/dev/null
age_pub="$(nix-shell -p ssh-to-age --run "ssh-to-age -i '${keyfile}.pub'")"
cat <<EOF
Generated: ${keyfile}(.pub)
=== 1. Add this line under keys: in ${sops_yaml} ===
- &${hostname} ${age_pub}
=== 2. Add *${hostname} to whichever creation_rules key_groups this host needs ===
(e.g. secrets/common.yaml always; add a per-host secrets/${hostname}.yaml
block too if this host will get its own secrets, same pattern as
nix-cache/server.)
=== 3. Re-encrypt every secrets file you just added it to ===
nix-shell -p sops --run 'sops updatekeys ${nixos_repo}/secrets/common.yaml'
=== 4. Commit + push this repo so the flake build picks up the new recipient ===
=== 5. Get the key onto the installer, one of two ways ===
a) Rebuild the installer image with all host-keys/ baked in (see
docs/auto-installer.md):
NIXOS_HOST_KEYS_DIR="${keydir}" nix build .#iso --impure
(or .#lxc / .#pxe / .#all — --impure is required since host-keys/
is gitignored and flakes can't see it otherwise)
b) Or, for an image already built without keys, scp it in after boot:
scp ${keyfile}{,.pub} root@<target-ip>:/root/host-keys/
Then continue with /etc/auto-install.sh as normal — it checks
/etc/host-keys (baked in) before /root/host-keys (scp'd) and installs
whichever it finds before running nixos-install.
EOF
+20 -47
View File
@@ -5,67 +5,40 @@ sops:
age: age:
- enc: | - enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmaFVBeVp3Zk80TG1OU045 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6NkpZRzJuMFNuV09WamR0
b204QzFYL1psVm1xdlBVYmVIWFpKVnJWbUdvCnJRVGVUbElPYVczeEdkSDU4WGYz SERDN0VSUlNQbkhSem1EeFlxdlhmdUx0S21JCnY1VkRBQTBqcW9JRHpJWEtJSitN
bkliK0dGcitjZnRYUXJQVVpTY2gva0kKLS0tIHBxMDBNYWJrSHAvNlZDWERmbVQ3 dHkyR0I4ckNkWkpGWHAzZGRaZkhJalEKLS0tIHRrU3RhU3UxN3B4NHdLeStuSXQ4
VDFscTRjdGpLUnk5VVdyTjY5MFNPSW8KX5Or/zoixFulaX8ljY4ke3jdhc3Jaw95 anFkRlpMTHowZzJNdnY0MExQcXd4OUEKgbT7uOSFkfEs6t3X6jmGOiC28lDJWF33
4BqrlILGapcOsmWTDkDZBtS81oNvlRnH+xaM2UJSe+nIplNcC+Cl2g== 50f2fZ771ylhHa6WJMetGZ5cwl9r1RCaDiWyJEaqNGe7NqARlhr3EQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
recipient: age10nd382a9klsn2mrs60emdtsxe43pht3a0m9p29phfrhy0wfyt3vsq9r667 recipient: age10nd382a9klsn2mrs60emdtsxe43pht3a0m9p29phfrhy0wfyt3vsq9r667
- enc: | - enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1ZUZ0bXRGVFMzZzg1TzhE YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDamw2ekY0dFZyOGNJelVa
N3kwYjdEV0tmcVdacVJHZUNXRHo1aHhXczFBCm1WcW51K3NSK25uMUFNb3NRbE9J ZGlNK2VNOWtWNTRzU3o2aVJvRi9CME5yS1JFCndlamdFMzVRTnoyVE1ZWXZkTjRR
UE00VWNIclhVZHdPUmlNOXI1aGlhck0KLS0tIFphckVmRXZrTmI5K3BUL3NlMTAv eWdSZzZERHE5VElrOGZvcE4vK0g2d0EKLS0tIG15QlVyalZTK2NpVDdWWU4yUU4r
OG9RTHNEQXVMcXVWZXZnN2NYZ3hraUUKEXrloIgmADuRpa2YN2GIRYT+YN60pxga SkFncC9rZkNKUS9MSmF6WGQwOENwZTQKs5kLNLdQJoZtcsw3zlUWUUtJs0MJnuvw
bLeVDtBYU+KA+2F8S46o43ZmRTE2MXWlMhnZ35uNR4hgE3auKlIziA== o5vziOswRnuXENw//xN01nMDC6Ckzvb+q9GFIyxHLE4j3fT5XdZakg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
recipient: age19gfn2yedg76dmztm4hncr7vf3r3c9j0qpt4rap7y7gersjk4m3ks2lhd0e recipient: age19gfn2yedg76dmztm4hncr7vf3r3c9j0qpt4rap7y7gersjk4m3ks2lhd0e
- enc: | - enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZdXBMY2t6U0VBWjRyWUV2 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyaWpWTGd4TEVoaHg4b3hm
WS9oS0tWUnBQMWhPc3VsTVVKSnZSemxvU0FZCmFWbzFEZEZrMzJxTmpJKy9HY2F5 S1o3VXdkYkZCS0QxcW5hUWxyVjFneE5aSmp3ClNsdEZoMHpPUzI4K3B0ZnBYMlEw
RHBjcUNYZ1R5ZHUxVmhPYjJRQkZyMU0KLS0tIGcvZ2hPQURmanJLRjRaNEJtTml3 MkJyd2NPcGJDZzgvc1EyWFBhNVlGUVEKLS0tIEptYXI2bnJHZVZGR3hSSm1sMlN5
dElTa2hZck1rSG1HcDBVSjZQNjhzT0EKgUylDuQBZkW1Z6AB/EsVbxcippw5XOeY ay8wdUh6TEowL0ZiUWtqbXl3NzhYOVEKW9l4mr+MLhuXA8sgQndaU8NiFeCMcxhG
e+NDtqFixYR1u57+fKVl5dY281kspYIQDCUx1lBZiH7iwUPZWNtEfA== qjKFn+mu2GFbwfZWAy6y/KUd9Ug4H6y3pNHlJMHupTu8v2wZ+3S4EA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
recipient: age1ll6hj5ggruetgjwjfnplpn5xtq35uhlcdflksx3xmnjm6s3uad9sz70jkf recipient: age1ll6hj5ggruetgjwjfnplpn5xtq35uhlcdflksx3xmnjm6s3uad9sz70jkf
- enc: | - enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHYWtBYmU2Qk0vQ2dUQjUy YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxVG13RVVweGpRM04vMWxG
RGs1b1BzVm82Z210MGcrbnhiS0pCVnJzbkFVCnhpZUxSVmZTd0VSM0ZvZ01tM2hP V2hMMnp2Qk5Ub1BZQWNKNXVya3J4NGpreDJrCktqajVPRXdEL1BMU1dMbDhmU01L
QlJ4NUQ0VjBBSXJGR0VScE5zNXhjVjgKLS0tIFZyNVF2a2VPdzhyZ1MzN3dYa0xx UlQvRVQvcEFUZVZ5Umc3Y0hMUWNLVFEKLS0tIFgzRnF1RHdQdktDVjROSURYYTdx
U0tqTWZNSDdHU3Z5UHNBbGR6aFZ1MDQK7z0OC0yazekxpLmiKFuqWZm1rWMZqpXb NjAydjVuV1VCOGZoVFdTZmw1YmJ0eEEKN9KRGegafu1sjHlhyn4KCMPPAKxsSZLc
FGnZFMDdEwB5wTeiy4LCXS70zyr5eVT7KPeK25EG6pXQ4qqKZ12CyA== QJkei1ZQ0AVgC2QfCVEXonMOrs45nCIplG+uyER9khZyyjKObWk1pA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
recipient: age120le4a5l8dh3lyfgvmj3d9ksmej6ajs5mer5y7r0vfg3x9fn69dqf8xgzu recipient: age120le4a5l8dh3lyfgvmj3d9ksmej6ajs5mer5y7r0vfg3x9fn69dqf8xgzu
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqSG5NemtzUXlhelpvblFl
TldjUGVtZFFXWGM5ei9EN3V5N2ZLY0VRV0RJCnFNN1lVNmhWckFWbUVJd0grR2Ja
MmdYazZLUVFpelUyMFhta3dGSEc2Mm8KLS0tIHl4TlhhVFVOcmkxaHpKVWlrdEJx
VlBQazd5MG1yc3E0TzQrd3FmWG8wd00K8+cAm4oWVraERb8i8EurAnsR/L085uPR
zzIZEYW6hHxf9Ah9vMzM+3KIsnnS0Gr5QT8ATzpd8huXCqPNiveDFQ==
-----END AGE ENCRYPTED FILE-----
recipient: age1qz9d4ka4xgexujyd247s7lp737sulp5fhxl5d65fj2ykvc4j4edqrsdks8
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQdDdQUEh6ejg3UG1LMi8w
bTJacGZQY3dUVEtJY3NGeWpxYWRITkZpN2swClVmb2F5N0phYzRXVG1RY1NsUm52
OWVLY3FJU0JXcGFVZDJGdVJ0dVhBN0UKLS0tIEl2b3JjV2JaS0crMnRpZElGdDZS
MDFyelRvcUsyUDdtai9IYnpHK3g2L2cKlvZloUKACDy9OyRI7ruPUjYqFENXzcVI
amFHFTbEGKVWIPwDjEwsMT+S4bHBkNWyny5dD5CrBpk7fiyQ+5U8+Q==
-----END AGE ENCRYPTED FILE-----
recipient: age120whqj96g26lsgy4udvgsn8dc9lumh8jeu3a564fx79rjr5lxffqmrljuu
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTZnZIa2xXM3RIYk1tbitC
NlRTeXFib3JDdXdhR01ZdUl6Z09vWmllRGxBCnpPalo4K0JhRlNpQ2d0b2RNcjUx
K3FRaXdMVHZud2FKRkw4UDREL1NrMDgKLS0tIE5CZDBHRXNscG9JK1hvWlZPVjJy
d0d2VnE4bXd6MGNPVzVUdFdocDYzcHcKW2Hs5oBO5ooc/uqWV/TOjq1xsxFR204s
GRtFUOg9tfglk3TcQbgZV0/pYlBJYzgb7iZD0qVe4XYj68q1A1bPwQ==
-----END AGE ENCRYPTED FILE-----
recipient: age164px2a8e48ptsf9ngtan38aa6jls4jdl26mzrgzf6sn3vcvt49hqjrgr8w
lastmodified: "2026-07-19T02:30:40Z" lastmodified: "2026-07-19T02:30:40Z"
mac: ENC[AES256_GCM,data:UiL3VMDF6rq4Nr87KspcDx434q3tfNXeb5pwH2O+4ssNQ6xzcYDdzXBnhAY3zLBsqPMKrvHBd4Ot/gEMcq3FMIVe7Q6p9yWKpep66KZ/yWEhAlwIVhD79Oj8VS+1CHKjf25zpRdhZorp04oeFQQd9VfjJB4EE/Q1aVbwTGlpIic=,iv:i/0conaFgFia+wzNTdUL6tlSTw35HTK3Ap1Sr5RGHf8=,tag:ULbz5FllShA/JjlSRdxA0g==,type:str] mac: ENC[AES256_GCM,data:UiL3VMDF6rq4Nr87KspcDx434q3tfNXeb5pwH2O+4ssNQ6xzcYDdzXBnhAY3zLBsqPMKrvHBd4Ot/gEMcq3FMIVe7Q6p9yWKpep66KZ/yWEhAlwIVhD79Oj8VS+1CHKjf25zpRdhZorp04oeFQQd9VfjJB4EE/Q1aVbwTGlpIic=,iv:i/0conaFgFia+wzNTdUL6tlSTw35HTK3Ap1Sr5RGHf8=,tag:ULbz5FllShA/JjlSRdxA0g==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
+10 -19
View File
@@ -3,31 +3,22 @@ sops:
age: age:
- enc: | - enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDbHd1Y1dpa2ZiQ2E1bXRP YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkb29VM3haQ0c0WDY0STVn
SnkrWHI0V2U1eGFKY0RZamZQQjluS0hGeENZCmduUFQyd1Q5RkZGMGFoenJhNmZh L1ZyOUROSnR6ZjZZZWc1VGFFNVp6bWxCV3hZCnlGTC9CbEtIM3MvSGJQaStEbzJ0
VmZ2OStNaFpJejFxQ2JUZXFpNThaMncKLS0tIEhJdGdQeXEzb25Nbk5YZktCWVUz eWVhY2l6UHNDRTYxdEpkd003WXFia2MKLS0tIHcxU3FPYTVuZ0RqZTZTT1RvZnN0
NUJDUWRoTkd5R2pFblZjS0NSbVR5dkkKDYeW+zRpha04/CasFM91K6v1PpkNGHRu OGlQM3B2R0l4MHhWNXBBWmpiOEVxK1EK8kxh3ikKL6Fw2am3r7lPGpB0fCqzEukO
qAoKs9KSg9VxS7ya8RuLmylKRdpPkupm/8SXIJvQuCXp5LWmNJ4zkA== NU10Cbf38Bd+fybRbBnvRuu9To1FOf+KU3iKbsuWmZn4KJn4Ajcbhw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
recipient: age10nd382a9klsn2mrs60emdtsxe43pht3a0m9p29phfrhy0wfyt3vsq9r667 recipient: age10nd382a9klsn2mrs60emdtsxe43pht3a0m9p29phfrhy0wfyt3vsq9r667
- enc: | - enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4UktiUUdmd092bnZMdFMz YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCNWRhK2QrV1ZibllqY25Y
Q05xVlhnNzhPZUY4TjF5bjRCbklacTdJd1RBCnJ4bEVMaWRLZExIUFVEUDBXTnlV ZVRPLzZ0TE82TWZ4L0w5ZmFPTDBtT0poODBnCkE5TWhJcXJjNkdva1hYZ3loeVdq
MDU4WUk5VlJjdlhVUVpzZXlnWHhqTjQKLS0tIE9iclhGVElPcU9OLzF0bEVjMjVp UlBXWHZpRUpMSGhPU0FIRi9JMEtTdGMKLS0tIE9yUk5Ebjk2MEFtNEkyR3RDcU51
YzlQTGFYZEhLdTk3N3ZramVjVGRXREUKjOjqO/jX5iEKN43WiJ8qS/1mDfxdj8uO ZVMwNnNRMlBMVVFlamU1U3JQSy9UT00KJZdEpRHuj4Dp1dGwP1z4xi9oddQOrQj2
K7Yyc/Yj0qMvGwLNzphjmbT29P7dXk4Ht4TedqCd+8DfhpOgLVIaSA== qheEN/IlifVdZDpvlLUc8jgLzd/TO5EeEhVqfbdrlua8FHly29oTNw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
recipient: age120le4a5l8dh3lyfgvmj3d9ksmej6ajs5mer5y7r0vfg3x9fn69dqf8xgzu recipient: age120le4a5l8dh3lyfgvmj3d9ksmej6ajs5mer5y7r0vfg3x9fn69dqf8xgzu
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjaXpvQU9yRUc3ektPMmU5
Q0xLWU9mYXVOeTVBNGNsZzJPa1lkVlRUZHlvClhoSVV6YjB1Q3pTTzVvNFlNYkU4
Y2RrbFk5SUFKSDVjeFU0Wlc2aGFUMFUKLS0tIDlVeXM4WWRUakg4Zk5mcjdJL3VC
S1k5eFBpVnREQlZwYllpeTNhWW5GS1EKi2sMwyJJ0D8acjCZmxlcwdU1sglBuxR7
2SEMsctdGC+5E3ilPXvPpZ5RONZHbXxn6kQRBlBv6AJERpGDzsfgfA==
-----END AGE ENCRYPTED FILE-----
recipient: age164px2a8e48ptsf9ngtan38aa6jls4jdl26mzrgzf6sn3vcvt49hqjrgr8w
lastmodified: "2026-07-19T02:30:40Z" lastmodified: "2026-07-19T02:30:40Z"
mac: ENC[AES256_GCM,data:7+FeT6aeCGn+JFBXbPO0qP4BJ1nHPSennewv1kWkG+hOTIqs1ymuswUK1Hyfi6Z9h2umFX9HvK+o3qtmYvk6k7BUNe6w6QUHTNwm6lmNqrb7sgAE3iFVI2p9m14NGhgoTfnXx1M4JIZ1iuNYhCukpENI4+svIe+r7x5YeE5Evac=,iv:4AKAPI6upyAvHBr8BLWX7R/NupmJdcXdqiN8e0ZQ3ls=,tag:TkpfpCaLhn+Mx5cQZZuMdA==,type:str] mac: ENC[AES256_GCM,data:7+FeT6aeCGn+JFBXbPO0qP4BJ1nHPSennewv1kWkG+hOTIqs1ymuswUK1Hyfi6Z9h2umFX9HvK+o3qtmYvk6k7BUNe6w6QUHTNwm6lmNqrb7sgAE3iFVI2p9m14NGhgoTfnXx1M4JIZ1iuNYhCukpENI4+svIe+r7x5YeE5Evac=,iv:4AKAPI6upyAvHBr8BLWX7R/NupmJdcXdqiN8e0ZQ3ls=,tag:TkpfpCaLhn+Mx5cQZZuMdA==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
-44
View File
@@ -1,44 +0,0 @@
{
# Network / domains
lanDomain = "gitea.lan.ddnsgeek.com"; # Gitea/DDNS domain
homeDomain = "sweet.home"; # base LAN domain for service subdomains (pve., docker.)
tailnetDomain = "tail13f623.ts.net"; # Tailscale MagicDNS suffix
lanCidr = "192.168.2.0/24"; # LAN subnet
pxeServerIp = "192.168.2.247"; # pxe-boot host's LAN IP
pbsIp = "192.168.2.108"; # Proxmox Backup Server LAN IP
# Cross-host references (LAN hostnames/users other hosts reach over the network)
nixCacheHost = "nix-cache"; # substituter/remote-builder hostname
nfsServerHost = "server"; # NFS export source hostname
dockerHost = "docker"; # docker-compose stack host
remoteBuilderUser = "nixremote"; # remote builder SSH user
# Public keys authorized to SSH in as remoteBuilderUser on the nix-cache
# host (modules/nix-cache/server.nix) — one per client host that's allowed
# to use it as a distributed builder.
remoteBuilderAuthorizedKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFDEA1S2ikpObREgbP5uVBWMxIOGbY8B+Wx7VTZK1m6t root@server"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPAYIT9ormlmxZ0SziyDQaUntnKI8HK9/s3Qac1ZKjP2 root@docker"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKKKzoEPl/ZW9KBRHBcp6/ThOngGpwMv5EhkTlgC4aDf root@nixos"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIGtOWOCS+ImHc7NehguoyD7PbonGosKMZqc9+QR3v/h root@nixos"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHxXTQxFnArK5HXG7czeoybZebCGfxpUdusJkPn+BCSp root@server"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICMJhrfFayLBG+gWtO6oAvgambw5nWWgztiTFEaaaVRH debian@surface"
];
# Admin SSH public key, authorized on the primary user of every host and
# the installer image's nixos/root users.
adminSshKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCq/Q5LvIXlZwO2kdeAN5nLGZ59nZB7JHYMEszHxmNtGMzv1lM31jiPNsr0z2EKVZhE7OOfa2IF9rhWYD7JUA9G0yzdZ4WTXFNGVVOJoOVH6vAF3XCxoVilOEwTc7h2Wiy+rzd0B28/3spffzQQWJhY6GRQVa8j+6xAGF60Fcvl1vLosYT9Bn2ZbK4TCWOwAn2jqXIieGpZdn/UNZbGOeKRiCvhktDfMAzuQzN/9jMu/oF4pkPn2X1UrsQdNlvp0Ci8md612MozIpncQJyAF1ADhunr3sMx0isUXiqD29R5DS4TftpekqLNLak+zcxFa8N7DcRNp3DcKfJvyTkwQrR4r+b7lFLYOLHLagSso9CzeW/paAS2q9I5SBm/2DtE1diLLg2jZikYcstsu/G5RgvbzbKqjiaMwTdXC3AMvDxQrs7U5pDRZFzoofG3cpODbTm+uy3m0kP70z0M1K45UbDG0p+itnTu9x40JbQEgefbx38AItNvAIx1A8HO4I1VX28= wayne@stream";
# System
timeZone = "Australia/Brisbane";
primaryUser = "nixos"; # main interactive user on every host
# Storage
storageRoot = "/tank"; # ZFS pool root on `server`
# Well-known ports for LAN services referenced from multiple hosts
beszelHubPort = 8090;
pveWebPort = 8006;
pbsWebPort = 8007;
}