My NixOS and Nix-Darwin configurations.
- modules - something that's imported on-demand and does not support explicitly enabling
- options - something that's always imported but requires explicit enable. It's also configurable via some abstraction.
- systems - prepared modules for specific systems like nixos, darwin etc.
- profiles - prepared modules for a specific use-case like desktop, server, laptop, etc.
Note
in all commands flake location can be one of the following:
# github repo
github:konradmalik/dotfiles#<target>
# local current dir
.#<target>
# absolute local git repo
git+file://$HOME/Code/github.com/konradmalik/dotfiles#<target>I'll use the local version for brevity.
$ sudo nixos-rebuild --flake . switch
# or
$ sudo nixos-rebuild --flake . bootTo just build (for example for a test):
$ nix build .#nixosConfigurations.m3800.config.system.build.toplevel$ nix build .#rpi4-2-sd-imageCopy it somewhere and unpack:
$ unzstd -d rpi4-2.img.zstFlash directly to the card:
$ sudo dd if=rpi4-2.img of=/dev/sdX bs=4096 conv=fsync status=progressNote
The filesystem won't be complete, it will miss etc and more. NixOS will populate those dirs on first boot.
So if you need to modify something on the card (like read host keys) then the steps are:
- boot rpi with the newly flashed card once
- wait a minute or two
- poweroff rpi and mount the card on your PC
- filesystem will be complete
In NixOS ISO:
Clone this repo
$ git clone https://github.com/konradmalik/dotfilesEnter shell
$ nix-shellUse disko to format and mount:
$ sudo disko --mode destroy,format,mount ./hosts/m3800/disko.nixGenerate hardware configuration:
$ nixos-generate-config --no-filesystems --root /mntGenerate/add sops keys (if required for the configuration). Do this later only if no critical services rely on them (like user passwords).
Host ones will be picked up automatically. Add user ones to /home/USER/.config/sops.keys.txt.
For details refer to sops-nix section.
Finally, use hardware-configuration and disko to install nixos:
$ sudo nixos-install --flake .#m3800 --root /mntIn NixOS ISO:
Clone this repo
$ git clone https://github.com/konradmalik/dotfilesEnter shell
$ nix-shellUse disko to mount:
$ sudo disko --mode mount ./hosts/m3800/disko.nixEnter your system
$ cd /mnt
$ nixos-enterFirst clone this repo to the machine.
Then you need to install nix. nix-darwin manual suggests using lix as the bootstrapper
(it does not influence what implementation of nix is used later by the system).
Next install homebrew.
Enter the devshell from this repo.
Finally, build and enable config locally:
$ sudo darwin-rebuild switch --flake .To just build (for example for a test):
$ nix build .#darwinConfigurations.m4.config.system.build.toplevel
# or shortened by nix-darwin
$ nix build .#darwinConfigurations.m4.systemIt is useful to have a Linux builder on a macOS machine to build linux-specific stuff.
NixOS has a great support for this. We need to:
- set up a remote builder
- configure nix.buildMachines to use it
We can have either a truly remote machine (local PC, cloud VM etc. etc.) or a 'local remote builder' which is just a qemu virtual machine with NixOS inside. This 'local remote builder' is very handy to have either way, very easy to deploy and very lightweight (it mounts your existing /nix/store for example for absolutely minimal disk usage).
nix-darwin support a Linux builder as an option:
nix.linux-builder.enable = true;Use container.
Build and enable config locally:
$ home-manager switch --flake .To just build (for example for a test):
$ nix build .#[email protected]Strategy with keys:
- none of the keys block new machines. If they're missing, they'll just fail to decrypt on runtime.
agederived from host ssh key for host-wide secretsagederived from personal ssh key for personal secrets- one global
agekey per person that is kept secret and not directly on any machine. Serves as a backup to decrypt in case of 'tragedy'
To get age key for the machine, use:
$ cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-ageAdd this key to .sops.yaml and propagate re-encryption to all secrets:
$ for file in $(grep -lr "^sops:$"); do sops updatekeys -y $file; doneCreate age directory for sops:
$ mkdir -p "$XDG_CONFIG_HOME/sops/age" \
$ && touch "$XDG_CONFIG_HOME/sops/age/keys.txt" \
$ && chmod 700 "$XDG_CONFIG_HOME/sops/age" \
$ && chmod 600 "$XDG_CONFIG_HOME/sops/age/keys.txt"Create age key from your personal ssh key:
Why do this when decryption keys are also derived from host ssh keys?
- Redundancy, 2. Personal (user-specific) secrets, 3. Keys generated here can also be used in the home-manager module below
$ ssh-to-age -private-key -i ~/.ssh/personal > "$XDG_CONFIG_HOME/sops/age/keys.txt"Add this key to .sops.yaml and propagate re-encryption to all secrets:
$ for file in $(grep -lr "^sops:$"); do sops updatekeys -y $file; doneFor user-specific secrets, a home-manager modules of sops-nix is used.
We similarly use age. The key is reused from system-wide config (the one derived from personal ssh).
See how sops is configured in the home-manager (it just points at the keys.txt file).
Misterio77 - big inspiration for hyprland and nix files structure.