bsarden / nix-config

Nix configuration for MacOS and NixOS w/ starter templates + step-by-step guides ✨

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Nix for MacOS + NixOS

Build Starter Template

Overview

Hey, you made it! Welcome. 🤓

Nix is a powerful package manager for Linux and Unix systems that ensures reproducible, declarative, and reliable software management.

This repository contains configuration for a general-purpose development environment that runs on MacOS, NixOS, or both simultaneously.

I use it daily on my 🧑🏻‍💻 M1 Macbook Pro and an x86 PC in my home office. It also runs as a VM on your Mac. Others have reported that it's working for them too.

Check out the starter templates and step-by-step commands below to get started!

Table of Contents

Layout

.
├── 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

Features

  • Nix Flakes: 100% flake driven, no configuration.nix, no Nix channels─ just flake.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: Zero maintenance homebrew environment with nix-darwin and nix-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: 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

Videos

MacOS

Updating dependencies with one command

Build.mov

Instant Emacs 29 thanks to daemon mode

  • GUI
Emacs.mov
  • Terminal
Emacs_Terminal.mov

NixOS

NixOS.mp4

Installing

Important

Note: Nix 2.18 currently has a bug that impacts this repository.

For now, if you run into errors like this:

error: path '/nix/store/52k8rqihijagzc2lkv17f4lw9kmh4ki6-gnugrep-3.11-info' is not valid

Run nix copy to make the path valid.

nix copy --from https://cache.nixos.org /nix/store/52k8rqihijagzc2lkv17f4lw9kmh4ki6-gnugrep-3.11-info

For MacOS

I've tested these instructions on a fresh Macbook Pro as of September 2023.

1. Install dependencies

xcode-select --install

2. Install Nix

Thank you for the installer, Determinate Systems!

curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install

3. Initialize a starter template

This is a simplified version without secrets management.

