# NixOS + Home Manager Setup Overview (sam/nixos) This document is a practical overview of how this NixOS setup was built and how “dotfiles” are managed, so another AI session (or you later) can replicate it on another machine. Repo: `ssh://git@gitea.lab.audasmedia.com.au:2222/sam/nixos.git` ## Goals of this setup - Reproducible NixOS install via flakes (`nixos-rebuild` / `nixos-install`) - Home Manager managed user config (zsh, kitty, nvim config, etc.) - KDE Plasma + Hyprland selectable at SDDM login - Neovim works reliably on NixOS: - config tracked in git - plugins installed via lazy.nvim into a writable directory - avoid writing any lockfiles into `/nix/store` (read-only) ## High-level architecture - System config: `hosts//configuration.nix` - Hardware config: `hosts//hardware-configuration.nix` - generated per-machine during install, then committed - Home Manager (as NixOS module): `home/sam/home.nix` - Neovim config stored in repo: `home/sam/nvim/...` ### Repo structure (typical) - `flake.nix` - `hosts/aspire-laptop/configuration.nix` - `hosts/aspire-laptop/hardware-configuration.nix` - `home/sam/home.nix` - `home/sam/nvim/` (init.lua, lua/, lazy-lock.json from old setup if needed) - `scripts/install-from-iso.sh` ## Installation procedure (wipe disk) ### BIOS notes - Secure Boot disabled on the Acer test laptop for easiest install. (If Secure Boot is locked by a BIOS Supervisor password, bare-metal install may be blocked; use a VM test instead.) ### From the NixOS graphical ISO (live environment) 1. Connect to the internet. 2. Clone repo to the live environment: - `git clone ssh://git@gitea.lab.audasmedia.com.au:2222/sam/nixos.git /tmp/nixos` 3. Partition/mount (WIPES DISK): - Identify disk (e.g. `/dev/sda` or `/dev/nvme0n1`) - Run: - `sudo DISK=/dev/ bash /tmp/nixos/scripts/install-from-iso.sh` This creates: - EFI partition (vfat) - Btrfs root with subvolumes `@` and `@home` - Mounts under `/mnt` and generates `/mnt/etc/nixos/hardware-configuration.nix` 4. Copy repo into target: - `sudo rm -rf /mnt/etc/nixos` - `sudo mkdir -p /mnt/etc` - `sudo cp -a /tmp/nixos /mnt/etc/nixos` 5. Copy generated hardware config into the repo host path: - `sudo cp -f /mnt/etc/nixos/hardware-configuration.nix /mnt/etc/nixos/hosts//hardware-configuration.nix` 6. Install: - `sudo nixos-install --flake /mnt/etc/nixos#` - reboot ### After first boot - Set password for `sam` if needed: - `sudo passwd sam` - If using Tailscale: - `sudo tailscale up` ## SSH access (to administer remotely) This setup enabled OpenSSH server via NixOS config. - `services.openssh.enable = true;` - `services.openssh.openFirewall = true;` - Password auth was enabled for convenience in testing (not best practice). To apply: - `sudo nixos-rebuild switch --flake /etc/nixos#` ## “Dotfiles” / config management approach (what we actually did) ### The key rule Home Manager symlinks managed files into `/nix/store` (read-only). That is fine for config files, but NOT fine for files that apps need to write to at runtime. ### Neovim (special case) Neovim + lazy.nvim expects to write: - lockfile - plugin installs - cache/state So: 1) The Neovim config code is kept in git and linked by Home Manager, but we do NOT have HM own the entire `~/.config/nvim` directory. We link only: - `~/.config/nvim/init.lua` - `~/.config/nvim/lua/` Example Home Manager linking (conceptual): - `xdg.configFile."nvim/init.lua".source = ./nvim/init.lua;` - `xdg.configFile."nvim/lua".source = ./nvim/lua;` 2) lazy.nvim is configured to write lockfile into a writable location: - lockfile path: `vim.fn.stdpath("data") .. "/lazy-lock.json"` (=> `~/.local/share/nvim/lazy-lock.json`) 3) Plugins are installed by lazy.nvim into: - `~/.local/share/nvim/lazy/` 4) After a new install / new machine, bootstrap plugins with: - `nvim --headless "+Lazy! sync" "+qa"` ### Why we avoided Nix-managed Neovim plugins in HM If `programs.neovim.plugins = ...` is used, Neovim may load plugins from a read-only Nix “vim pack dir” under `/nix/store/...`. Some plugins (notably treesitter) try to write build artifacts into the plugin directory, which fails on read-only paths. Therefore: - Nix installs `nvim` + dependencies (node/python/rg/fd/compilers). - lazy.nvim installs the plugins at runtime into user-writable dirs. ### Other tools Most other CLI tools can be installed declaratively via NixOS or Home Manager. Their configs can be safely managed by HM as symlinks (read-only is fine). ## Notable fixes/decisions made during setup - If you see errors like “Read-only file system” writing `lazy-lock.json`, it means HM is managing the lockfile path. Fix by moving lockfile to data dir and not linking `lazy-lock.json` into `/nix/store`. - Treesitter module name mismatch was fixed in config to handle upstream changes: attempt `require("nvim-treesitter.config")` and fallback to `require("nvim-treesitter.configs")`. - Avante was disabled on low-power machines by removing/renaming its plugin spec file so lazy.nvim does not load it. - Git remote update issues were resolved using: - `git fetch origin` - `git pull --rebase origin main` - `git push` ## Adding programs (basic workflow) ### System-wide packages Edit: - `hosts//configuration.nix` Add to: - `environment.systemPackages = with pkgs; [ ... ];` Apply: - `sudo nixos-rebuild switch --flake /etc/nixos#` ### User-only packages Edit: - `home/sam/home.nix` Add to: - `home.packages = with pkgs; [ ... ];` Apply: - `sudo nixos-rebuild switch --flake /etc/nixos#` ### Then commit + push - `cd /etc/nixos` - `git add -A` - `git commit -m "..." && git push` ## Secrets (do not put in git) Do not commit API keys (Gemini/OpenAI/etc.) into this repo. Preferred: - store secrets outside git (password manager) and export into your shell - or use a secret manager like `sops-nix` later Example (local-only) environment file: - `~/.config/environment.d/10-secrets.conf` - contains `GEMINI_API_KEY=...` - not tracked in git ## References - NixOS Manual: https://nixos.org/manual/nixos/stable/ - Home Manager Manual: https://nix-community.github.io/home-manager/ - Flakes: https://nixos.wiki/wiki/Flakes - Packages/options search: https://search.nixos.org/