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.
Check out the starter templates below to get started!
.
├── 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-darwin
andnix-homebrew
- Disk Management: Declarative disk management with
disko
, say goodbye to disk utils - Secrets Management: Declarative secrets with
agenix
for 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-manager
module 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: manage 10000 d 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 --install
Thank you for the installer, Determinate Systems!
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
This is a simplified version without secrets management.
nix flake init -t github:dustinlyons/nixos-config#starter
This is a full version with secrets management.
nix flake init -t github:dustinlyons/nixos-config#starterWithSecrets
Run this script to replace stub values with your username, full name, and email.
chmod +x bin/apply && bin/apply
You can search for packages on the official NixOS website.
Review these files
darwin/casks
darwin/packages
darwin/home-manager
nixos/packages
shared/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_ed25519
andid_ed25519_agenix
.
nix run github:dustinlyons/nixos-config#copyKeys
nix run github:dustinlyons/nixos-config#createKeys
If you're rolling your own, just check they are installed correctly.
nix run github:dustinlyons/nixos-config#checkKeys
First-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-darwin
Then, 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/build
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_ed25519
andid_ed25519_agenix
.
nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#copyKeys
nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#createKeys
If you're rolling your own, just check they are installed correctly.
nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#checkKeys
After 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
nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#install
With secrets
nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#installWithSecrets
On first boot at the login screen:
- Use the shortcut
Ctrl-Alt-F2
to move to a terminal session - Login as
root
using 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#live
With 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 .#macos
bin/build
sudo nixos-rebuild switch --flake .#nixos
bin/build
nix 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