This is a repository for my NixOS configuration.
You can boot from the custom ISO which comes with Git, my custom Neovim build, and flakes pre-enabled.
Download the latest pre-built ISO from the Releases page, or build it locally:
just isoThen write it to a flash drive:
just iso-install /dev/sdXNote
If you don't have the custom ISO, a standard NixOS installer works too. You will just need to enter a Nix shell with Git first:
nix-shell -p git-
Clone the Git repository.
git clone https://github.com/BastianAsmussen/dotfiles.git ~/dotfiles cd ~/dotfiles
-
Enter the provided Nix development shell.
nix develop
Note
On a standard NixOS installer without flakes enabled, use the compatibility shell instead:
nix-shell --experimental-features 'nix-command flakes'-
Choose a host.
-
View available host options.
HOSTNAME=$(ls modules/nixosModules/hosts | fzf) -
Set manually, e.g.
delta.HOSTNAME=delta
-
-
Set up the disk configuration.
just disko $HOSTNAME -
Finally, install NixOS with the given configuration.
just install $HOSTNAME
-
error: creating pipe: Too many open filesSimply increase the open file limit, i.e. setting it to
2048.ulimit -n 2048 -
warning: download buffer is full; consider increasing the 'download-buffer-size' settingIt's worth to consider increasing the download buffer during installation. Like the warning suggests, this can be accomplished by increasing the
download-buffer-sizesetting; pass--option download-buffer-size nwherenis the buffer size to thejust installcommand from step 3.
Hosts with LUKS-encrypted disks (e.g. epsilon, delta) use
fido2-device=auto in their disko configs so the LUKS volume can be unlocked
with a FIDO2 token (such as a YubiKey) instead of typing a passphrase.
FIDO2 tokens are not enrolled automatically! You must enroll them manually
after installation. Without enrollment the Tokens: section in luksDump will
be empty and the system will fall back to a password prompt.
# Main disk (contains root filesystem).
just fido2-enroll /dev/nvme0n1p3
# Extra disk (marked nofail, won't block boot).
just fido2-enroll /dev/nvme1n1p1You can verify enrollment succeeded:
sudo cryptsetup luksDump /dev/nvme0n1p3 | grep -A5 'Tokens'A successfully enrolled token will show a systemd-fido2 entry under
Tokens: instead of an empty section.
Disko generates systemd units that reference disks by GPT partition label
(e.g. /dev/disk/by-partlabel/disk-extra-luks). If a disk was partitioned
outside of disko the label may not exist and systemd will time out waiting for
it at boot.
To fix this, set the label manually (non-destructive, only changes the GPT name, not data):
# For the extra NVMe:
sudo sgdisk -c 1:disk-extra-luks /dev/nvme1n1The extra NVMe (extra_lvm) and backup (/dev/sda) volumes are marked with
nofail in both their crypttab and mount options. This means:
- If the disk is missing or its partition label doesn't exist, boot continues normally instead of hanging for 90 seconds and failing.
- The main disk (
luks_lvm) intentionally does not havenofailbecause it contains/,/nix, and/home.
This config uses sops-nix with age-format keys to manage secrets. There are two kinds of access keys:
- User key: A standalone key for editing and maintaining
secrets.yamlfrom any machine. - Host key: Derived from the host's SSH ed25519 key so
sops-nixcan decrypt secrets during NixOS builds.
Create a personal age key at the default path sops-nix looks for:
just age-keygenThe public key is printed to the terminal. Back up the contents of keys.txt
somewhere safe (e.g. a password manager).
To re-print the public key later:
age-keygen -y ~/.config/sops/age/keys.txtEach NixOS host already has an SSH host key created when openssh is enabled.
Derive an age public key from it:
just age-host-keyNote
The sops module in this config (modules/nixosModules/features/sops.nix)
already points sops.age.sshKeyPaths at /etc/ssh/ssh_host_ed25519_key and
sets generateKey = true, so the private side is handled automatically at
activation time.
Add the public keys to the .sops.yaml file in your secrets repository:
keys:
- &user_alice age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- &host_kappa age1yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
creation_rules:
- path_regex: secrets\.yaml$
key_groups:
- age:
- *user_alice
- *host_kappaAfter updating .sops.yaml, re-encrypt secrets.yaml so the new keys can
access it:
sops updatekeys secrets.yaml-
I recommend updating the flake.lock file about once per week.
just upgrade
Note
If it can't build, roll back the flake.lock file to a previous version and rebuild:
just rollbackTip
The rebuild and upgrade commands accept extra arguments after the
hostname. For example, to enable verbose trace output:
just rebuild kappa --show-trace-
Move the host directory, e.g.
kappa->sigma.mv modules/nixosModules/hosts/kappa modules/nixosModules/hosts/sigma
-
Switch to new configuration.
just rebuild sigma
Warning
The hostname won't update automatically!
To update the hostname, either reboot the computer, or restart the current session.
-
Scaffold a new host from the minimal template.
just add-host zeta
-
Edit
modules/nixosModules/hosts/zeta/configuration.nixto add the modules and settings your new machine needs (hardware config, desktop, features, etc.). Seeepsilonordeltafor reference. -
Build and switch to the new host.
just rebuild zeta
I track stuff I need to get done and stuff that annoys me about my current
setup in a file called TODO.md.
If you have suggestions or notice something that could be improved, feel free
to open a pull request. I'll review and consider integrating your
contributions.
You can use this flake for development environment templates.
nix-shell -p jq --run "nix flake show self --json 2>/dev/null | jq '.templates | map_values(.description) | del(.default)'"Note
Because we override the Nix registry
here, we can simply use the self registry
entry which references this flake.
mkdir ~/Projects/example
cd ~/Projects/example
nix flake init -t self#rust
./init.sh