~johnhamelink/Nix

My Nix configuration, spanning multiple machines

8986504 feat(Emacs): Refine eamcs capture commands (for org-capture and org-agenda)

4 days ago

7a01d32 feat: Improve and update slack-org-protocol-capture

4 days ago

A comprehensive NixOS configuration spanning multiple devices across GNU/Linux and Darwin.

#Features

  • Uses the Lix fork
  • Includes configurations for multiple devices
  • Secrets are stored in SOPS, GPG and git-crypt.
  • Includes a live ISO configuration that applies both NixOS and home-manager configuration into the ISO.

#Caveats

  • Designed for me, on my hardware, and for my purposes. It might not be suitable for you. That's OK!
  • I maintain this project because I am actively using it, so it changes without warning and I don't maintain a changelog. I do, however, try to keep my git commits relatively thoughtful, if you are curious about why I made a change.

#Bootstrapping

Install any necessary SSH & PGP keys to the target machine, then clone this repository.

# Ensure you can pull from the repo
eval $(ssh-agent)
ssh-add ~/.ssh/*

pushd .config
git clone git@git.sr.ht:~johnhamelink/nix
pushd nix

#NixOS Target (TODO)

WIP

# Enable sun as a Linux build server:
echo "ssh-ng://sun	x86_64-linux	/home/john/.ssh/id_sun	64	1	nixos-test,benchmark,big-parallel" | sudo tee -a /etc/nix/machines

echo "Host sun
  User john
  PasswordAuthentication no
  IdentityFile /Users/johnhamelink/.ssh/id_sun
" | sudo tee /etc/ssh/ssh_config.d/sun

#MacOS Target

# Set the hostname on the target device, then flush the cache and reboot
sudo scutil --set HostName neptune
sudo scutil --set ComputerName neptune
sudo scutil ---set LocalHostName neptune
dscacheutil -flushcache

sudo reboot

# SSH into the new hostname

# Install Nix using the determinate systems installer
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
exit
  
# Upgrade nix
sudo -i nix upgrade-nix
  
# Build base dir for nix flake
mkdir -p ~/.config
  
# Trigger the XCode installer GUI to install command line developer tools.
# On the target device, click through the installation dialogs.
xcode-select --install

# Approve sun as a known host to root user
sudo su -c ssh sun

# Acquire gpg & git-crypt, unlock the repo:
nix --extra-experimental-features nix-command \
    --extra-experimental-features flakes \
    shell nixpkgs#git-crypt nixpkgs#gnupg

gpg --import git-crypt-priv.key
git-crypt unlock

exit # Back to the outer shell

# Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
(echo; echo 'eval "$(/usr/local/bin/brew shellenv)"') >> /Users/johnhamelink/.zprofile
    eval "$(/usr/local/bin/brew shellenv)"

# Trigger the installation of the bundle tap
brew bundle

# Install the configuration
nix --extra-experimental-features nix-command \
    --extra-experimental-features flakes \
    run nix-darwin -- switch --flake ~/.config/nix

# Accept the XCode EULA
sudo xcodebuild -license accept

#Usage

#Nix-Darwin

# Use this Nix configuration
darwin-rebuild switch --flake .#

# Success!

#NixOS

# Switch to this NixOS configuration
sudo nixos-rebuild switch --flake .#

# Use nh for a nicer daily experience
nh os switch -u && nhs home switch -u

# Build a NixOS live ISO in ./result/iso/. See here to boot from QEMU:
# https://wiki.nixos.org/wiki/Creating_a_NixOS_live_CD#Testing_the_image
nix build .\#nixosConfigurations.saturn_iso.config.system.build.isoImage

#Home Manager

# Use the home-manager configuration
home-manager switch --flake .

# Read home-manager's NEWS:
home-manager news --flake .

#TODOs

  1. Build CI jobs for building these images
  2. Deploy CI to sun so that packages can be pre-compiled & pre-cached
  3. Setup Headscale
  4. Figure out how to deploy the git repo as a directory inside the filesystem of the Live ISO

#FAQ

#Why bother with declarative configuration?

I've had to reconfigure operating systems many many times over the years. Over those years I've formed a fairly detailed opinion on how I want my operating system to behave, and a declarative operating system such as Nix allows me to express these idioms in a reproducable way, while handling the indivdual requirements and nuances that individual machines may have (driver requirements, services aimed for a specific usecase, etc). Likewise, when I make improvements for one machine, it becomes trivial to deploy that change to all my devices.

#What about a Brewfile?

  • Homebrew only handles software installation, it doesn't provide a mechanism to implement configuration. Nix handles both.
  • Yes, homebrew can work on Linux, but it's not a well trodden path, and I want to work with software where free operating systems are first class, well supported citizens. Nix works well enough on MacOS, and great on Linux.

#Why not GNU Guix?

I really do need cross-compatibility with MacOS in order to be able to use this in work situations. I do really like Guix though, and I would like to maintain a Guix configuration for my Linux machines someday. Until then, this configuration scratches my itch.