# homelab Flake-based NixOS config. Host: `jupiter` (ZimaBlade, NAS + services). ## Structure ``` flake.nix # inputs (nixpkgs, disko) + nixosConfigurations jupiter/configuration.nix # real host: imports + bootloader + data mount jupiter/disk-config.nix # disko: OS-disk partitions + filesystems jupiter/hardware-configuration.nix # PLACEHOLDER — kernel modules, regenerate on target jupiter/services.nix # shared: users, ssh, samba, containers, caddy jupiter/vm.nix # VirtualBox test image (jupiter-vbox) ``` Two configs from one service definition: `jupiter` (real host, disko-partitioned) and `jupiter-vbox` (test OVA). Both import `services.nix`. ## Test in VirtualBox (no hardware needed) ``` nix build .#nixosConfigurations.jupiter-vbox.config.system.build.virtualBoxOVA VBoxManage import result/*.ova --vsys 0 --vmname jupiter-vbox VBoxManage startvm jupiter-vbox --type headless ``` Login `darman` / `test`. Forward ports with `VBoxManage modifyvm ... --natpf1`. ## First install on the ZimaBlade — nixos-anywhere + disko Wipes the OS disk and installs the flake over SSH. No USB needed if the box already runs Linux (ZimaOS) reachable by root SSH — nixos-anywhere kexecs into an installer, partitions via disko, installs. > ⚠️ The OS disk in `disk-config.nix` is WIPED. Set `device` to the OS disk > 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. 1. Set the real OS disk id in `jupiter/disk-config.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`. 3. Set the real samba password: ``` export SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt nix shell nixpkgs#sops -c sops secrets/jupiter.yaml # edit, commit ``` 4. Stage the pre-generated host key so sops can decrypt on boot #1 (private key lives off-repo in `~/.config/homelab/jupiter/`): ``` install -Dm600 ~/.config/homelab/jupiter/ssh_host_ed25519_key \ /tmp/extra/etc/ssh/ssh_host_ed25519_key install -Dm644 ~/.config/homelab/jupiter/ssh_host_ed25519_key.pub \ /tmp/extra/etc/ssh/ssh_host_ed25519_key.pub ``` 5. Run from your laptop: ``` nix run github:nix-community/nixos-anywhere -- \ --flake .#jupiter \ --extra-files /tmp/extra \ --generate-hardware-config nixos-generate-config ./jupiter/hardware-configuration.nix \ --target-host root@ ``` `--extra-files` plants the host key before first boot (its age identity is already a recipient in `.sops.yaml`, so `/run/secrets/samba_password` decrypts on boot #1). `--generate-hardware-config` pulls the target's real kernel modules into the placeholder. Commit the result. Reboot into NixOS. Manual alternative (USB ISO): boot installer, `disko` the disk, then `nixos-install --flake .#jupiter`. ## Deploy (the `./deploy` wrapper) All arguments mandatory — no default host, no default config. ``` ./deploy kexec # headless kexec into a RAM installer (RO-root box) ./deploy install # first install; wipes OS disk, ships host key ./deploy switch # rebuild + activate on a running host ./deploy boot|test # stage for next boot / activate without boot entry ``` `` is a `nixosConfigurations` name (`jupiter`, `vps`). Its pre-generated SSH host key lives at `~/.config/homelab//ssh_host_ed25519_key`. Examples: ``` ./deploy switch jupiter jupiter.sol ./deploy install vps 159.195.64.117 ``` Rollback: `nixos-rebuild switch --rollback` on the host, or pick a prior generation at boot. ## Adding a service Copy the `whoami` block in `oci-containers.containers`, swap image/ports/volumes. Native NixOS module exists for many apps (Nextcloud, Jellyfin, Grafana...) — prefer `services.` over a container when available. Add a `caddy` `virtualHosts` block to expose it. ## Notes - Backend is Podman with `dockerCompat` — `docker` CLI works, no daemon. - Samba keeps its own password DB. `services.samba` never sets it; a systemd oneshot (`samba-smbpasswd`) provisions it. Host reads the password from `/run/secrets/samba_password` (**sops-nix**); the VM falls back to plaintext `/etc/samba/smb-password`. - Secrets: `secrets/jupiter.yaml` is age-encrypted (safe to commit) to two recipients in `.sops.yaml` — the **admin** key (edit on laptop, `~/.config/sops/age/keys.txt`) and the **jupiter host** key (derived from its SSH host key via `ssh-to-age`, decrypts at runtime). Private keys live off-repo and are gitignored. Rotate/add recipients with `sops updatekeys`. - Data disk: plain `fileSystems."/mnt/data"` in configuration.nix — kept out of disko so it is never formatted. Reference by `by-id` / `by-uuid`. - `system.stateVersion` = `26.05`, install-time schema. Do NOT bump on upgrades. - Terraform is not used: a single bare-metal box has no provider API. disko + nixos-anywhere cover provisioning natively. ```