Hey, you made it! Welcome. 🤓
This Nix configuration runs on MacOS, NixOS, or both simultaneously. It's also a good example of a MacOS Nix flake.
I use this daily on my 🧑🏻💻 M1 Macbook Pro and an x86 PC in my home office. It also runs as a VM on your Mac.
Check out the starter templates below to get started!
- Nix for MacOS + NixOS
.
├── bin # Optional scripts used to run build/update
├── shared # Shared configurations applicable to all systems
├── darwin # MacOS and nix-darwin configuration
├── nixos # My NixOS desktop-related configuration
├── overlays # Drop an overlay file in this dir, and it runs. So far, mainly patches.
├── templates # Starter versions of this configuration
- Nix Flakes: 100% flake driven, no
configuration.nix, no Nix channels─ justflake.nix - Same Environment Everywhere: Easily share config across Linux and Mac (both Nix and Home Manager)
- MacOS Dream Setup: Fully declarative MacOS, including UI, dock and MacOS App Store apps
- Simple Bootstrap: Simple Nix commands to start from zero, both x86 and MacOS platforms
- Managed Homebrew: Fully managed homebrew environment with
nix-darwinandnix-homebrew - Disk Management: Declarative disk management with
disko, say goodbye to disk utils - Secrets Management: Declarative secrets with
agenixfor SSH, PGP, syncthing, and other tools - Super Fast Emacs: Bleeding edge Emacs that fixes itself, thanks to a community overlay
- Built In Home Manager:
home-managermodule for seamless configuration (no extra clunky CLI steps) - NixOS Environment: Extensively configured NixOS including clean aesthetic + window animations
- Nix Overlays: Auto-loading of Nix overlays: drop a file in a dir and it runs (great for patches!)
- Declarative Sync: No-fuss Syncthing: managed keys, certs, and configuration across all platforms
- Emacs Literate Configuration: Large Emacs literate configuration to explore (if that's your thing)
- Simplicity and Readability: Optimized for simplicity and readability in all cases, not small files everywhere
Build.mov
GUI
Emacs.mov
Terminal
Emacs_Terminal.mov
NixOS.mp4
I've tested these instructions on a fresh Macbook Pro as of September 2023.
xcode-select --installThank you for the installer, Determinate Systems!
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- installThis is a simplified version without secrets management.
nix flake init -t github:dustinlyons/nixos-config#starterThis is a full version with secrets management.
nix flake init -t github:dustinlyons/nixos-config#starterWithSecretsRun this script to replace stub values with your username, full name, and email.
chmod +x bin/apply && bin/applyYou can search for packages on the official NixOS website.
Review these files
darwin/casksdarwin/packagesdarwin/home-managernixos/packagesshared/packages
If you are using the starter with secrets, there are a few additional steps.
In Github, create a private nix-secrets repository.
Then, change the nix-secrets input in the flake.nix to reference it.
Before geneating your first build, these keys need to exist in your ~/.ssh directory. I've provided a few helper commands below. Choose one.
| Key Name | Platform | Description |
|---|---|---|
| id_ed25519 | MacOS / NixOS | Used to download secrets from Github. |
| id_ed25519_agenix | MacOS / NixOS | Used to encrypt and decrypt secrets. |
This script auto-detects a USB drive connected to the current system.
Keys must be named
id_ed25519andid_ed25519_agenix.
nix run github:dustinlyons/nixos-config#copyKeysnix run github:dustinlyons/nixos-config#createKeysIf you're rolling your own, just check they are installed correctly.
nix run github:dustinlyons/nixos-config#checkKeysFirst-time installations require you to move the current /etc/nix/nix.conf out of the way.
sudo mv /etc/nix/nix.conf /etc/nix/nix.conf.before-nix-darwinThen, run this script, which wraps the Nix commands to build and deploy a new Nix generation.
chmod +x bin/darwin-build && chmod +x bin/build && bin/buildThis configuration supports both x86_64 and aarch64 platforms.
Download and burn the minimal ISO image. Boot the installer.
If you are using the starter with secrets, there are a few additional steps.
In Github, create a private nix-secrets repository.
Then, change the nix-secrets input in the flake.nix to reference it.
Before geneating your first build, these keys need to exist in your ~/.ssh directory. I've provided a few helper commands below. Choose one.
| Key Name | Platform | Description |
|---|---|---|
| id_ed25519 | MacOS / NixOS | Used to download secrets from Github. |
| id_ed25519_agenix | MacOS / NixOS | Used to encrypt and decrypt secrets. |
This script auto-detects a USB drive connected to the current system.
Keys must be named
id_ed25519andid_ed25519_agenix.
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#copyKeyssudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#createKeysIf you're rolling your own, just check they are installed correctly.
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#checkKeysAfter the keys are in place, you're good to go. Run either of these commands:
Important
For Nvidia cards, select the second option, nomodeset, when booting the installer.
Warning
Running this will reformat your drive to the ext4 filesystem.
Simple
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#installWith secrets
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#installWithSecretsOn first boot at the login screen:
- Use the shortcut
Ctrl-Alt-F2to move to a terminal session - Login as
rootusing the password created during installation - Set the user password with
passwd <user> - Go back to the login screen:
Ctrl-Alt-F7
To create a new secret secret.age, first create a secrets.nix file at the root of your nix-secrets repository. This is only used by the agenix CLI command. It assumes your SSH private key is in ~/.ssh/ or you can provide the -i flag with a path to your id_ed25519 key.
let
user1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH";
users = [ user1 ];
system1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE";
systems = [ system1 ];
in
{
"secret.age".publicKeys = [ user1 system1 ];
}
Then run this command:
EDITOR=vim nix run github:ryantm/agenix -- -e secret.age
This opens an editor to accept, encrypt, and write your secret to disk. Commit the file to your nix-secrets repo and add a reference in the secrets.nix of your nixos-config.
| Secret Name | Platform | Description |
|---|---|---|
syncthing-cert |
MacOS / NixOS | Syncthing certificate |
syncthing-key |
MacOS / NixOS | Syncthing key |
github-ssh-key |
MacOS / NixOS | GitHub SSH key |
github-signing-key |
MacOS / NixOS | GitHub signing key |
These are the secrets I use.
When changing secrets after your configuration exists, be sure to run nix flake update from your nixos-config so that you reference the latest change.
Not yet available. Coming soon.
nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#liveWith Nix, changes to your system are made by
- editing your system configuration
- building the system closure
- creating and switching to the new generation
nix build .#darwinConfigurations.macos.system && \
./result/sw/bin/darwin-rebuild switch --flake .#macosbin/buildChoose the flake target for your platform.
sudo nixos-rebuild switch --flake .#x86_64sudo nixos-rebuild switch --flake .#aarch64bin/buildnix flake update| Component | Description |
|---|---|
| Window Manager | Xorg + bspwm |
| Terminal Emulator | alacritty |
| Bar | polybar |
| Application Launcher | rofi |
| Notification Daemon | dunst |
| Display Manager | lightdm |
| File Manager | thunar |
| Text Editor | emacs daemon mode |
| Media Player | cider |
| Image Viewer | feh |
| Screenshot Software | flameshot |
"All we have to decide is what to do with the time that is given us." - J.R.R. Tolkien