-
-
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; | |
}; | |
} |
@jmatsushita I was wondering do I need to put all these files in ~/.config
? I want to keep these files in git and a lot of generated files and configs are in ~/.config
which would be nice to keep out of git
@jmatsushita phenomenal job!
I was wondering if in your setup kitty
is accessible from spotlight and does it open as any other mac apps?I tried your config in a new M1 box but I had no luck to get kitty
to work.
great work!
There's a typo at https://gist.github.com/jmatsushita/5c50ef14b4b96cb24ae5268dab613050#file-flake-nix-L96 , where you wrote "progams" instead of "programs"
s/config.progams/config.programs
@jmatsushita this is amazing and thanks.
I am wondering if this could be used for the Intel based mac's? I can understand that ,"system" variable is set to "aarch64-darwin". But replacing that with "x86_64-darwin" and removing the overlay
# 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; }) );
and some apple silicon stuff could do the job?
@aranw You're welcome :)
do I need to put all these files in ~/.config?
I have them in ~/.config/nix
Not sure about the primaryUsers trick, maybe this ?
@smunix Thanks! I just fixed it.
@lucamaraschi I'm afraid I dropped kitty
and went back to using Terminal
😓
@johnykifle Yes I don't see a reason why this wouldn't work! Don't have a machine to test though, so feel free to report back 👋
What do I need to do if I don't want to use unstable but 22.05 instead?
There are multiple references to unstable in the flake inputs. Also nix installed an unstable channel automatically for the root user
Can I set that channel programmatically so that the channel from the flake is also used for commands such as nix-shell
?
See here: https://discourse.nixos.org/t/do-flakes-also-set-the-system-channel/19798/3
Furthermore, do I need to run both commands from ~/.config
every time I want to rebuild?
nix build .#darwinConfigurations.username.system
./result/sw/bin/darwin-rebuild switch --flake .
or is it possible to somehow just run darwin-rebuild switch
from anywhere?
Also, I had to do some additional stuff to make it work, specifically:
echo -e "run\tprivate/var/run" | sudo tee -a /etc/synthetic.conf
/System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t
but I was prompted to do that.
And I also had to sudo chmod myUsername ~/.nix-defexpr
because that was created as root somehow.
Thank you so much for taking the time to answer all these questions by the way.
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;
into home.nix
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 .
@jmatsushita Thanks so much for this gist and the video. In the video you mention a module and "trick" for
users.primaryUser
I tried to do some googling to figure out what this does but I was unable to find anything obvious about what it does. I was wondering do you have a source about this or perhaps write a little explanation as to what it is and why you are not using it?