Luca's nix configuration
Table of Contents
1 Introduction
1.1 This repository
This repository contains my system configuration.
The main objective is to have a portable and reproducible system in order to for example bootstrap a new system in a quick and automated way.
The ideal is to share packages and configuration across different operating systems.
At the moment I only use a macOS
system but I am prepared for the day I will switch to nixOS
Tools:
nix
as a package manager- In particular, an experimental feature called
flake
to achieve complete reproducibility
- In particular, an experimental feature called
home-manager
to configure packages and dotfilesnix-darwin
to configure macOS systems (e.g. it has a greatbrew
module)
1.2 This file
This file (readme.org
) is used to generate (the correct term is tangle
) my flake.nix
file, where I specify the inputs and outputs of my system configuration.
The tangled flake.nix
file imports other .nix
files (e.g. darwin/default.nix
).
This file is better viewed in HTML format here or through org-mode
(clone the repo and open in emacs
).
You can visit my blog at the same website.
2 flake.nix
2.1 file structure
# NOTE: this file is tangled from readme.org # DO NOT edit by hand { description = "Luca Cambiaghi's darwin configuration"; <<inputs>> outputs = inputs@{ self, nixpkgs, darwin, home-manager, flake-utils, ... }: let <<nixpkgs-config>> <<home-manager-config>> <<nix-darwin-config>> in { darwinConfigurations = { <<luca-macbookpro>> <<github-ci>> }; <<cloud-vm>> <<home-manager-modules>> } // <<dev-shell>> }
2.2 inputs
inputs = { # Package sets nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; nixpkgs-master.url = "github:nixos/nixpkgs/master"; nixpkgs-stable-darwin.url = "github:nixos/nixpkgs/nixpkgs-20.09-darwin"; nixos-stable.url = "github:nixos/nixpkgs/nixos-20.09"; # Environment/system management # darwin.url = "github:lnl7/nix-darwin"; darwin.url = "github:hardselius/nix-darwin"; darwin.inputs.nixpkgs.follows = "nixpkgs"; home-manager.url = "github:nix-community/home-manager"; home-manager.inputs.nixpkgs.follows = "nixpkgs"; # Other sources emacs.url = "github:nix-community/emacs-overlay"; fish-done = { url = "github:franciscolourenco/done"; flake = false; }; flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; flake-utils.url = "github:numtide/flake-utils"; };
2.3 nixpkgs config
The trick in the overlays
variable allows us to use the stable version of problematic
packages. You can just use stable.pkg
instead of pkg
in home/default.nix
nixpkgsConfig = with inputs; { config = { allowUnfree = true; allowUnsupportedSystem = true; }; overlays = [ ( final: prev: let system = prev.stdenv.system; nixpkgs-stable = if system == "x86_64-darwin" then nixpkgs-stable-darwin else nixos-stable; in { master = nixpkgs-master.legacyPackages.${system}; stable = nixpkgs-stable.legacyPackages.${system}; } ) emacs.overlay ]; };
2.4 home-manager config
homeManagerCommonConfig = with self.homeManagerModules; { imports = [ ./home # configs.git.aliases # configs.starship.symbols # programs.kitty.extras ]; };
2.5 nix-darwin config
nixDarwinCommonModules = { user }: [ # Main `nix-darwin` config ./darwin # `home-manager` module home-manager.darwinModules.home-manager { nixpkgs = nixpkgsConfig; # Hack to support legacy worklows that use `<nixpkgs>` etc. # nix.nixPath = { nixpkgs = "$HOME/.config/nixpkgs/nixpkgs.nix"; }; # `home-manager` config users.users.${user}.home = "/Users/${user}"; home-manager.useGlobalPkgs = true; home-manager.users.${user} = homeManagerCommonConfig; } ];
2.6 luca-macbook-pro
luca-macbookpro = darwin.lib.darwinSystem { modules = nixDarwinCommonModules { user = "luca"; } ++ [ { networking = { knownNetworkServices = ["Wi-Fi" "Bluetooth PAN" "Thunderbolt Bridge"]; hostName = "luca-macbookpro"; computerName = "luca-macbookpro"; localHostName = "luca-macbookpro"; }; } ]; specialArgs = { inherit inputs nixpkgs; }; };
2.7 github-ci
githubCI = darwin.lib.darwinSystem { modules = nixDarwinCommonModules { user = "runner"; } ++ [ ({ lib, ... }: { homebrew.enable = lib.mkForce false; }) ]; };
2.8 home-manager-modules
# homeManagerModules = { # configs.git.aliases = import ./home/configs/git-aliases.nix; # configs.gh.aliases = import ./home/configs/gh-aliases.nix; # configs.starship.symbols = import ./home/configs/starship-symbols.nix; # programs.neovim.extras = import ./home/modules/programs/neovim/extras.nix; # programs.kitty.extras = import ./home/modules/programs/kitty/extras.nix; # };
2.9 cloud-vm
Build and activate with nix build .#cloudVM.activationPackage; ./result/activate
cloudVM = home-manager.lib.homeManagerConfiguration { system = "x86_64-linux"; homeDirectory = "/home/luca"; username = "luca"; configuration = { imports = [ homeManagerCommonConfig ]; nixpkgs = nixpkgsConfig; }; };
2.10 dev-shell
inputs.flake-utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages.${system}; in { devShell = import ./shell.nix { inherit pkgs; }; });
3 Practical commands
3.1 Install nix (flakes)
thanks https://github.com/kclejeune/system
# 1. if [[ $(uname -s) == 'Darwin' ]]; then # sh <(curl -L https://nixos.org/nix/install) --daemon --darwin-use-unencrypted-nix-store-volume sh <(curl -L https://github.com/numtide/nix-flakes-installer/releases/download/nix-2.4pre20210126_f15f0b8/install) --daemon --darwin-use-unencrypted-nix-store-volume else sh <(curl -L https://nixos.org/nix/install) --daemon fi # 2. git clone git@github.com:lccambiaghi/nixpkgs.git ~/git/nixpkgs # 3. cd ~/git/nixpkgs && nix build ".#darwinConfigurations.luca-macbookpro.system" && ./result/sw/bin/darwin-rebuild switch --flake .#luca-macbookpro
3.2 darwin-rebuild
darwin-rebuild build --flake .#luca-macbookpro # nix build ".#darwinConfigurations.luca-macbookpro.system" darwin-rebuild switch --flake .#luca-macbookpro # ./result/sw/bin/darwin-rebuild switch --flake .#luca-macbookpro
3.3 nix flake update
nix flake update --update-input nixpkgs
4 Nix
4.1 Fundamentals
Set:
{ "a b" = "c"; count = 2; }
List:
[42 "a b" (3 + 6) [2 3 4] {x = 2;}]
Lambda:
(x: x + x) 21 # 42 let hi = {name, place}: "Hi ${name} in ${place}!"; in hi { name = "Michael"; place = "Austria"; }
Parameter with default value:
{ pkgs ? import <nixpkgs> {} }:
<nixpkgs>
refers to the value of the nixpkgs attribute declared in the NIXPATH environment variable
4.2 Config
A config takes an attribute as parameter and returns an attribute set
{ pkgs }: { packageOverrides = pkgs: { emacs = pkgs.emacs.override { withGTK2 = false; withGTK3 = false; withXwidgets = false; }; }; allowUnfree = true; }
4.3 Derivation
A derivation takes inputs and produces output. A derivation is lazy, so it will only be evaluated when it is input to other derivations.
derivation { name = "hello-world"; system = "x86_64-linux"; outputs = [ "out" ]; # This is the default, and can be omitted. builder = "${pkgs.bash}/bin/bash"; args = [ "-c" "echo 'Hello world!' > $out" ]; }
Derviation outputs are stored in the nix store. Each derivation's output is defined by an hash which encodes all input derivations. If something changes even slightly in the inputs, the hash output will change.
4.4 Escaping in strings
- You can use
'
to escape double quotes - You can use
''
to escape dollar