refactor: move host configs under hosts/{jupiter,vps}

- git-mv jupiter/ vps/ into hosts/; fix ../ -> ../../ for common/services/secrets
- flake.nix + deploy point at hosts/<config>/
- README structure updated
- verified: jupiter/vps/vbox all eval
This commit is contained in:
erik
2026-07-13 19:34:27 +02:00
parent fb782cb9fe
commit b6c393ff98
12 changed files with 47 additions and 38 deletions
+19 -10
View File
@@ -5,16 +5,25 @@ Flake-based NixOS config. Host: `jupiter` (ZimaBlade, NAS + services).
## Structure ## Structure
``` ```
flake.nix # inputs (nixpkgs, disko) + nixosConfigurations flake.nix # inputs + nixosConfigurations (jupiter, vps, kexec, ...)
jupiter/configuration.nix # real host: imports + bootloader + data mount common.nix # shared base: user, ssh, nix, firewall, timezone
jupiter/disk-config.nix # disko: OS-disk partitions + filesystems services/ # one reusable module per service
jupiter/hardware-configuration.nix # PLACEHOLDER — kernel modules, regenerate on target samba.nix avahi.nix audiobookshelf.nix containers.nix caddy.nix tailscale.nix
jupiter/services.nix # shared: users, ssh, samba, containers, caddy hosts/
jupiter/vm.nix # VirtualBox test image (jupiter-vbox) jupiter/ # ZimaBlade NAS
configuration.nix # host bits + imports common + the services it runs
disk-config.nix # disko: eMMC partitions
hardware-configuration.nix
secrets.nix # sops-nix wiring
vm.nix # VirtualBox test image (jupiter-vbox)
vps/ # netcup public reverse proxy + tailnet node
configuration.nix disk-config.nix hardware-configuration.nix secrets.nix
secrets/ # age-encrypted sops files (jupiter.yaml, vps.yaml)
scripts/ # deploy, edit_secrets
``` ```
Two configs from one service definition: `jupiter` (real host, disko-partitioned) Hosts compose by importing `common.nix` + whichever `services/*` modules they
and `jupiter-vbox` (test OVA). Both import `services.nix`. run. Each service module opens its own firewall ports.
## Test in VirtualBox (no hardware needed) ## Test in VirtualBox (no hardware needed)
@@ -35,7 +44,7 @@ an installer, partitions via disko, installs.
> ONLY (by-id). Back up / physically identify the NAS data disk first — it must > ONLY (by-id). Back up / physically identify the NAS data disk first — it must
> NOT appear in disko. `lsblk -o NAME,SERIAL,SIZE,MODEL` to identify. > NOT appear in disko. `lsblk -o NAME,SERIAL,SIZE,MODEL` to identify.
1. Set the real OS disk id in `jupiter/disk-config.nix` 1. Set the real OS disk id in `hosts/jupiter/disk-config.nix`
(`ls -l /dev/disk/by-id`), and the data-disk mount in `configuration.nix`. (`ls -l /dev/disk/by-id`), and the data-disk mount in `configuration.nix`.
2. Add your login SSH pubkey to `users.users.darman.openssh.authorizedKeys.keys`. 2. Add your login SSH pubkey to `users.users.darman.openssh.authorizedKeys.keys`.
3. Set the real samba password: 3. Set the real samba password:
@@ -56,7 +65,7 @@ an installer, partitions via disko, installs.
nix run github:nix-community/nixos-anywhere -- \ nix run github:nix-community/nixos-anywhere -- \
--flake .#jupiter \ --flake .#jupiter \
--extra-files /tmp/extra \ --extra-files /tmp/extra \
--generate-hardware-config nixos-generate-config ./jupiter/hardware-configuration.nix \ --generate-hardware-config nixos-generate-config ./hosts/jupiter/hardware-configuration.nix \
--target-host root@<zimablade-ip> --target-host root@<zimablade-ip>
``` ```
`--extra-files` plants the host key before first boot (its age identity is `--extra-files` plants the host key before first boot (its age identity is
+3 -3
View File
@@ -31,7 +31,7 @@
modules = [ modules = [
disko.nixosModules.disko disko.nixosModules.disko
sops-nix.nixosModules.sops sops-nix.nixosModules.sops
./jupiter/configuration.nix ./hosts/jupiter/configuration.nix
]; ];
}; };
@@ -42,7 +42,7 @@
modules = [ modules = [
disko.nixosModules.disko disko.nixosModules.disko
sops-nix.nixosModules.sops sops-nix.nixosModules.sops
./vps/configuration.nix ./hosts/vps/configuration.nix
]; ];
}; };
@@ -52,7 +52,7 @@
jupiter-vbox = nixpkgs.lib.nixosSystem { jupiter-vbox = nixpkgs.lib.nixosSystem {
inherit system; inherit system;
specialArgs = { inherit inputs; }; specialArgs = { inherit inputs; };
modules = [ ./jupiter/vm.nix ]; modules = [ ./hosts/jupiter/vm.nix ];
}; };
# Custom kexec installer with our SSH key baked in, for headless install # Custom kexec installer with our SSH key baked in, for headless install
@@ -6,13 +6,13 @@
./hardware-configuration.nix ./hardware-configuration.nix
./disk-config.nix # disko: OS-disk partitions + filesystems ./disk-config.nix # disko: OS-disk partitions + filesystems
./secrets.nix # sops-nix: samba password, tailscale key, ... ./secrets.nix # sops-nix: samba password, tailscale key, ...
../common.nix # shared base: user / ssh / nix / firewall ../../common.nix # shared base: user / ssh / nix / firewall
../services/samba.nix ../../services/samba.nix
../services/avahi.nix ../../services/avahi.nix
../services/audiobookshelf.nix ../../services/audiobookshelf.nix
../services/containers.nix ../../services/containers.nix
../services/caddy.nix ../../services/caddy.nix
../services/tailscale.nix ../../services/tailscale.nix
]; ];
# ---- Host identity ---- # ---- Host identity ----
@@ -1,16 +1,16 @@
{ config, ... }: { config, ... }:
# sops-nix secret wiring (real host only; not imported by vm.nix). # sops-nix secret wiring (real host only; not imported by vm.nix).
# Encrypted values live in ../secrets/jupiter.yaml, decrypted at activation to # Encrypted values live in ../../secrets/jupiter.yaml, decrypted at activation to
# /run/secrets/<name>. # /run/secrets/<name>.
# #
# The host decrypts with its OWN SSH host key (age identity derived via # The host decrypts with its OWN SSH host key (age identity derived via
# ssh-to-age, recipient listed in ../.sops.yaml). The key is pre-generated on # ssh-to-age, recipient listed in ../../.sops.yaml). The key is pre-generated on
# the laptop and shipped once at install as /etc/ssh/ssh_host_ed25519_key # the laptop and shipped once at install as /etc/ssh/ssh_host_ed25519_key
# (nixos-anywhere --extra-files) — so decryption works on boot #1 and there is # (nixos-anywhere --extra-files) — so decryption works on boot #1 and there is
# no separate sops-only key to manage. # no separate sops-only key to manage.
{ {
sops.defaultSopsFile = ../secrets/jupiter.yaml; sops.defaultSopsFile = ../../secrets/jupiter.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
# Decrypts to /run/secrets/samba_password (root-only by default). # Decrypts to /run/secrets/samba_password (root-only by default).
+6 -6
View File
@@ -6,12 +6,12 @@
{ {
imports = [ imports = [
(modulesPath + "/virtualisation/virtualbox-image.nix") (modulesPath + "/virtualisation/virtualbox-image.nix")
../common.nix # shared base: user / ssh / nix / firewall ../../common.nix # shared base: user / ssh / nix / firewall
../services/samba.nix ../../services/samba.nix
../services/avahi.nix ../../services/avahi.nix
../services/audiobookshelf.nix ../../services/audiobookshelf.nix
../services/containers.nix ../../services/containers.nix
../services/caddy.nix ../../services/caddy.nix
]; ];
networking.hostName = "jupiter"; networking.hostName = "jupiter";
@@ -6,9 +6,9 @@
./hardware-configuration.nix ./hardware-configuration.nix
./disk-config.nix # disko: vda partitions + filesystems ./disk-config.nix # disko: vda partitions + filesystems
./secrets.nix # sops-nix: tailscale authkey ./secrets.nix # sops-nix: tailscale authkey
../common.nix # shared base: user / ssh / nix / firewall ../../common.nix # shared base: user / ssh / nix / firewall
../services/caddy.nix ../../services/caddy.nix
../services/tailscale.nix ../../services/tailscale.nix
]; ];
# ---- Boot (UEFI) ---- # ---- Boot (UEFI) ----
@@ -37,7 +37,7 @@
networking.nameservers = [ "9.9.9.9" "1.1.1.1" "2620:fe::fe" ]; networking.nameservers = [ "9.9.9.9" "1.1.1.1" "2620:fe::fe" ];
# firewall (enable + 22), caddy (80/443), tailscale (trust tailscale0 + join # firewall (enable + 22), caddy (80/443), tailscale (trust tailscale0 + join
# headscale) come from ../common.nix and ../services/{caddy,tailscale}.nix. # headscale) come from ../../common.nix and ../../services/{caddy,tailscale}.nix.
# ---- Public reverse proxy vhosts ---- # ---- Public reverse proxy vhosts ----
# Caddy gets automatic public HTTPS (Let's Encrypt) for real domains. # Caddy gets automatic public HTTPS (Let's Encrypt) for real domains.
+3 -3
View File
@@ -1,11 +1,11 @@
{ config, ... }: { config, ... }:
# sops-nix wiring for the VPS. Encrypted values live in ../secrets/vps.yaml, # sops-nix wiring for the VPS. Encrypted values live in ../../secrets/vps.yaml,
# decrypted with the VPS's own SSH host key (recipient in ../.sops.yaml). # decrypted with the VPS's own SSH host key (recipient in ../../.sops.yaml).
# The host key is pre-generated on the laptop and shipped at install # The host key is pre-generated on the laptop and shipped at install
# (nixos-anywhere --extra-files -> /etc/ssh/ssh_host_ed25519_key). # (nixos-anywhere --extra-files -> /etc/ssh/ssh_host_ed25519_key).
{ {
sops.defaultSopsFile = ../secrets/vps.yaml; sops.defaultSopsFile = ../../secrets/vps.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.secrets.tailscale_authkey = { }; sops.secrets.tailscale_authkey = { };
+2 -2
View File
@@ -66,7 +66,7 @@ case "$cmd" in
{ [ -n "$config" ] && [ -n "$host" ]; } || die "usage: ./deploy install <config> <host>" { [ -n "$config" ] && [ -n "$host" ]; } || die "usage: ./deploy install <config> <host>"
hostkey="$HOME/.config/homelab/$config/ssh_host_ed25519_key" hostkey="$HOME/.config/homelab/$config/ssh_host_ed25519_key"
[ -f "$hostkey" ] || die "missing host key: $hostkey" [ -f "$hostkey" ] || die "missing host key: $hostkey"
[ -d "./$config" ] || die "no ./$config directory in the repo" [ -d "./hosts/$config" ] || die "no ./hosts/$config directory in the repo"
# Stage the pre-generated SSH host key so sops can decrypt on boot #1. # Stage the pre-generated SSH host key so sops can decrypt on boot #1.
stage="$(mktemp -d)" stage="$(mktemp -d)"
@@ -78,7 +78,7 @@ case "$cmd" in
nix run github:nix-community/nixos-anywhere -- \ nix run github:nix-community/nixos-anywhere -- \
--flake ".#$config" \ --flake ".#$config" \
--extra-files "$stage" \ --extra-files "$stage" \
--generate-hardware-config nixos-generate-config "./$config/hardware-configuration.nix" \ --generate-hardware-config nixos-generate-config "./hosts/$config/hardware-configuration.nix" \
--target-host "root@$host" --target-host "root@$host"
;; ;;