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, rufus... 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"
export NIX_CONFIG="experimental-features = nix-command flakes"
nix run nixpkgs#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 "/home/nixos/.config/secretkey"
sudo chown -R nixos:users $RESTORE_PATH
mkdir -p /home/nixos/.config
cp $RESTORE_PATH/home/nixos/.config/nixos /home/nixos/.config/nixos -r
mkdir -p /home/nixos/.config/secretkey
cp $RESTORE_PATH/home/nixos/.config/secretkey/sops_private_key.txt /home/nixos/.config/secretkey/sops_private_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 where 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 "Cannot read ssh key" warnings, they resolve on first boot:
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 "setting up secrets"/ssh key and "su: Authentication service" warnings from
nixos-enter, they resolve on first boot
sudo mkdir -p /mnt/home/nixos/.config
sudo cp /home/nixos/.config/nixos /mnt/home/nixos/.config/nixos -r
sudo cp /home/nixos/.config/secretkey /mnt/home/nixos/.config/secretkey -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"- Reebot
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 set PUBLIC_KEY (age-keygen -o ~/.config/secretkey/sops_private_key.txt 2>&1 | sed 's/Public key: //')
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 export PUBLIC_KEY=$(age-keygen -o ~/.config/secretkey/sops_private_key.txt 2>&1 | sed 's/Public key: //')
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/secrets/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"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.~/.config/secretkey/sops_private_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.
REPO=/home/nixos/mnt/usb/restic-repo
RESTORE_PATH="$HOME/restic-restored/"
restic restore latest -r "$REPO" --target "$RESTORE_PATH"
mkdir /home/nixos/.config/secretkey
cp $RESTORE_PATH/home/nixos/.config/secretkey/sops_private_key.txt /home/nixos/.config/secretkey/sops_private_key.txt
cp $RESTORE_PATH/home/nixos/projects /home/nixos/projects -r
cp $RESTORE_PATH/home/nixos/notes /home/nixos/notes -r
cp $REPO /home/nixos/restic-repo -r
sudo rm $RESTORE_PATH -rsops-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)