Files
nixos-4screen/previous_setup.md
2026-02-08 13:09:33 +11:00

6.2 KiB

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/<host>/configuration.nix
  • Hardware config: hosts/<host>/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/<disk> 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/<host>/hardware-configuration.nix
  6. Install:

    • sudo nixos-install --flake /mnt/etc/nixos#<host>
    • 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#<host>

“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;
  1. 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)
  1. Plugins are installed by lazy.nvim into:
  • ~/.local/share/nvim/lazy/
  1. 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/<host>/configuration.nix Add to:
  • environment.systemPackages = with pkgs; [ ... ]; Apply:
  • sudo nixos-rebuild switch --flake /etc/nixos#<host>

User-only packages

Edit:

  • home/sam/home.nix Add to:
  • home.packages = with pkgs; [ ... ]; Apply:
  • sudo nixos-rebuild switch --flake /etc/nixos#<host>

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