CI Workflow | Target Platform | CI Job Status |
---|---|---|
NixOS System Configuration | NixOS | |
Home Manager User Configuration | Linux / macOS | |
Nix-on-Droid | Android | (not implemented yet) |
This repo contains my personal system configuration that consists of:
- My config for NixOS
- My config for Home Manager
- My dconf (written in Nix) for the Gnome Desktop Environment
- My ZFS partitioning and formatting script
- My dotfiles for Git, Fish, NeoVim, EditorConfig, Prettier
- My config for Nix-on-Droid (WIP)
- Old install scripts (tested on: {see CI matrix above})
It includes a Nix Flake file which acts as an entrypoint for Nix and defines the following outputs:
nixosConfigurations.*
- NixOS system configurationshomeConfigurations.*
- Nix Home Manager configurationnixOnDroidConfigurations.*
- Nix-on-Droid configuration for Nix-powered Android shell environment
flowchart TD
A(1. Fork this repo)
B(2. Create a branch for your configuration)
C(3. Customize your configuration)
D(4. Apply system and home configuration)
E(5. Keep your fork up to date)
subgraph Start
direction LR
A --> B
end
Start --> Loop
subgraph Loop
direction TB
E --> C
C --> D
D --> E
end
You most likely want to update some of these things:
- Git username and email - edit this file
- NixOS username - edit
defaultUser
in flake.nix - Commit your NixOS machine config under
nixos/machines
- Update
home.sessionVariables
- Add/remove home packages in
nixos/home/pkg-sets
- Switch to latest Home Manager configuration:
(no
home-manager switch --flake $CFG#$USER
sudo
or reboot necessary) - Switch to latest NixOS system configuration:
(updating the kernel requires reboot, while changes to services (e.g. enabling docker, or updating the firewall rules) don't)
sudo nixos-rebuild switch --flake "$CFG#$(hostname)"
First, check your git remotes. You should have one pointing to your fork and one
pointing to this repo. In this case petar
points to this repo and origin
points to yours.
git remote -v
origin [email protected]:<your-fork>/dotfiles.git (fetch)
origin [email protected]:<your-fork>/dotfiles.git (push)
petar https://github.com/PetarKirov/dotfiles.git (fetch)
petar https://github.com/PetarKirov/dotfiles.git (push)
(The choice of SSH for the fork and HTTPS for the original repo in the URL schema is deliberate to signify that the original repo is read-only, while the fork is read/write.)
Next simply pull from the original repo and rebase your branch on top:
git pull --rebase petar main
To update only the packages managed by home-manager (no sudo
or restart
needed):
git pull --rebase petar main && home-manager switch --flake $CFG#$USER
To update everything and restart:
git pull --rebase petar main \
&& home-manager switch --flake $CFG#$USER \
&& sudo nixos-rebuild switch --flake "$CFG#$(hostname)" \
&& reboot
If you want to maintain a completely independent fork, or if you just want to update dependencies on your own schedule, you can manually update the flake inputs like this:
nix flake update $CFG
The versions of most software installed on the system are determined by the
Nixpkgs commit hash stored in the flake.lock
file. Running the command above
will update it (and the other flake inputs) to latest version.
-
Boot into a live NixOS environment
-
Generate a
hostid
for the target system:echo "$(tr -dc 0-9a-f < /dev/urandom | head -c 8)"
-
Update
/etc/nixos/configuration.nix
of the live NixOS environment like so:{ config, pkgs, ... }: { imports = [ <nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix> ]; networking.hostId = "<enter the hostid obtained at step 2>"; nix = { trustedUsers = [ "root" "nixos" ]; extraOptions = '' experimental-features = nix-command flakes ''; }; }
# Open the file and change it to the snippet below: sudo vim /etc/nixos/configuration.nix # Once the file has been updated and saved, apply the settings: sudo nixos-rebuild switch
These settings will ensure that you're using a recent enough version of Nix with the necessary features enabled and that ZFS will set the right hostid when partitioning the storage drive.
-
Clone this repo:
git clone https://github.com/PetarKirov/dotfiles && cd dotfiles
-
Assuming that you're installing NixOS on a clean drive, run the automated ZFS partitioning tool:
- Run it in "dry-run" mode to get information about your system:
./utils/make_zfs.bash
- If you need to partition your drive run:
env DRY_RUN=0 KEEP_PARTITIONS=0 ./utils/make_zfs.bash
- If your drive is already partitioned, run:
env DRY_RUN=0 ./utils/make_zfs.bash
Now there should be a root ZFS partition mounted at
/mnt
, a boot partition at/mnt/boot
and a swap partition. - Run it in "dry-run" mode to get information about your system:
-
Pick a name for the machine and generate the NixOS config, which you'll edit manually:
export MACHINE=machine-name mkdir ./nixos/machines/$MACHINE sudo nixos-generate-config \ --root /mnt \ --dir /..$(git rev-parse --show-toplevel)/nixos/machines/$MACHINE
Your files were automatically generated under
../dotfiles/nixos/machines/$MACHINE/
. -
Update them manually to match the format of the other machines under
./nixos/machines
(e.g. separatefile-systems.nix
file).Tip: use
lsblk
to list the storage devices bypartuuid
:lsblk -o KNAME,SIZE,PARTUUID,MOUNTPOINTS
-
Copy the
dotfiles
repo inside the user's home dir in order to persist the changes we did in the live environmentsudo mkdir -p /mnt/home/$USER/code/repos sudo cp -a ../dotfiles /mnt/home/$USER/code/repos
-
With everything configured we can now perform the actual NixOS installation:
sudo nixos-install --impure --flake ".#$MACHINE" --root /mnt
-
Now that NixOS has been installed on the target drive, chroot into it (using
nixos-enter
) and change the password of the default user:sudo nixos-enter --root /mnt passwd $THE_USER_NAME exit
(Replace
$THE_USER_NAME
in the command above with the your username.) -
Reboot into the new NixOS install and activate the home-manager config:
# Home Manager generates config files for Fish which may conflict with the # default fish files. Delete the default ones to prevent any conflicts: rm -rf /home/$USER/.config/fish # Change the owner of the repo to your own user: sudo chown -R $USER ~/code # Build and activate Home Manager nix build -L --json ~/code/repos/dotfiles#homeConfigurations.$USER.activationPackage \ | jq -r '.[].outputs | to_entries[].value' \ | xargs -I@@ sh -c '@@/activate'
-
You're done!
- Find Nix packages: https://search.nixos.org/packages
- Browse NixOS configuration options:
- Full list (on a single page): https://nixos.org/manual/nixos/stable/options.html
- Search: https://search.nixos.org/options
- Home Manager docs: https://nix-community.github.io/home-manager/
- Home Manager options: https://nix-community.github.io/home-manager/options.html
- Nix Language
- Overview: https://nixery.dev/nix-1p.html
- Nix cheatsheet: https://learnxinyminutes.com/docs/nix
- Interactive tour of Nix: https://nixcloud.io/tour/?id=1
- Official docs: https://nixos.org/manual/nix/stable/expressions/writing-nix-expressions.html
- Nix Flakes
- An introduction: https://christine.website/blog/nix-flakes-1-2022-02-21
- Official docs: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html
- Cachix: https://www.cachix.org
- Nix Direnv: https://github.com/nix-community/nix-direnv
- Direnv: https://direnv.net/