flake.nix: Entrypoint for the config. Eachoutputs.nixosConfiguration.*defines a configuration for a different machine / virtual machine.hosts/config.nix: Main config file. Specifies installed programs,.nixconfig files, environment variables, and not much more.hosts/basic_config.nix: Things I don't put inhosts/config.nixbecause they rarely change, like battery or audio settings.dotfiles/*/**: Regular config files for each program, that I symlink usingGNU stow.dotfiles/*.nix: Nix config for some programs.scripts_as_dotfiles/: Scripts that programs rely on, or that I effectively use as configuration.hosts/: Configuration specific the different machines / virtual machines; referenced fromflake.nix.secrets/: Encrypted secrets and related config.
- Flash the nixos minimal iso to an usb. Can use balenaEtcher, dd... With dd on Linux:
lsblk -pd # Find the usb. Must be the whole disk e.g. /dev/sdb and not /dev/sdb1
sudo umount /dev/sdb*
sudo dd bs=4M conv=fsync oflag=direct status=progress if=/home/nixos/Downloads/nixos-minimal-26.05.4808.569d57850992-x86_64-linux.iso of=/dev/sdb-
Enter the laptop boot menu, disable secure boot, and delete the secure boot keys
-
Boot from the usb
-
Clone this repo:
nmcli device wifi list
sudo nmcli device wifi connect "SSID_NAME" password "WIFI_PASSWORD"
git clone "https://github.com/pbvrl/dotfiles" "$HOME/.config/nixos"or restore from local storage...
nmcli device wifi list
sudo nmcli device wifi connect "SSID_NAME" password "WIFI_PASSWORD"
nix run nixpkgs#bashmount --extra-experimental-features "nix-command flakes" # Xm; e.g. 3m; mount to /home/nixos/mnt/usb
REPO=/home/nixos/mnt/usb/restic-repo
RESTORE_PATH="$HOME/restic-restored/"
sudo nix run nixpkgs#restic --extra-experimental-features "nix-command flakes" -- restore latest -r "$REPO" --target "$RESTORE_PATH" --include "/home/nixos/.config/nixos" --include "/var/lib/sops-nix"
sudo chown -R nixos:users $RESTORE_PATH
mkdir -p /home/nixos/.config
cp $RESTORE_PATH/home/nixos/.config/nixos /home/nixos/.config/nixos -r
sudo mkdir -p /var/lib/sops-nix
sudo cp $RESTORE_PATH/var/lib/sops-nix/key.txt /var/lib/sops-nix/key.txt
sudo chown nixos:users /var/lib/sops-nix/key.txt && sudo chmod 600 /var/lib/sops-nix/key.txt- Point the partitioning config to the laptop/pc's disk:
lsblk -pd # Find the main internal disk e.g. /dev/nvme0n1
vim /home/nixos/.config/nixos/hosts/base/disko.nix disk1 = {
type = "disk";
device = "/dev/nvme0n1"; # <-- Partition the drive encrypting the main parition:
WARNING: This wipes the disk.
echo -n "yourEncryptionPassword" > /tmp/luks-password.txt
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount /home/nixos/.config/nixos/hosts/base/disko.nix
lsblk -pf # Verify the 'vfat' and 'crypto_LUKS' partitions were created- Generate the hardware config (
--no-filesystemsbecause disko handles that):
sudo nixos-generate-config --no-filesystems --show-hardware-config > /home/nixos/.config/nixos/hosts/base/hardware-configuration.nix- Install nixos on the main partition. Prompts for the root password at the end:
WARNING:
nixos-installrequires at least 4GB of ram, otherwise there are other alternatives
Ignore the "Cannot read ssh key" warnings, they resolve on first boot. Ignore "Activation script snippet 'setupSecrets' failed"
sudo nixos-install --root /mnt --impure --flake /home/nixos/.config/nixos#base- Symlink dotfiles before rebooting, so rebooting lands in a ready system:
Ignore the "Cannot read ssh key" and the "su: Authentication service cannot retrieve authentication info" warnings, they resolve on first boot. Ignore "Activation script snippet 'setupSecrets' failed"
sudo mkdir -p /mnt/home/nixos/.config
sudo cp /home/nixos/.config/nixos /mnt/home/nixos/.config/nixos -r
sudo nixos-enter --root /mnt -c "chown -R nixos:users /home/nixos"
sudo nixos-enter --root /mnt -c "su - nixos -c /home/nixos/.config/nixos/scripts/stow.sh"- Reboot
This logs off the temporary environment running from the usb and boots inside the main drive where the flake was installed
Lanzaboote will automatically reboot a second time from the login screen, and enroll the secureboot keys
reboot
sudo bootctl status # Secure Boot: disabled
sudo sbctl verify # only the kernel .efi file is not signed- Reboot a third time, enter the bios console, and reenable SecureBoot. Then check it is enabled.
reboot
sudo bootctl status # Secure Boot: enabled- Install browser extensions: Vimium, etc.
Super+h shows the keybind helper.
For rebuiding, use --impure to pick up the private git submodule:
sudo nixos-rebuild switch --impure --flake "/home/nixos/.config/nixos#$hostname"- Generate a .sops.yaml file, a public key and a private key:
|
fish sudo mkdir -p /var/lib/sops-nix
set PUBLIC_KEY (sudo age-keygen -o /var/lib/sops-nix/key.txt 2>&1 | sed 's/Public key: //')
sudo chown nixos:users /var/lib/sops-nix/key.txt; and sudo chmod 600 /var/lib/sops-nix/key.txt
echo "keys:
- &personal $PUBLIC_KEY
creation_rules:
- path_regex: secrets.yaml\$
key_groups:
- age:
- *personal" > ~/.config/nixos/secrets/.sops.yaml
cd ~/.config/nixos/secrets
rm secrets.yaml |
bash sudo mkdir -p /var/lib/sops-nix
export PUBLIC_KEY=$(sudo age-keygen -o /var/lib/sops-nix/key.txt 2>&1 | sed 's/Public key: //')
sudo chown nixos:users /var/lib/sops-nix/key.txt && sudo chmod 600 /var/lib/sops-nix/key.txt
cat > ~/.config/nixos/secrets/.sops.yaml << EOF
keys:
- &personal $PUBLIC_KEY
creation_rules:
- path_regex: secrets.yaml\$
key_groups:
- age:
- *personal
EOF
cd ~/.config/nixos/secrets
rm secrets.yaml |
- Place your secrets in the
secrets.yamlfile:
~/.config/nixos/scripts/sops.shFor example:
OPENROUTER_API_KEY: sk-or-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
USUAL_USBS_SERIALS: |
xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxx
git:
USER_EMAIL: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
USER_NAME: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMake sure your .nix files using config.sops.secrets, including ~/.config/nixos/secrets/sopsnix.nix, only reference secrets you have set in secrets.yaml
When you exit the editor the file becomes encrypted.
- Rebuild:
sudo nixos-rebuild switch --impure --flake "/home/nixos/.config/nixos#$hostname"Follow the above setup, then:
nix build "/home/nixos/.config/nixos#nixosConfigurations.iso.config.system.build.isoImage" -o "/home/nixos/.config/nixos/live_iso"
lsblk -pd # Find the usb. Must be the whole disk e.g. /dev/sdb and not /dev/sdb1
sudo umount /dev/sdb*
sudo dd bs=4M conv=fsync oflag=direct status=progress if=/home/nixos/.config/nixos/live_iso/iso/*.iso of=/dev/sdb
rm "/home/nixos/.config/nixos/live_iso"Python dependencies can be troublesome with NixOs's non-FHS filesystem. I either:
- Use distrobox and run an Ubuntu shell
- Use fix-python for something quick from my old laptop
~/.config/nixos/: Where this repo lives locally. It didn't necessarily have to be here but I chose this location./var/lib/sops-nix/key.txt: Decrypts sops secrets.~/projects/~/notes/~/restic-repo/: Where I backup the above paths to.
Set up a new dotfile:
- Add the dotfile in
~/.config/nixos/dotfiles/*/* - Reference it in
~/.config/nixos/scripts/stow.sh, and run the script, to symlink it where the program expects it.
| Program | Reload options (not necessarily all) |
|---|---|
| River | Log out (Super+Shift+E) and back in. |
riverctl COMMAND (avoids logging out) |
|
| Kanata | sudo nixos-rebuild switch --impure --flake "/home/nixos/.config/nixos#$hostname" |
systemctl stop kanata-default; kanata -c ~/.config/nixos/dotfiles/kanata/kanata.kbd |
|
| Helix | :config-reload |
| Ghostty | Press ctrl+shift+, (default for reload_config) |
| Mako | makoctl reload |
| Tmux | tmux source ~/.tmux.conf |
| Fish | source ~/.config/fish/config.fish |
| Lazygit | Open a new instance |
| Yazi | Open a new instance |
| Claude-code | Open a new instance |
| sigoden/aichat | Open a new instance |
- Specify the package in
config.environment.systemPackages; Seeconfiguration.nix. - Rebuild
sudo nixos-rebuild switch --impure --flake "/home/nixos/.config/nixos#$hostname"
- (Optional) Change
inputs.nixpkgs.urlinflake.nix - Run
nix flake updateornix flake update nixkpgs - Rebuild
sudo nixos-rebuild switch --impure --flake "/home/nixos/.config/nixos#$hostname"
I avoid doing that, as a software consumer. If a program doesn't work on my nixpkgs version, I pass on it until it does.
I made scripts for my usual backup sceneraios. They are just thin wrappers around the restic CLI:
~/.config/nixos/scripts/restic_backup.sh: Do a backup.~/.config/nixos/scripts/restic_copy.sh: Copy the backup to drives.~/.config/nixos/scripts/restic__backup_and_copy.sh: Call the above two sequentially.
|
fish set REPO /run/media/nixos/USB1/restic-repo
set RESTORE_PATH "$HOME/restic-restored/"
restic restore latest -r "$REPO" --target "$RESTORE_PATH"
sudo mkdir -p /var/lib/sops-nix
sudo cp $RESTORE_PATH/var/lib/sops-nix/key.txt /var/lib/sops-nix/key.txt
sudo chown nixos:users /var/lib/sops-nix/key.txt && sudo chmod 600 /var/lib/sops-nix/key.txt
sudo cp $RESTORE_PATH/home/nixos/.config/nixos/private /home/nixos/.config/nixos/private -r
sudo cp $RESTORE_PATH/home/nixos/projects /home/nixos/projects -r
sudo cp $RESTORE_PATH/home/nixos/notes /home/nixos/notes -r
sudo cp $REPO /home/nixos/restic-repo -r
sudo chown -R nixos:users /home/nixos
sudo rm $RESTORE_PATH -r
sudo nixos-rebuild switch --impure --flake "/home/nixos/.config/nixos#$hostname" |
bash REPO=/run/media/nixos/USB1/restic-repo
RESTORE_PATH="$HOME/restic-restored/"
restic restore latest -r "$REPO" --target "$RESTORE_PATH"
sudo mkdir -p /var/lib/sops-nix
sudo cp $RESTORE_PATH/var/lib/sops-nix/key.txt /var/lib/sops-nix/key.txt
sudo chown nixos:users /var/lib/sops-nix/key.txt && sudo chmod 600 /var/lib/sops-nix/key.txt
sudo cp $RESTORE_PATH/home/nixos/.config/nixos/private /home/nixos/.config/nixos/private -r
sudo cp $RESTORE_PATH/home/nixos/projects /home/nixos/projects -r
sudo cp $RESTORE_PATH/home/nixos/notes /home/nixos/notes -r
sudo cp $REPO /home/nixos/restic-repo -r
sudo rm $RESTORE_PATH -r
sudo nixos-rebuild switch --impure --flake "/home/nixos/.config/nixos#$hostname" |
sops-nix enables referencing the secrets from the nixos config.
- Run sops
~/.config/nixos/scripts/sops.sh. This unencrypts the file and opens it in $EDITOR, where you add/edit secrets. - Save and exit; The file becomes encrypted again.
- To access a secret from the nixos config (and also expose it at
/run/secrets/$SECRET, depending on who you set as the owner):
- Reference it in
~/.config/nixos/secrets/sopsnix.nix - Reference it wherever you want to use it in the config with
config.sops.secrets.SECRET.path - Rebuild
sudo nixos-rebuild switch --impure --flake "/home/nixos/.config/nixos#$hostname"
- To access a secret from the shell prompt, or a script:
cat /run/secrets/$SECRETWARNING:
- It might be better to have the secrets referenced in
sopsnix.nixbe owned by systemd services and not the user. - Access through /run/secrets/$SECRET might be problematic if a program keeps a history of the outputs of shell commands.
- I might remove the access through /run/secrets/$SECRET.
Click
-
For automating program installation:
- No automation, download from a website on
Windowsor usewget. Ansiblescripts (too unreliable, always had to tweak something) onPopOs (Ubuntu)NixOs(now)
- No automation, download from a website on
-
For managing dotfiles:
- Save them 1 by 1 to an usb/cloud and copy them over to a new machine.
Chezmoi(too bothersome for a one machine setup)NixOs home-manager(same as chezmoi, and also I felt like it does too many things under thehome-managerumbrella)Gnu Stow(now)