Centralize shared values into variables.nix

One file (variables.nix) holding every value that was previously
hardcoded and repeated across modules: LAN domain/CIDR, home/tailnet
domains, cross-host references (nix-cache substituter hostname, NFS
server hostname, remote-builder user), PXE/PBS IPs, timezone, and the
primary username.

Wired in via flake.nix's specialArgs (and home-manager's
extraSpecialArgs for the two home.nix files), so any module picks it
up by just adding `vars` to its function arguments — no explicit
import needed. Two hosts (nix-cache, server) now derive their own
networking.hostName from the same variable other hosts use to reach
them, so there's exactly one place to change either identifier.

Purely mechanical: every substituted value matches what was already
there, confirmed by identical toplevel .drv paths for all 17 targets
before and after.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-19 14:51:37 +10:00
co-authored by Claude Sonnet 5
parent 71d052e737
commit eadb1e35ce
20 changed files with 219 additions and 191 deletions
+1
View File
@@ -46,6 +46,7 @@ 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`) |
+3 -1
View File
@@ -23,6 +23,7 @@
let let
system = "x86_64-linux"; system = "x86_64-linux";
inherit (nixpkgs) lib; inherit (nixpkgs) lib;
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
@@ -46,6 +47,7 @@
home-manager = { home-manager = {
useGlobalPkgs = true; useGlobalPkgs = true;
useUserPackages = true; useUserPackages = true;
extraSpecialArgs = { inherit vars; };
users.nixos = import homeFile; users.nixos = import homeFile;
}; };
} }
@@ -53,7 +55,7 @@
./modules/nix-cache/client.nix ./modules/nix-cache/client.nix
./modules/remote-builder-client.nix ./modules/remote-builder-client.nix
]; ];
specialArgs = { inherit inputs; }; specialArgs = { inherit inputs vars; };
}; };
# Generated platform x build-type matrix. pxe-boot has no linode # Generated platform x build-type matrix. pxe-boot has no linode
+2 -2
View File
@@ -1,7 +1,7 @@
{ config, ... }: { config, vars, ... }:
{ {
networking.hostName = "nix-cache"; networking.hostName = vars.nixCacheHost;
sops.secrets."beszel-token".sopsFile = ../../secrets/nix-cache.yaml; sops.secrets."beszel-token".sopsFile = ../../secrets/nix-cache.yaml;
sops.templates."nix-cache-beszel.env".content = '' sops.templates."nix-cache-beszel.env".content = ''
+49 -49
View File
@@ -1,16 +1,16 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, vars, ... }:
{ {
imports = [ imports = [
../../modules/common/aliases.nix ../../modules/common/aliases.nix
]; ];
home.username = "nixos"; # your actual username home.username = vars.primaryUser;
home.homeDirectory = "/home/nixos"; home.homeDirectory = "/home/${vars.primaryUser}";
home.stateVersion = "25.05"; # match your NixOS stateVersion home.stateVersion = "25.05"; # match your NixOS stateVersion
programs.home-manager.enable = true; # mandatory to activate HM programs.home-manager.enable = true; # mandatory to activate HM
# Optional: packages # Optional: packages
home.packages = with pkgs; [ home.packages = with pkgs; [
@@ -18,7 +18,7 @@
vim vim
tmux tmux
nextcloud-client nextcloud-client
# vscode # vscode
chromium chromium
]; ];
@@ -29,51 +29,51 @@
# 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 = { home.file = {
".local/share/applications/proxmox-chromium-app.desktop".text = '' ".local/share/applications/proxmox-chromium-app.desktop".text = ''
[Desktop Entry] [Desktop Entry]
Type=Application Type=Application
Name=Proxmox (Chromium) Name=Proxmox (Chromium)
Exec=chromium --app=https://pve.sweet.home:8006 --window-size=1920,1080 --window-position=0,0 Exec=chromium --app=https://pve.${vars.homeDomain}:8006 --window-size=1920,1080 --window-position=0,0
Icon=/home/nixos/.local/share/icons/proxmox.png Icon=${config.home.homeDirectory}/.local/share/icons/proxmox.png
Terminal=false Terminal=false
Categories=Hypervisor; Categories=Hypervisor;
StartupWMClass=PVE StartupWMClass=PVE
''; '';
".local/share/applications/pbs-chromium-app.desktop".text = '' ".local/share/applications/pbs-chromium-app.desktop".text = ''
[Desktop Entry] [Desktop Entry]
Type=Application Type=Application
Name=Proxmox Backup Server (Chromium) Name=Proxmox Backup Server (Chromium)
Exec=chromium --app=https://192.168.2.108:8007 --window-size=1920,1080 --window-position=0,0 Exec=chromium --app=https://${vars.pbsIp}:8007 --window-size=1920,1080 --window-position=0,0
Icon=/home/nixos/.local/share/icons/proxmox.png Icon=${config.home.homeDirectory}/.local/share/icons/proxmox.png
Terminal=false Terminal=false
Categories=backup; Categories=backup;
''; '';
".local/share/applications/proxmox-firefox-app.desktop".text = '' ".local/share/applications/proxmox-firefox-app.desktop".text = ''
[Desktop Entry] [Desktop Entry]
Type=Application Type=Application
Name=Proxmox (Firefox) Name=Proxmox (Firefox)
Exec=firefox --new-instance https://pve.sweet.home:8006 --profile ProxmoxWebApp --window-size=1920,1080 --class ProxmoxWebApp Exec=firefox --new-instance https://pve.${vars.homeDomain}:8006 --profile ProxmoxWebApp --window-size=1920,1080 --class ProxmoxWebApp
Icon=/home/nixos/.local/share/icons/proxmox.png Icon=${config.home.homeDirectory}/.local/share/icons/proxmox.png
Terminal=false Terminal=false
Categories=Hypervisor; Categories=Hypervisor;
StartupWMClass=PVE StartupWMClass=PVE
''; '';
".local/share/applications/pbs-firefox-app.desktop".text = '' ".local/share/applications/pbs-firefox-app.desktop".text = ''
[Desktop Entry] [Desktop Entry]
Type=Application Type=Application
Name=Proxmox Backup Server (Firefox) Name=Proxmox Backup Server (Firefox)
Exec=firefox --new-window https://192.168.2.108:8007 --profile PbsWebApp --window-size=1920,1080 --class PbsWebApp Exec=firefox --new-window https://${vars.pbsIp}:8007 --profile PbsWebApp --window-size=1920,1080 --class PbsWebApp
Icon=/home/nixos/.local/share/icons/proxmox.png Icon=${config.home.homeDirectory}/.local/share/icons/proxmox.png
Terminal=false Terminal=false
Categories=backup; Categories=backup;
StartupWMClass=PBS StartupWMClass=PBS
''; '';
}; };
} }
+3 -3
View File
@@ -1,7 +1,7 @@
{ config, ... }: { config, vars, ... }:
{ {
networking.hostName = "server"; networking.hostName = vars.nfsServerHost;
networking.hostId = "6689f93e"; networking.hostId = "6689f93e";
sops.secrets."beszel-token".sopsFile = ../../secrets/server.yaml; sops.secrets."beszel-token".sopsFile = ../../secrets/server.yaml;
@@ -13,7 +13,7 @@
#DOCKER_HOST = "tcp://docker-socket-proxy:2375"; #DOCKER_HOST = "tcp://docker-socket-proxy:2375";
#HUB_URL = "http://docker.sweet.home:8090"; #HUB_URL = "http://docker.sweet.home:8090";
KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFPR9kwtC4TAeTRu46A7+opZsYpxqkRJ+x/ZyB2GWCeG"; KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFPR9kwtC4TAeTRu46A7+opZsYpxqkRJ+x/ZyB2GWCeG";
EXTRA_FILESYSTEMS = "/tank/docker/volumes"; EXTRA_FILESYSTEMS = "${vars.storageRoot}/docker/volumes";
LOG_LEVEL = "debug"; LOG_LEVEL = "debug";
}; };
services.beszel.agent.environmentFile = config.sops.templates."server-beszel.env".path; services.beszel.agent.environmentFile = config.sops.templates."server-beszel.env".path;
+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://docker.sweet.home:8090"; HUB_URL = "http://docker.${vars.homeDomain}:8090";
}; };
} }
+2 -2
View File
@@ -1,10 +1,10 @@
{ config, lib, pkgs, inputs, ... }: { config, lib, pkgs, inputs, vars, ... }:
let let
pxeRoot = "/srv/pxe"; pxeRoot = "/srv/pxe";
httpRoot = "${pxeRoot}/http"; httpRoot = "${pxeRoot}/http";
tftpRoot = "${pxeRoot}/tftp"; tftpRoot = "${pxeRoot}/tftp";
pxeBaseUrl = "http://192.168.2.247"; pxeBaseUrl = "http://${vars.pxeServerIp}";
bootIpxe = pkgs.writeText "boot.ipxe" '' bootIpxe = pkgs.writeText "boot.ipxe" ''
#!ipxe #!ipxe
+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 = [ "tank" ]; boot.zfs.extraPools = [ (lib.removePrefix "/" vars.storageRoot) ];
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 = ''
/tank/docker/config 192.168.2.0/24(rw,sync,no_subtree_check,no_root_squash) ${vars.storageRoot}/docker/config ${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/volumes ${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/databases ${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}/docker/nextcloud-data ${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) ${vars.storageRoot}/raspi/volumes ${vars.lanCidr}(rw,sync,no_subtree_check,no_root_squash)
''; '';
}; };
+3 -3
View File
@@ -1,4 +1,4 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, vars, ... }:
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://gitea.lan.ddnsgeek.com/beatzaplenty/nixos.git#$(cat /etc/flake-target) --flake git+https://${vars.lanDomain}/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://gitea.lan.ddnsgeek.com/beatzaplenty/nixos.git#$(cat /etc/flake-target) --flake git+https://${vars.lanDomain}/beatzaplenty/nixos.git#$(cat /etc/flake-target)
''; '';
in in
{ {
+19 -18
View File
@@ -1,29 +1,30 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, vars, ... }:
{ {
imports = imports =
[ # Include the results of the hardware scan. [
# ./hardware-configuration.nix # Include the results of the hardware scan.
# ./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.
# Set your time zone. # Set your time zone.
time.timeZone = "Australia/Brisbane"; time.timeZone = vars.timeZone;
# 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
@@ -47,13 +48,13 @@
!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.nixos = { users.users.${vars.primaryUser} = {
isNormalUser = true; isNormalUser = true;
extraGroups = [ "wheel" ]; # Enable sudo for the user. extraGroups = [ "wheel" ]; # Enable sudo for the user.
packages = with pkgs; [ packages = with pkgs; [
@@ -61,8 +62,8 @@ users.users.root = {
]; ];
hashedPasswordFile = config.sops.secrets."nixos-hashedPassword".path; hashedPasswordFile = config.sops.secrets."nixos-hashedPassword".path;
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCq/Q5LvIXlZwO2kdeAN5nLGZ59nZB7JHYMEszHxmNtGMzv1lM31jiPNsr0z2EKVZhE7OOfa2IF9rhWYD7JUA9G0yzdZ4WTXFNGVVOJoOVH6vAF3XCxoVilOEwTc7h2Wiy+rzd0B28/3spffzQQWJhY6GRQVa8j+6xAGF60Fcvl1vLosYT9Bn2ZbK4TCWOwAn2jqXIieGpZdn/UNZbGOeKRiCvhktDfMAzuQzN/9jMu/oF4pkPn2X1UrsQdNlvp0Ci8md612MozIpncQJyAF1ADhunr3sMx0isUXiqD29R5DS4TftpekqLNLak+zcxFa8N7DcRNp3DcKfJvyTkwQrR4r+b7lFLYOLHLagSso9CzeW/paAS2q9I5SBm/2DtE1diLLg2jZikYcstsu/G5RgvbzbKqjiaMwTdXC3AMvDxQrs7U5pDRZFzoofG3cpODbTm+uy3m0kP70z0M1K45UbDG0p+itnTu9x40JbQEgefbx38AItNvAIx1A8HO4I1VX28= wayne@stream" "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"
]; ];
}; };
+30 -29
View File
@@ -1,21 +1,22 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, vars, ... }:
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.username = "nixos"; # your actual username home.username = vars.primaryUser;
home.homeDirectory = "/home/nixos"; home.homeDirectory = "/home/${vars.primaryUser}";
home.stateVersion = "25.11"; # match your NixOS stateVersion home.stateVersion = "25.11"; # match your NixOS stateVersion
programs.home-manager.enable = true; # mandatory to activate HM programs.home-manager.enable = true; # mandatory to activate HM
programs.bash.enable = true; 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
@@ -35,31 +36,31 @@ programs.bash.enable = true;
home.sessionVariables = { home.sessionVariables = {
EDITOR = "nano"; EDITOR = "nano";
}; };
# systemd.user.services.mount-proxmox-iso = { # systemd.user.services.mount-proxmox-iso = {
# Unit = { # Unit = {
# Description = "Mount Proxmox ISO dir via SSHFS"; # Description = "Mount Proxmox ISO dir via SSHFS";
# After = [ "network-online.target" ]; # After = [ "network-online.target" ];
# Wants = [ "network-online.target" ]; # Wants = [ "network-online.target" ];
# }; # };
# Service = { # Service = {
# Type = "simple"; # Type = "simple";
# ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p ${localMount}"; # 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}"; # 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}"; # ExecStop = "${pkgs.fuse3}/bin/fusermount3 -u ${localMount}";
# Restart = "on-failure"; # Restart = "on-failure";
# }; # };
# Install = { # Install = {
# WantedBy = [ "default.target" ]; # 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;
# }; # };
} }
+8 -8
View File
@@ -1,8 +1,8 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, vars, ... }:
{ {
fileSystems."/mnt/docker/config" = { fileSystems."/mnt/docker/config" = {
device = "server:/tank/docker/config"; device = "${vars.nfsServerHost}:${vars.storageRoot}/docker/config";
fsType = "nfs"; fsType = "nfs";
options = [ options = [
@@ -14,7 +14,7 @@
}; };
fileSystems."/mnt/docker/databases" = { fileSystems."/mnt/docker/databases" = {
device = "server:/tank/docker/databases"; device = "${vars.nfsServerHost}:${vars.storageRoot}/docker/databases";
fsType = "nfs"; fsType = "nfs";
options = [ options = [
@@ -26,7 +26,7 @@
}; };
fileSystems."/mnt/docker/volumes" = { fileSystems."/mnt/docker/volumes" = {
device = "server:/tank/docker/volumes"; device = "${vars.nfsServerHost}:${vars.storageRoot}/docker/volumes";
fsType = "nfs"; fsType = "nfs";
options = [ options = [
@@ -37,8 +37,8 @@
]; ];
}; };
fileSystems."/mnt/nextcloud-data" = { fileSystems."/mnt/nextcloud-data" = {
device = "server:/tank/docker/nextcloud-data"; device = "${vars.nfsServerHost}:${vars.storageRoot}/docker/nextcloud-data";
fsType = "nfs"; fsType = "nfs";
options = [ options = [
@@ -49,8 +49,8 @@
]; ];
}; };
fileSystems."/mnt/raspi-backup" = { fileSystems."/mnt/raspi-backup" = {
device = "server:/tank/raspi/volumes"; device = "${vars.nfsServerHost}:${vars.storageRoot}/raspi/volumes";
fsType = "nfs"; fsType = "nfs";
options = [ options = [
+2 -2
View File
@@ -1,9 +1,9 @@
{ ... }: { vars, ... }:
{ {
nix.settings = { nix.settings = {
substituters = [ substituters = [
"http://nix-cache" "http://${vars.nixCacheHost}"
"https://cache.nixos.org/" "https://cache.nixos.org/"
]; ];
trusted-public-keys = [ trusted-public-keys = [
+13 -11
View File
@@ -1,4 +1,4 @@
{ config, pkgs, ... }: { config, pkgs, vars, ... }:
{ {
# Generate the binary cache key pair on the nix-cache host: # Generate the binary cache key pair on the nix-cache host:
@@ -17,7 +17,7 @@
services.nginx = { services.nginx = {
enable = true; enable = true;
recommendedProxySettings = true; recommendedProxySettings = true;
virtualHosts."nix-cache" = { virtualHosts.${vars.nixCacheHost} = {
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}";
}; };
@@ -26,11 +26,11 @@
networking.firewall.allowedTCPPorts = [ 80 ]; networking.firewall.allowedTCPPorts = [ 80 ];
users.groups.nixremote = {}; users.groups.${vars.remoteBuilderUser} = { };
users.users.nixremote = { users.users.${vars.remoteBuilderUser} = {
isSystemUser = true; isSystemUser = true;
group = "nixremote"; group = vars.remoteBuilderUser;
createHome = true; createHome = true;
home = "/var/lib/nixremote"; home = "/var/lib/nixremote";
shell = pkgs.bashInteractive; shell = pkgs.bashInteractive;
@@ -38,17 +38,19 @@
# openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA... client@host" ]; # openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA... client@host" ];
# #
# Avoid absolute keyFiles paths here because they break pure flake evaluation. # Avoid absolute keyFiles paths here because they break pure flake evaluation.
openssh.authorizedKeys.keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFDEA1S2ikpObREgbP5uVBWMxIOGbY8B+Wx7VTZK1m6t root@server" openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPAYIT9ormlmxZ0SziyDQaUntnKI8HK9/s3Qac1ZKjP2 root@docker" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFDEA1S2ikpObREgbP5uVBWMxIOGbY8B+Wx7VTZK1m6t root@server"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKKKzoEPl/ZW9KBRHBcp6/ThOngGpwMv5EhkTlgC4aDf root@nixos" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPAYIT9ormlmxZ0SziyDQaUntnKI8HK9/s3Qac1ZKjP2 root@docker"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIGtOWOCS+ImHc7NehguoyD7PbonGosKMZqc9+QR3v/h root@nixos" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKKKzoEPl/ZW9KBRHBcp6/ThOngGpwMv5EhkTlgC4aDf root@nixos"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHxXTQxFnArK5HXG7czeoybZebCGfxpUdusJkPn+BCSp root@server"]; "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIGtOWOCS+ImHc7NehguoyD7PbonGosKMZqc9+QR3v/h root@nixos"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHxXTQxFnArK5HXG7czeoybZebCGfxpUdusJkPn+BCSp root@server"
];
}; };
services.openssh.enable = true; services.openssh.enable = true;
nix.settings = { nix.settings = {
trusted-users = [ "root" "nixremote" ]; trusted-users = [ "root" vars.remoteBuilderUser ];
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;
+18 -18
View File
@@ -1,26 +1,26 @@
{ ... }: { vars, ... }:
{ {
fileSystems."/mnt/raspi" = { fileSystems."/mnt/raspi" = {
device = "raspberrypi.tail13f623.ts.net:/home/raspi/raspi"; device = "raspberrypi.${vars.tailnetDomain}:/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"
]; ];
}; };
} }
+4 -4
View File
@@ -1,4 +1,4 @@
{ pkgs, ... }: { pkgs, vars, ... }:
{ {
# Install the remote builder key on each client host (do not commit private keys): # Install the remote builder key on each client host (do not commit private keys):
@@ -9,9 +9,9 @@
nix.buildMachines = [ nix.buildMachines = [
{ {
hostName = "nix-cache"; hostName = vars.nixCacheHost;
sshUser = "nixremote"; sshUser = vars.remoteBuilderUser;
sshKey = "/root/.ssh/nixremote"; sshKey = "/root/.ssh/${vars.remoteBuilderUser}";
system = pkgs.stdenv.hostPlatform.system; system = pkgs.stdenv.hostPlatform.system;
maxJobs = 4; maxJobs = 4;
speedFactor = 2; speedFactor = 2;
+3 -3
View File
@@ -1,4 +1,4 @@
{ pkgs, ... }: { pkgs, vars, ... }:
{ {
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/nixos/docker/monitoring/gotify/docker-health-to-gotify.sh"; ExecStart = "${pkgs.bash}/bin/bash /home/${vars.primaryUser}/docker/monitoring/gotify/docker-health-to-gotify.sh";
StandardOutput = "journal"; StandardOutput = "journal";
StandardError = "journal"; StandardError = "journal";
}; };
+16 -16
View File
@@ -1,22 +1,22 @@
{ pkgs, ... }: { pkgs, vars, ... }:
{ {
# Create nextcloud cron scheduled task # Create nextcloud cron scheduled task
systemd.services.nextcloud = { systemd.services.nextcloud = {
description = "Nextcloud scheduled task"; description = "Nextcloud scheduled task";
script = ''${pkgs.bash}/bin/bash ~/docker/services-up.sh --profile nextcloud exec -u 33 nextcloud-webapp php ./cron.php''; script = ''${pkgs.bash}/bin/bash ~/docker/services-up.sh --profile nextcloud exec -u 33 nextcloud-webapp php ./cron.php'';
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
User = "nixos"; User = vars.primaryUser;
};
path = with pkgs; [ docker docker-compose ];
}; };
path = with pkgs; [ docker docker-compose ];
};
systemd.timers.nextcloud = { systemd.timers.nextcloud = {
wantedBy = [ "timers.target" ]; wantedBy = [ "timers.target" ];
timerConfig = { timerConfig = {
OnCalendar = "*:0/5"; OnCalendar = "*:0/5";
Persistent = true; Persistent = 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=192.168.2.0/24" "--advertise-routes=${vars.lanCidr}"
]; ];
}; };
} }
+21
View File
@@ -0,0 +1,21 @@
{
# 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
remoteBuilderUser = "nixremote"; # remote builder SSH user
# System
timeZone = "Australia/Brisbane";
primaryUser = "nixos"; # main interactive user on every host
# Storage
storageRoot = "/tank"; # ZFS pool root on `server`
}