mkdir -p nixos-config && (cd nixos-config && nix flake --extra-experimental-features 'nix-command flakes' init -t github:dustinlyons/nixos-config#starter)

This is a full version with secrets management.

mkdir -p nixos-config && (cd nixos-config && nix flake --extra-experimental-features 'nix-command flakes' init -t github:dustinlyons/nixos-config#starterWithSecrets)

4. Apply your current user info

Run this script to replace stub values with your username, full name, and email.

chmod +x bin/apply && bin/apply

5. Decide what packages to install

You can search for packages on the official NixOS website.

Review these files

  • darwin/casks
  • darwin/packages
  • darwin/home-manager
  • nixos/packages
  • shared/packages

6. Optional: Setup secrets

If you are using the starter with secrets, there are a few additional steps.

6a. Create a private Github repo to hold your secrets

In Github, create a private nix-secrets repository. You'll enter this name during installation.

6b. Install keys

Before generating your first build, these keys must exist in your ~/.ssh directory. Don't worry, we provide a few commands to help you.

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.

You must one run of these commands:

Copy keys from USB drive

This script auto-detects a USB drive connected to the current system.

Keys must be named id_ed25519 and id_ed25519_agenix.

nix run github:dustinlyons/nixos-config#copyKeys
Create new keys
nix run github:dustinlyons/nixos-config#createKeys
Check existing keys

If you're rolling your own, just check they are installed correctly.

nix run github:dustinlyons/nixos-config#checkKeys

7. Install configuration

First-time installations require you to move the current /etc/nix/nix.conf out of the way.

[ -f /etc/nix/nix.conf ] && sudo mv /etc/nix/nix.conf /etc/nix/nix.conf.before-nix-darwin

If you're using a git repository, only files in the working tree will be copied to the Nix Store.

So it's imperative you run git add ..

Then, run bin/build, which wraps a few Nix commands to build and deploy a new Nix generation.

chmod +x bin/darwin-build && chmod +x bin/build && bin/build

For NixOS

This configuration supports both x86_64 and aarch64 platforms.

1. Burn the latest ISO

Download and burn the minimal ISO image to a USB, or create a new VM with the ISO as base.

Note, if you're building a VM on an Apple Silicon Mac, choose 64-bit ARM.

Quick Links

Boot the installer.

2. Optional: Setup secrets

If you are using the starter with secrets, there are a few additional steps.

2a. Create a private Github repo to hold your secrets

In Github, create a private nix-secrets repository. You'll enter this name during installation.

2b. Install keys

Before generating your first build, these keys must exist in your ~/.ssh directory. Don't worry, we provide a few commands to help you.

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.

You must one run of these commands:

Copy keys from USB drive

This script auto-detects a USB drive connected to the current system.

Keys must be named id_ed25519 and id_ed25519_agenix.

sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#copyKeys
Create new keys
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#createKeys
Check existing keys

If you're rolling your own, just check they are installed correctly.

sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#checkKeys

3. Install configuration

Run command

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, or you will see a blank screen.

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#install

With secrets

sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#installWithSecrets

4. Set user password

On first boot at the login screen:

  • Use the shortcut Ctrl-Alt-F2 (or Fn-Ctrl-Option-F2 if on a Mac) 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

How to create secrets

To create a new secret secret.age, first create a secrets.nix file at the root of your nix-secrets repository. This will only be used by the agenix CLI command.

secrets.nix

let
  user1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH";
  users = [ user1 ];

  system1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE";
  systems = [ system1 ];
in
{
  "secret.age".publicKeys = [ user1 system1 ];
}

Next, run the 'create secret' 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.

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 nix-secrets repository. References look like

{
  "secret.age".publicKeys = [ user1 system1 ];
}

where "secret.age" is your new filename.

Example

So, let's say I wanted to create a new secret to hold my Github SSH key.

I would cd into my nix-secrets repo directory, verify the agenix configuration (named secrets.nix) exists, then run

EDITOR=vim nix run github:ryantm/agenix -- -e github-ssh-key.age

This would start a vim session.

I would enter insert mode :i, copy+paste the key, hit Esc and then type :w to save it, resulting in the creation of a new file, github-ssh-key.age.

Next, I would edit secrets.nix to include a line specifying the public key to use for my new secret. I specify a user key, but I could just as easily specify a host key.

secrets.nix

let
  dustin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH";
  users = [ dustin ];
  systems = [ ];
in
{
  "github-ssh-key.age".publicKeys = [ dustin ];
}

Then I'd commit all changes to the nix-secrets repository, go back to my nixos-config and run nix flake update to update the lock file.

Now, all that's left is using the secret in my configuration.

Live ISO

Not yet available. Coming soon.

nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#live

Deploying changes to your system

With Nix, changes to your system are made by

For MacOS

nix build .#darwinConfigurations.macos.system && \
./result/sw/bin/darwin-rebuild switch --flake .#macos

Optional script to save keystrokes

bin/build

For NixOS

Choose the flake target for your platform.

sudo nixos-rebuild switch --flake .#x86_64-linux
sudo nixos-rebuild switch --flake .#aarch64-linux

Optional script to save keystrokes

bin/build

Update dependencies

nix flake update

Compatibility and Testing

This configuration has been tested and confirmed working on the following platforms:

  • M1 Apple Silicon
  • Bare metal x86_64 PC
  • NixOS inside VMWare on MacOS
  • MacOS Sonoma inside Parallels on MacOS

Contributing

Interested in contributing to this project? Here's how you can help:

  • Code Contributions: If you're interested in contributing code, please start by looking at open issues or feature requests. Fork the repository, make your changes, and submit a pull request. Make sure your code adheres to the existing style. For significant changes, consider opening an issue for discussion before starting work.

  • Reporting Bugs: If you encounter bugs or issues, please help by reporting them. Open a GitHub Issue and include as much detail as possible: what you were doing when the bug occurred, steps to reproduce the issue, and any relevant logs or error messages. This information will be invaluable in diagnosing and fixing the problem.

Feedback and Questions

Have feedback or questions? Feel free to use the discussion forum.

License

This project is released under the MIT License.

Appendix

Why Nix Flakes

Reasons to jump into flakes and skip nix-env, Nix channels, etc

  • Flakes work just like other package managers you already know: npm, cargo, poetry, composer, etc. Channels work more like traditional Linux distributions (like Ubuntu), which most devs don't know.
  • Flakes encapsulate not just project dependencies, but Nix expressions, Nix apps, and other configurations in a single file. It's all there in a single file. This is nice.
  • Channels lock all packages to one big global nixpkgs version. Flakes lock each individual package to a version, which is more precise and makes it much easier to manage overall.
  • Flakes have a growing ecosystem (see Flake Hub or Dev Env), so you're future-proofing yourself.

NixOS Components

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

Stars

"All we have to decide is what to do with the time that is given us." - J.R.R. Tolkien

Star History Chart

Support

Buy me a coffee or follow me on Twitter.

About

Nix configuration for MacOS and NixOS w/ starter templates + step-by-step guides ✨

License:MIT License


Languages

Language:Nix 68.0%Language:Shell 27.1%Language:Emacs Lisp 4.9%