Skip to content

About

My NixOS configurations

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

97 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nixos-config

Multi-host NixOS config using flakes. Every host shares common/ (users, package groups, services, home-manager) so package versions stay identical machine to machine; per-host files hold hostname + hardware specifics.

Layout

  • flake.nix — pins nixpkgs (release branch) + home-manager; flake.lock is the version pin. Upgrade on purpose: nix flake lock --update-input nixpkgs, rebuild all hosts, commit. Also pins nixpkgs-unstable (rolling) for groups listed in perry.unstableGroups; refresh with nix flake update nixpkgs-unstable. Also defines homeConfigurations.perry-mac, the Mac entry point (see Mac).
  • common/common.nix — shared users, services, networking, home-manager wiring, the perry.systemGroups selector, and the perry.unstableGroups selector (same group names served from the rolling unstable branch).
  • common/pkg-groups.nix — named package groups (core, dev, net, langs, ai, containers, tools, backup are safe on any host; browsers, graphics, media, office, dev-gui, remote, terminals, chat are desktop-only). A host picks its set with perry.systemGroups; default is all of them. Headless servers drop the GUI groups (see below). ai (herdr) is nixpkgs-unstable-only — it must be in perry.unstableGroups, not the stable set. The only packages outside the groups: kdePackages.kate (per-user via users.users.perryh.packages in common/common.nix) and the home-manager user packages in common/home.nix.
  • common/home.nix — shared user config via home-manager (zsh, git identity, ripgrep/fzf/eza, and the per-user agent CLIs omp + opencode 2 + herdr).
  • pkgs/ — repo-local derivations of packages not in nixpkgs (currently dsh, built from its published npm tarball, and opencode, OpenCode 2 from upstream's published binaries). Pattern: an overlay in pkgs/<name>/default.nix added to nixpkgs.overlays in common/common.nix (and to the flake's pkgs imports), referenced by name in a group or in common/home.nix.
  • hosts/<name>.nix — per-host: hostname, boot loader, laptop/desktop specifics, and perry.systemGroups for that machine.
  • hosts/<name>-hardware.nix — per-host boot/filesystem/disk. Regenerate with sudo nixos-generate-config and copy over; never hand-edit.

Package groups

perry.systemGroups selects which named groups to install (default = all, so a desktop needs no assignment):

# desktop — all groups including core (the default; nothing to set)

# headless server — no GUI, keep the base tools
perry.systemGroups = [ "core" "dev" "containers" ];

Groups (safe on any host — including headless servers and the Mac):

group packages
core gh, neovim, vim, curl, jq
dev git, dust, fd, pnpm, shellcheck, tree, zola
net whois, net-tools, iputils, bind.dnsutils, mtr, netcat, nmap, iperf3, tcpdump
langs go_latest, python3, ruby, rustc, cargo, nodejs_24
ai herdr (unstable-only), dsh (repo-local)
containers docker
tools p7zip, ethtool, gptfdisk, parted, testdisk, udisks, unzip
backup restic

Desktop-only (omit on headless hosts):

group packages
browsers firefox, brave, google-chrome
graphics gimp, darktable, digikam, imagemagick, kdePackages.marble, kdePackages.skanpage
media ffmpeg, mediainfo, mpv, ffmpegthumbnailer, vlc, yt-dlp, kdePackages.kdenlive
office libreoffice, kdePackages.kcalc
dev-gui vscode-fhs
remote rustdesk-flutter
terminals ghostty
chat vesktop, signal-desktop, slack

Selecting containers also enables the docker daemon and adds the user to the docker group; selecting browsers also enables the firefox module.

Unstable groups

A host can take whole groups from the rolling nixpkgs-unstable branch instead of the stable pin, while the OS and everything else stay on the release branch:

# hosts/<name>.nix — the list both hosts currently track
perry.unstableGroups = [ "terminals" "chat" "ai" "langs" "dev-gui" "remote" "dev" ];

The group is then installed exactly once, from unstable (its stable copy is dropped). Refresh those apps with nix flake update nixpkgs-unstable + rebuild; remove a group from the list to return it to the stable pin.

browsers is intentionally kept on the stable pin: Brave's Qt shim loads the session's Qt plugins from QT_PLUGIN_PATH, so it must be built against the same Qt as Plasma — unstable's Brave (Qt 6.12) aborts at startup against 26.05's Plasma (Qt 6.11). Browsers refresh with the OS via nix flake lock --update-input nixpkgs.

Note the ai group (herdr) exists only in unstable — hosts that don't list it in perry.unstableGroups get a clear error if the stable set includes it.

Mac (perry-mac)

perry-mac (aarch64-darwin) is a standalone home-manager configuration — no NixOS, so the package groups cannot come from environment.systemPackages and no group side effect applies (no docker daemon, no firefox module, no restic service). Deploy with:

home-manager switch --flake ~/git/nixos-config#perry-mac

Which groups the Mac gets is set in the homeConfigurations.perry-mac module in flake.nix: cliGroups comes from the stable pin, cliUnstableGroups from nixpkgs-unstable, and both expand the same common/pkg-groups.nix definitions the NixOS hosts use. Currently core net tools backup (stable) + langs dev (unstable), so the Mac has gh, git, neovim, jq, restic, the language toolchains, the dev CLIs and the network tooling. Each group keeps the source the NixOS hosts take it from, so versions stay identical machine to machine; groups the hosts track from unstable need to be listed in cliUnstableGroups to stay in step.

Members nixpkgs marks Linux-only (iputils, ethtool, parted, udisks) are filtered out automatically. The GUI groups stay Linux-only, and containers / ai are excluded on purpose (no docker daemon on darwin; the repo-local dsh would need a darwin build — omp, opencode and herdr already reach the Mac through common/home.nix).

First boot on a machine

  1. Clone this repo (flakes are enabled by default on 25.05+).
  2. sudo nixos-generate-config → copy /etc/nixos/hardware-configuration.nix into the repo as hosts/<name>-hardware.nix.
  3. No password setup needed: users.mutableUsers (default) merges with existing accounts and leaves existing passwords alone. (For a brand-new user, set hashedPassword.)
  4. Create hosts/<name>.nix (copy one) and add nixosConfigurations.<name> = mkHost "<name>"; in flake.nix.
  5. sudo nixos-rebuild switch --flake <repo-path>#<name>.

First build compiles the whole closure — takes a while. With a flake, /etc/nixos/configuration.nix is left as-is; the flake in this repo is the single source of truth.

Adding a new host

  1. Copy hosts/perry-eb.nix + hosts/perry-eb-hardware.nix to the new name.
  2. Add nixosConfigurations.<name> = mkHost "<name>"; in flake.nix.
  3. Generate hardware on the machine, deploy, commit.

Packages not in nixpkgs

When a package isn't in nixpkgs at all, add a repo-local derivation under pkgs/<name>/default.nix as an overlay (wired into nixpkgs.overlays in common/common.nix and the flake's pkgs imports, referenced by name in a group or in common/home.nix). Today: dsh, the DeepSeek Harness CLI, built with buildNpmPackage from the published npm tarball; and opencode, OpenCode 2 built from upstream's published per-platform npm binaries (fetchurl + one SRI hash per system, patchelf'd to the nix loader — refresh recipes in each default.nix).

About

My NixOS configurations

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages