Declarative system configuration used on my 2018 Intel Macbook Pro.
$ nix-info -m && date
- system: `"x86_64-darwin"`
- host os: `Darwin 23.4.0, macOS 10.16`
- multi-user?: `no`
- sandbox: `yes`
- version: `nix-env (Nix) 2.19.2`
- nixpkgs: `not found`
Mon Mar 18 09:12:30 PDT 2024
Check out my blog post Fearless Tinkering with Nix for an introduction to and conceptual overview of Nix covering:
- what problems nix solves
- the architecture of nix and the software engineering philosophies that shape it
- ways that nix and its ecosystem can be used
NixOS allows users to define their entire system configuration in a declarative manner via the Nix expression language. This includes specifying packages, services, users, and other system settings. The declarative nature of NixOS ensures that the system configuration is version-controllable, reproducible, and easy to share. It also simplifies system administration by providing a single source of truth for the entire system state.
Outside of NixOS, declarative system configuration can be achieved on MacOS through various Nix-based tools like home-manager
and nix-darwin
. These tools work with both standard and flake
-based approaches:
System Configuration | Platforms | Configuration File | Configuration Options | Notes |
---|---|---|---|---|
NixOS | NixOS | configuration.nix |
Available in Manual or NixOS Options Search | |
Home-Manager | NixOS, Linux, MacOS | home.nix |
accounts , home , launchd , nix , programs , services , systemd , targets.darwin , wayland , xdg , xsession |
Can also be configured as NixOS module or nix-darwin module |
Nix-Darwin | MacOS | darwin-configuration.nix |
enviroment , homebrew , launchd , networking , nix , programs , services , system , users |
Can manage homebrew package installations (ex. brew install foo ) |
dotnix
(this repo) is a flake-based system configuration for my machine powered by both Nix-Darwin and Home-Manager.
File | Purpose | Notes |
---|---|---|
darwin.nix |
My system configuration via nix-darwin including: • packages from nixpkgs • packages from homebrew • MacOS settings (dock, scroll direction, etc) ...and more |
• Nix-Darwin Options - pre-defined configurations available with nix-darwin • NixPkgs - package repository + binary cache with 100k+ available packages |
home.nix |
My system configuration via home-manager including: • apps (1Password, Firefox, VSCode) • dev settings ( .git , .bashrc )• CLI tools ( bat , fzf , jq )...and more |
• Home-Manager Manual - tool for declaratively managing system configuration, dotfiles, etc • Home-Manager Options & Options Search - pre-defined configurations available with home-manager |
flake.nix |
Takes Nix expressions as input, then output things like package definitions, development environments, or, as is the case here, system configurations. For this specific repository, we can think of it as wrapping darwin.nix and home.nix in order to provide it pinned dependencies and manage the outputs. |
• Zero to Nix Glossary • xeiaso's Nix Flake Guides |
flake.lock |
Pins dependencies used in flake inputs | |
bin/apply-system.sh |
Script to initialize and apply system configuration. Also downloads homebrew binary outside of nix, and configures default shell | Simple nix run nix-darwin -- switch invocation (same as running darwin-rebuild switch ) |
bin/apply-system.sh |
Script to apply system configuration | Simple nix run nix-darwin -- switch invocation (same as running darwin-rebuild switch ) |
bin/update-system.sh |
Script to update dependencies | Simple nix flake update invocation |
Software installed with dotnix
is specified in following ways:
- Home-Manager Options
- Via
programs.*
inhome.nix
- Via
- Nixpkgs Package Set
- Via
home.packages
inhome.nix
, corresponding tonixpkgs
release atflake.nix:inputs.nixpkgs.url
- Via
- Flake Inputs
- Via
inputs
inflake.nix
and pinned inflake.lock
- Via
System-wide nix
settings are specified in home.nix
under the following declarations:
nix.package
- Determines which version of
nix
is used- Has matching declaration under
home.packages.config.nix.package
- Has matching declaration under
- Determines which version of
home.sessionVariables
- Environment variables set at login
nix.settings
- Replaces configuration that's usually found at
/etc/nix/nix.conf
- Sets feature flags, binary cache keys and locations, etc
- Replaces configuration that's usually found at
nix.registry
- Replaces configuration that's usually found at
/etc/nix/registry.json
- Same as default found at https://github.com/NixOS/flake-registry
-
"The flake registry serves as a convenient method for the Nix CLI to associate short names with flake URIs, such as linking
nixpkgs
togithub:NixOS/nixpkgs/nixpkgs-unstable.
"
-
- Replaces configuration that's usually found at
- Install
nix
Follow the Zero-to-Nix Quickstart Guide for a flake-based nix
installation.
- Setup
dotnix
repo
$ mkdir -p ~/.config
$ cd ~/.config
$ git clone https://github.com/hkscarf/dotnix
FIXME TODO - Need to describe configuring. Replacing hostname, user, home dir, etc
- Apply system configurations
$ cd ~/.config/dotnix/
$ ./bin/init-system.sh
- Modify configuration files
For example, add a new package to install in darwin.nix
or move to a newer release of nixpkgs
in flake.nix
.
- Apply system configurations
$ cd ~/.config/dotnix/
$ ./bin/apply-system.sh
- Update dependencies in
flake.lock
$ cd ~/.config/dotnix/
$ ./bin/update-system.sh
- Apply system configurations
$ cd ~/.config/dotnix/
$ ./bin/apply-system.sh
Declarative macOS Configuration - Using nix-darwin
and home-manager
: https://xyno.space/post/nix-darwin-introduction
Setting up Nix on macOS: https://davi.sh/til/nix/nix-macos-setup/
Switching to nix-darwin and Flakes: https://evantravers.com/articles/2024/02/06/switching-to-nix-darwin-and-flakes/