Skip to content

My personal system and $HOME configuration managed by Nix

License

Notifications You must be signed in to change notification settings

PetarKirov/dotfiles

Repository files navigation

Nix Flakes-based System & Home Configuration, Dotfiles, and Install Scripts

CI Status

CI Workflow Target Platform CI Job Status
NixOS System Configuration NixOS NixOS
Home Manager User Configuration Linux / macOS Home Manager on Linux Home Manager on macOS
Nix-on-Droid Android (not implemented yet)

Overall status: Actions Status

Overview

This repo contains my personal system configuration that consists of:

It includes a Nix Flake file which acts as an entrypoint for Nix and defines the following outputs:

  • nixosConfigurations.* - NixOS system configurations
  • homeConfigurations.* - Nix Home Manager configuration
  • nixOnDroidConfigurations.* - Nix-on-Droid configuration for Nix-powered Android shell environment

Basic Usage

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
Loading

3. Customize your configuration

You most likely want to update some of these things:

  1. Git username and email - edit this file
  2. NixOS username - edit defaultUser in flake.nix
  3. Commit your NixOS machine config under nixos/machines
  4. Update home.sessionVariables
  5. Add/remove home packages in nixos/home/pkg-sets

4. Apply home and system configuration

  • Switch to latest Home Manager configuration:
    home-manager switch --flake $CFG#$USER
    (no sudo or reboot necessary)
  • Switch to latest NixOS system configuration:
    sudo nixos-rebuild switch --flake "$CFG#$(hostname)"
    (updating the kernel requires reboot, while changes to services (e.g. enabling docker, or updating the firewall rules) don't)

5. Keep your fork up to date

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

Putting everything together

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

Manually update all Nix Flake inputs

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.

Installing NixOS

  1. Boot into a live NixOS environment

  2. Generate a hostid for the target system:

    echo "$(tr -dc 0-9a-f < /dev/urandom | head -c 8)"
  3. 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.

  4. Clone this repo:

    git clone https://github.com/PetarKirov/dotfiles && cd dotfiles
  5. 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.

  6. 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/.

  7. Update them manually to match the format of the other machines under ./nixos/machines (e.g. separate file-systems.nix file).

    Tip: use lsblk to list the storage devices by partuuid:

    lsblk -o KNAME,SIZE,PARTUUID,MOUNTPOINTS
  8. Copy the dotfiles repo inside the user's home dir in order to persist the changes we did in the live environment

    sudo mkdir -p /mnt/home/$USER/code/repos
    sudo cp -a ../dotfiles /mnt/home/$USER/code/repos
  9. With everything configured we can now perform the actual NixOS installation:

    sudo nixos-install --impure --flake ".#$MACHINE" --root /mnt
  10. 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.)

  11. 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'
  12. You're done!

Nix Ecosystem Docs