-
-
Save jmatsushita/5c50ef14b4b96cb24ae5268dab613050 to your computer and use it in GitHub Desktop.
### | |
### [2023-06-19] UPDATE: Just tried to use my instructions again on a fresh install and it failed in a number of places. | |
###. Not sure if I'll update this gist (though I realise it seems to still have some traffic), but here's a list of | |
###. things to watch out for: | |
### - Check out the `nix-darwin` instructions, as they have changed. | |
### - There's a home manager gotcha https://github.com/nix-community/home-manager/issues/4026 | |
### | |
# I found some good resources but they seem to do a bit too much (maybe from a time when there were more bugs). | |
# So here's a minimal Gist which worked for me as an install on a new M1 Pro. | |
# Inspired by https://github.com/malob/nixpkgs I highly recommend looking at malob's repo for a more thorough configuration | |
# | |
# Some people are coming directly to this Gist from search results and not the original post[1]. If that sounds like you, you should also know there is a video[2] that accompanies this. | |
# | |
# [1] https://discourse.nixos.org/t/simple-workable-config-for-m1-macbook-pro-monterey-12-0-1-with-nix-flakes-nix-darwin-and-home-manager/16834 | |
# [2] https://www.youtube.com/watch?v=KJgN0lnA5mk | |
# | |
# Let's get started | |
# | |
# Let's install nix (at the time of writing this is version 2.5.1 | |
curl -L https://nixos.org/nix/install | sh | |
# I might not have needed to, but I rebooted | |
mkdir -p ~/.config/nix | |
# Emable nix-command and flakes to bootstrap | |
cat <<EOF > ~/.config/nix/nix.conf | |
experimental-features = nix-command flakes | |
EOF | |
# Get the flake.nix in this gist | |
cd ~/.config | |
curl https://gist.githubusercontent.com/jmatsushita/5c50ef14b4b96cb24ae5268dab613050/raw/24a755065de59fc77a552518e106454750e86a49/flake.nix -O | |
# Get the configuration.nix and home.nix | |
curl https://gist.githubusercontent.com/jmatsushita/5c50ef14b4b96cb24ae5268dab613050/raw/24a755065de59fc77a552518e106454750e86a49/configuration.nix -O | |
curl https://gist.githubusercontent.com/jmatsushita/5c50ef14b4b96cb24ae5268dab613050/raw/24a755065de59fc77a552518e106454750e86a49/home.nix -O | |
# Until this is addressed https://github.com/LnL7/nix-darwin/issues/149 | |
sudo mv /etc/nix/nix.conf /etc/nix/.nix-darwin.bkp.nix.conf | |
# Build the configuration | |
nix build .#darwinConfigurations.j-one.system | |
./result/sw/bin/darwin-rebuild switch --flake . | |
# Enjoy! | |
# Might be useful to install x86 packages in the nix profile manually | |
nix profile install nixpkgs#legacyPackages.x86_64-darwin.haskellPackages.stack |
{ pkgs, lib, ... }: | |
{ | |
# Nix configuration ------------------------------------------------------------------------------ | |
nix.binaryCaches = [ | |
"https://cache.nixos.org/" | |
]; | |
nix.binaryCachePublicKeys = [ | |
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" | |
]; | |
nix.trustedUsers = [ | |
"@admin" | |
]; | |
users.nix.configureBuildUsers = true; | |
# Enable experimental nix command and flakes | |
# nix.package = pkgs.nixUnstable; | |
nix.extraOptions = '' | |
auto-optimise-store = true | |
experimental-features = nix-command flakes | |
'' + lib.optionalString (pkgs.system == "aarch64-darwin") '' | |
extra-platforms = x86_64-darwin aarch64-darwin | |
''; | |
# Create /etc/bashrc that loads the nix-darwin environment. | |
programs.zsh.enable = true; | |
# Auto upgrade nix package and the daemon service. | |
services.nix-daemon.enable = true; | |
# Apps | |
# `home-manager` currently has issues adding them to `~/Applications` | |
# Issue: https://github.com/nix-community/home-manager/issues/1341 | |
environment.systemPackages = with pkgs; [ | |
kitty | |
terminal-notifier | |
]; | |
# https://github.com/nix-community/home-manager/issues/423 | |
environment.variables = { | |
TERMINFO_DIRS = "${pkgs.kitty.terminfo.outPath}/share/terminfo"; | |
}; | |
programs.nix-index.enable = true; | |
# Fonts | |
fonts.enableFontDir = true; | |
fonts.fonts = with pkgs; [ | |
recursive | |
(nerdfonts.override { fonts = [ "JetBrainsMono" ]; }) | |
]; | |
# Keyboard | |
system.keyboard.enableKeyMapping = true; | |
system.keyboard.remapCapsLockToEscape = true; | |
# Add ability to used TouchID for sudo authentication | |
security.pam.enableSudoTouchIdAuth = true; | |
} |
{ | |
description = "Jun's darwin system"; | |
inputs = { | |
# Package sets | |
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-21.11-darwin"; | |
nixpkgs-unstable.url = github:NixOS/nixpkgs/nixpkgs-unstable; | |
# Environment/system management | |
darwin.url = "github:lnl7/nix-darwin/master"; | |
darwin.inputs.nixpkgs.follows = "nixpkgs-unstable"; | |
home-manager.url = "github:nix-community/home-manager"; | |
home-manager.inputs.nixpkgs.follows = "nixpkgs-unstable"; | |
# Other sources | |
comma = { url = github:Shopify/comma; flake = false; }; | |
}; | |
outputs = { self, darwin, nixpkgs, home-manager, ... }@inputs: | |
let | |
inherit (darwin.lib) darwinSystem; | |
inherit (inputs.nixpkgs-unstable.lib) attrValues makeOverridable optionalAttrs singleton; | |
# Configuration for `nixpkgs` | |
nixpkgsConfig = { | |
config = { allowUnfree = true; }; | |
overlays = attrValues self.overlays ++ singleton ( | |
# Sub in x86 version of packages that don't build on Apple Silicon yet | |
final: prev: (optionalAttrs (prev.stdenv.system == "aarch64-darwin") { | |
inherit (final.pkgs-x86) | |
idris2 | |
nix-index | |
niv | |
purescript; | |
}) | |
); | |
}; | |
in | |
{ | |
# My `nix-darwin` configs | |
darwinConfigurations = rec { | |
j-one = darwinSystem { | |
system = "aarch64-darwin"; | |
modules = attrValues self.darwinModules ++ [ | |
# Main `nix-darwin` config | |
./configuration.nix | |
# `home-manager` module | |
home-manager.darwinModules.home-manager | |
{ | |
nixpkgs = nixpkgsConfig; | |
# `home-manager` config | |
home-manager.useGlobalPkgs = true; | |
home-manager.useUserPackages = true; | |
home-manager.users.jun = import ./home.nix; | |
} | |
]; | |
}; | |
}; | |
# Overlays --------------------------------------------------------------- {{{ | |
overlays = { | |
# Overlays to add various packages into package set | |
comma = final: prev: { | |
comma = import inputs.comma { inherit (prev) pkgs; }; | |
}; | |
# Overlay useful on Macs with Apple Silicon | |
apple-silicon = final: prev: optionalAttrs (prev.stdenv.system == "aarch64-darwin") { | |
# Add access to x86 packages system is running Apple Silicon | |
pkgs-x86 = import inputs.nixpkgs-unstable { | |
system = "x86_64-darwin"; | |
inherit (nixpkgsConfig) config; | |
}; | |
}; | |
}; | |
# My `nix-darwin` modules that are pending upstream, or patched versions waiting on upstream | |
# fixes. | |
darwinModules = { | |
programs-nix-index = | |
# Additional configuration for `nix-index` to enable `command-not-found` functionality with Fish. | |
{ config, lib, pkgs, ... }: | |
{ | |
config = lib.mkIf config.programs.nix-index.enable { | |
programs.fish.interactiveShellInit = '' | |
function __fish_command_not_found_handler --on-event="fish_command_not_found" | |
${if config.programs.fish.useBabelfish then '' | |
command_not_found_handle $argv | |
'' else '' | |
${pkgs.bashInteractive}/bin/bash -c \ | |
"source ${config.programs.nix-index.package}/etc/profile.d/command-not-found.sh; command_not_found_handle $argv" | |
''} | |
end | |
''; | |
}; | |
}; | |
security-pam = | |
# Upstream PR: https://github.com/LnL7/nix-darwin/pull/228 | |
{ config, lib, pkgs, ... }: | |
with lib; | |
let | |
cfg = config.security.pam; | |
# Implementation Notes | |
# | |
# We don't use `environment.etc` because this would require that the user manually delete | |
# `/etc/pam.d/sudo` which seems unwise given that applying the nix-darwin configuration requires | |
# sudo. We also can't use `system.patchs` since it only runs once, and so won't patch in the | |
# changes again after OS updates (which remove modifications to this file). | |
# | |
# As such, we resort to line addition/deletion in place using `sed`. We add a comment to the | |
# added line that includes the name of the option, to make it easier to identify the line that | |
# should be deleted when the option is disabled. | |
mkSudoTouchIdAuthScript = isEnabled: | |
let | |
file = "/etc/pam.d/sudo"; | |
option = "security.pam.enableSudoTouchIdAuth"; | |
in '' | |
${if isEnabled then '' | |
# Enable sudo Touch ID authentication, if not already enabled | |
if ! grep 'pam_tid.so' ${file} > /dev/null; then | |
sed -i "" '2i\ | |
auth sufficient pam_tid.so # nix-darwin: ${option} | |
' ${file} | |
fi | |
'' else '' | |
# Disable sudo Touch ID authentication, if added by nix-darwin | |
if grep '${option}' ${file} > /dev/null; then | |
sed -i "" '/${option}/d' ${file} | |
fi | |
''} | |
''; | |
in | |
{ | |
options = { | |
security.pam.enableSudoTouchIdAuth = mkEnableOption '' | |
Enable sudo authentication with Touch ID | |
When enabled, this option adds the following line to /etc/pam.d/sudo: | |
auth sufficient pam_tid.so | |
(Note that macOS resets this file when doing a system update. As such, sudo | |
authentication with Touch ID won't work after a system update until the nix-darwin | |
configuration is reapplied.) | |
''; | |
}; | |
config = { | |
system.activationScripts.extraActivation.text = '' | |
# PAM settings | |
echo >&2 "setting up pam..." | |
${mkSudoTouchIdAuthScript cfg.enableSudoTouchIdAuth} | |
''; | |
}; | |
}; | |
}; | |
}; | |
} |
{ config, pkgs, lib, ... }: | |
{ | |
home.stateVersion = "22.05"; | |
# https://github.com/malob/nixpkgs/blob/master/home/default.nix | |
# Direnv, load and unload environment variables depending on the current directory. | |
# https://direnv.net | |
# https://rycee.gitlab.io/home-manager/options.html#opt-programs.direnv.enable | |
programs.direnv.enable = true; | |
programs.direnv.nix-direnv.enable = true; | |
# Htop | |
# https://rycee.gitlab.io/home-manager/options.html#opt-programs.htop.enable | |
programs.htop.enable = true; | |
programs.htop.settings.show_program_path = true; | |
home.packages = with pkgs; [ | |
# Some basics | |
coreutils | |
curl | |
wget | |
# Dev stuff | |
# (agda.withPackages (p: [ p.standard-library ])) | |
google-cloud-sdk | |
haskellPackages.cabal-install | |
haskellPackages.hoogle | |
haskellPackages.hpack | |
haskellPackages.implicit-hie | |
haskellPackages.stack | |
idris2 | |
jq | |
nodePackages.typescript | |
nodejs | |
purescript | |
# Useful nix related tools | |
cachix # adding/managing alternative binary caches hosted by Cachix | |
# comma # run software from without installing it | |
niv # easy dependency management for nix projects | |
nodePackages.node2nix | |
] ++ lib.optionals stdenv.isDarwin [ | |
cocoapods | |
m-cli # useful macOS CLI commands | |
]; | |
# Misc configuration files --------------------------------------------------------------------{{{ | |
# https://docs.haskellstack.org/en/stable/yaml_configuration/#non-project-specific-config | |
home.file.".stack/config.yaml".text = lib.generators.toYAML {} { | |
templates = { | |
scm-init = "git"; | |
params = { | |
author-name = "Your Name"; # config.programs.git.userName; | |
author-email = "youremail@example.com"; # config.programs.git.userEmail; | |
github-username = "yourusername"; | |
}; | |
}; | |
nix.enable = true; | |
}; | |
} |
Seems gists can't do pull requests, so here is a link to a fork to add info about the video you made. Might be worth adding some sort of note referencing since this is showing up directly in search results.
https://gist.github.com/ksexton/89baeb4a8b518727242e4d933d49e315#file-readme
Are there any special steps I need to take when setting this up for multiple users?
I have encountered multiple issues so far:
- homebrew and any commands installed by it are not present on that user
(casks are present, but only the applications, not the commands, i.e. vscode is installed but thecode
command cannot be used) - zsh prompts the following every time I open a shell:
zsh compinit: insecure directories and files, run compaudit for list. Ignore insecure directories and files and continue [y] or abort compinit [n]?
system.defaults
options are not set up for that user
@ksexton Added you changes. Thank you! 🙏
@jmatsushita thanks a lot for this awesome work!
there is small question rather out of curiocity:
users.nix.configureBuildUsers
given the official recommended way of nix
installation (macOS)
$ sh <(curl -L https://nixos.org/nix/install)
which creates nix
opendirectory group and build user.
Isn't, therefore, users.nix.configureBuildUsers
actually redundant? Or maybe does it exist for advanced users who prefer fine grained installation doing all these steps manually (I mean: creating users, group, APFS volume, registering daemon, etc)?
Hi @jmatsushita, thank you for both your gists and video!
I do have an issue that I'm hoping you could help me with.
When running:
./result/sw/bin/darwin-rebuild switch --flake .
I get the error:
flake 'path:/Users/roberm/.config?lastModified=1670021446&narHash=sha256-Zz3FXSWLs4eFVor1Hwy+mhorjGLRdwwwSCJoS88YI9s=' does not provide attribute 'packages.aarch64-darwin.darwinConfigurations.MacBook-Pro.system', 'legacyPackages.aarch64-darwin.darwinConfigurations.MacBook-Pro.system' or 'darwinConfigurations.MacBook-Pro.system'
I'm on a newly bought MacbookPro M1 (Ventura). The only changes I made were to remove the Kitty overlay, change the name of the system and user, and change a few options that Nix warned me about being deprecated (and gave me the new equivalent ones).
Other than that, I'm using the same code as here. Do you know why this error is occurring? Or how to solve it?
Thank you for your excellent work!!!
@rober-m Note line 45 of flake.nix, j-one = darwinSystem {...
. To switch to this the first time I would specify the name "j-one" like this.
./result/sw/bin/darwin-rebuild switch --flake ".#j-one"
I am not positive this will solve your problem but it can't hurt to try.
Thank you, @dansteeves68! It did solve the problem! It makes so much sense in retrospect 😂.
Thank you for this, it's really helpful!
Is there also a config that shows multiple users on a single M1 mac?
This was great - thanks. I just wanted to point people to nix-community/home-manager#1341 (comment) in case they wanted to get installed apps indexed by Spotlight
This does work on Intel Mac.
# Enable experimental nix command and flakes
# nix.package = pkgs.nixUnstable;
nix.extraOptions = ''
auto-optimise-store = true
experimental-features = nix-command flakes
'' + lib.optionalString (pkgs.system == "x86_64-darwin") ''
extra-platforms = x86_64-darwin aarch64-darwin
'';
I have both Intel and M1 Macs. How can I set this up so this is configured dynamically and it's not hard-coded?
TouchID for PAM was merged a while ago
This does work on Intel Mac.
# Enable experimental nix command and flakes # nix.package = pkgs.nixUnstable; nix.extraOptions = '' auto-optimise-store = true experimental-features = nix-command flakes '' + lib.optionalString (pkgs.system == "x86_64-darwin") '' extra-platforms = x86_64-darwin aarch64-darwin '';
I have both Intel and M1 Macs. How can I set this up so this is configured dynamically and it's not hard-coded?
Technically, it's being dynamically. Because they're return an optional string if the pkgs.system
matches the aarch64-darwin
value, if does not match, won't append anything to the string.
If you want to add other architectures, you can do a key/value mapping and appending based on it too.
Just tried to use my instructions again on a fresh install and it failed in a number of places. Not sure if I'll update this gist (though I realise it seems to still have some traffic), but here's a list of things to watch out for:
- Check out the
nix-darwin
instructions, as they have changed. - There's a home manager gotcha nix-community/home-manager#4026
For those who are new to nix, starting with Fleek is highly recommended.
@ZeroDeth Fleek seems fine and I haven't tried it, but AFAICT:
- it doesn't manage your system level settings like nix-darwin does
- It's a wrapper on top of home-manager, if you like yaml there might be advantages to that, but things will break underneath, and you'll have to know some nix to figure out why (to be fair that's not a problem with fleek, just with anything that provided some wrapping abstraction).
How is your experience with it?
@jmatsushita I have been utilizing Nix on a virtual machine for three years, without encountering any problems. However, I attempted to use Nix on both my Intel and M1 Mac and discovered Fleek as a potential solution. While it was initially useful for beginners, it has not been functioning properly for the past two months. Despite submitting several contributions and issues to Fleek, I have not received any response or resolution.
Have you tried experimenting with devbox.sh? It's a great tool to import a remote configuration and customize your experience. https://www.jetpack.io/devbox/docs/devbox_global/#using-fleek-with-devbox-global
@jmatsushita thanks for this post those years ago! Even if there's some issues with things here and there, it's a great reference and helped me get my head all the way around the nix -> flake -> nix-darwin + home-manager situation... so i wanted to say thanks!
@ZeroDeth I would definitely hang in there. i've used nix on mac laptops for nearly 2 years. I can't imagine going back. Just look for nix-darwin/flake configurations on github that have a large number of stars or followers. My personal setups were based on a work script that provisioned each laptop with a nix/flake setup. i've seen many very similar to mine though.
@jmatsushita I have been utilizing Nix on a virtual machine for three years, without encountering any problems. However, I attempted to use Nix on both my Intel and M1 Mac and discovered Fleek as a potential solution. While it was initially useful for beginners, it has not been functioning properly for the past two months. Despite submitting several contributions and issues to Fleek, I have not received any response or resolution.
Have you tried experimenting with devbox.sh? It's a great tool to import a remote configuration and customize your experience. https://www.jetpack.io/devbox/docs/devbox_global/#using-fleek-with-devbox-global
Seems like that the Fleek repository is archived as Mar 24, 2024
Thank you so much for this! it helped me get off the ground with home-manager and nix-darwin.
There were a few minor things I had to change in the flake.nix
:
- LnL7/nix-darwin#228 has been merged, so the touchId setup needs to go away to prevent duplicate definitions
- NixOS/nixpkgs#137512 has been closed, and so I think the workarounds for the kitty m1 builds have to go away. I don't use kitty, so I just removed it all.
- There were a bunch of warnings about renamed config options. Not a huge deal, I just renamed them all 1 by 1 and there was no issue.
- The
home-manager.users.jun
config key needs to be changed to indicate your mac username - Add
users.users."$MY_USER_NAME".homeDirectory = "/Users/$MY_USER_NAME";
above thehome-manager.useGlobalPkgs
line. based on: nix-community/home-manager#4026
Lastly (and this was noted in comments above) the command to enable the flake should be ./result/sw/bin/darwin-rebuild switch --flake ".#j-one"
rather than ./result/sw/bin/darwin-rebuild switch --flake .
Thanks so much for this!! Helped with a bizarre niche issue I had 🙏
Another thing that I had issues with was direnv not working out of the box.
I found out that is because zsh is installed globally using nix-darwin while direnv is activated in home-manager, meaning that the direnv hook is never inserted into the global zshrc.
To fix this, just put another
programs.zsh.enable = true;
intohome.nix