k1-c's NixOS configuration (flake). Manages multiple machines from a single flake.
.
├── flake.nix # flake entry / nixosConfigurations
├── hosts/ # per-machine config
│ ├── daiv/ # main desktop (NVIDIA RTX 5070 Ti, Windows dual boot)
│ ├── insomnia/ # sub desktop (NVIDIA + Intel NPU)
│ ├── dwarf/ # sub desktop (Intel iGPU)
│ └── mind/ # sub desktop (Intel iGPU + DisplayLink)
├── modules/ # NixOS modules (shared across hosts)
│ └── desktop/ # SDDM + COSMIC (default) / Plasma / Hyprland
└── home/k1nix/ # home-manager (user "k1nix")
├── claude-code.nix # Claude Code + statusLine (repo / branch / Linear issue)
└── desktop/ # waybar / fuzzel / hyprlock etc.
| host | CPU/GPU | role |
|---|---|---|
| daiv | i9-13900KF + NVIDIA RTX 5070 Ti | main desktop |
| insomnia | Intel + NVIDIA RTX 3070 | sub desktop |
| dwarf | Intel + iGPU | sub desktop |
| mind | Intel + iGPU (DisplayLink dock) | sub desktop |
daiv notes: Intel VMD is enabled on this board (keep vmd in the initrd; do not disable VMD in BIOS or the Windows install on the other NVMe stops booting). Windows lives on a separate ESP, so it is picked from the firmware boot menu; see hosts/daiv/default.nix for the optional systemd-boot entry.
Both hosts share a single user account k1nix. Initial password is password (see below).
Pick at login via SDDM:
- COSMIC (Wayland) — default on every host. Uses COSMIC 1.6 from
nixos-unstable(seemodules/desktop/cosmic.nix) for Frosted Glass. Untested on the NVIDIA hosts as of 2026-09; if it fails to start, pick Plasma from SDDM. - Plasma (Wayland) — Liquid Glass-ish look (KWin Blur + Background Contrast +
kde-rounded-corners, transparent panel). Walker bound toMeta+Return/Meta+D. Animated wallpaper viaplasma-smart-video-wallpaper-reborn(drop a file at~/.config/wallpaper/animated.mp4). - Hyprland (Wayland, dynamic tiling)
Per-DE home-manager configs live in home/k1nix/desktop/{plasma,hyprland}.nix. KDE side is configured declaratively via plasma-manager. waybar and friends run as systemd user units bound to graphical-session.target.
SDDM greeter itself still runs on X11 (
wayland.enable = false) to dodge the NVIDIA + open-module +kwin_waylandatomic-modeset bug — only the Plasma session is Wayland.
Assumes you have booted the NixOS minimal ISO.
# UEFI layout (GPT + ESP)
sudo parted /dev/nvme0n1 -- mklabel gpt
sudo parted /dev/nvme0n1 -- mkpart ESP fat32 1MiB 512MiB
sudo parted /dev/nvme0n1 -- set 1 esp on
sudo parted /dev/nvme0n1 -- mkpart primary 512MiB 100%
sudo mkfs.fat -F 32 -n boot /dev/nvme0n1p1
sudo mkfs.ext4 -L nixos /dev/nvme0n1p2
sudo mount /dev/disk/by-label/nixos /mnt
sudo mkdir -p /mnt/boot
sudo mount -o umask=077 /dev/disk/by-label/boot /mnt/bootnix-shell -p git --run 'git clone https://github.com/k1-c/nix /mnt/etc/nixos'
cd /mnt/etc/nixos
# Create a directory for the new host (example: laptop)
mkdir -p hosts/laptop
sudo nixos-generate-config --root /mnt --show-hardware-config \
> hosts/laptop/hardware-configuration.nixCopy hosts/dwarf/default.nix as a starting point for hosts/laptop/default.nix, then:
- set
networking.hostNametolaptop - if the machine has NVIDIA, import a
./nvidia.nixmodeled afterhosts/insomnia/nvidia.nix
Add one line to nixosConfigurations in flake.nix:
laptop = mkHost "laptop" "x86_64-linux";sudo nixos-install --flake /mnt/etc/nixos#laptop
# After reboot, log in as k1nix / passwordWhen the target host is already defined in this flake (insomnia or dwarf) and the
disk layout matches what is committed in hosts/<name>/hardware-configuration.nix,
you can skip the clone step and let nixos-install fetch everything over the network.
# Boot the NixOS minimal ISO, then partition & mount /mnt
# (see "Initial setup" step 1)
# Install straight from the GitHub flake
sudo nixos-install \
--flake github:k1-c/nix#dwarf \
--no-root-password # the user already has initialPasswordNotes:
- Older ISOs may not have flakes enabled by default. Add
--option experimental-features 'nix-command flakes'ifnixos-installcomplains about unknown experimental features. - For a brand-new machine without a matching
hosts/<name>/directory, this shortcut does not work. Use the full "Initial setup" flow to clone, generatehardware-configuration.nix, add the host toflake.nix, push, and then install. - Pinning to a specific revision:
github:k1-c/nix/<commit-or-tag>#dwarf.
git clone https://github.com/k1-c/nix ~/dev/git/github.com/k1-c/nix
cd ~/dev/git/github.com/k1-c/nix
# Evaluate first to catch errors safely
sudo nixos-rebuild dry-build --flake .#$(hostname)
# Apply
sudo nixos-rebuild switch --flake .#$(hostname)
nix flakeonly sees git-tracked files. When trying local changes, at leastgit add -A(no commit needed) before runningnixos-rebuild.
# Refresh flake.lock
nix flake update
# Update a single input
nix flake update nixpkgs
# Apply
sudo nixos-rebuild switch --flake .#$(hostname)To roll back a generation:
sudo nixos-rebuild switch --rollback
# Or pick an older generation from the GRUB menuhome/k1nix/git.nix only holds the personal identity. Work identities stay out of this public repo and live in untracked files under ~, selected by where ghq clones the repo (~/dev/git/github.com/<owner>/<repo>).
-
Base config (tracked). HTTPS credentials come from gh, pinned to the personal account with
gh auth token --user k1-c.gh auth git-credentialis not used, because it always answers with gh's active account, whichever onegh auth switchlast picked. -
~/.gitconfig.local(untracked). The base config includes it. It maps an owner directory to a per-account file:[includeIf "gitdir:~/dev/git/github.com/<org>/"] path = ~/.gitconfig.<org>
-
~/.gitconfig.<org>(untracked). Overrides the identity and the credential helper:[user] name = <name> email = <work-email> # The empty value clears the inherited (personal) helper; without it git # would still try the personal token first. [credential "https://github.com"] helper = helper = "!f() { test \"$1\" = get || exit 0; echo username=<work-account>; echo \"password=$(gh auth token --hostname github.com --user <work-account>)\"; }; f"
To add an account, run gh auth login for it (both accounts stay logged in; gh auth status lists them), then add an includeIf + file pair. Check it from inside a clone:
git config --show-origin --get-all user.email
git config --show-origin --get-all credential.https://github.com.helperCaveats:
-
includeIf "gitdir:..."only matches inside an existing repo. Before the first clone,ghq getuses the base (personal) credentials. For a private work repo the personal account cannot read, force the include for the clone:GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=include.path GIT_CONFIG_VALUE_0=~/.gitconfig.<org> \ ghq get <org>/<repo>
-
This only switches git. The
ghCLI itself (gh pr create, …) still uses the active account, so rungh auth switchor setGH_TOKENwhen working on those repos.
hosts/{insomnia,dwarf}/default.nix ships with a hardcoded initialPassword = "password".
- While this repository is public, the password is visible to anyone
- After the first install, log in, run
passwdto change it, then delete that line and commit - Long-term, migrate to secret management with
sops-nixoragenix
initialPassword is only written when /etc/shadow has no entry for the user, so once passwd has changed it the option becomes a no-op. Still, the literal stays in git history, so it is hygienic to strip it.
GitHub Actions runs nix flake check --no-build on every push / PR / workflow_dispatch (.github/workflows/check.yml).
What it catches:
- Nix syntax errors
- References to nonexistent attributes / options
- Typos in import paths
flake.lockconsistency
What it does not catch: actual builds (proprietary NVIDIA and friends are not fetched in CI). Run nixos-rebuild dry-build locally, or extend the workflow with a build job if needed.
| input | source | purpose |
|---|---|---|
nixpkgs |
NixOS/nixpkgs/nixos-25.11 |
main package set |
nixpkgs-unstable |
NixOS/nixpkgs/nixos-unstable |
a few newer packages (gh, codex) |
home-manager |
nix-community/home-manager/release-25.11 |
user-level configuration |
plasma-manager |
nix-community/plasma-manager |
declarative KDE Plasma 6 home-manager module |