Bootstrapping new system


I am trying to create a central configuration of my machines like many others before me. After surveying prior arts (settling on something close to the Barrucadu’s answer here), I still could not find answers to the following questions :

  • I obviously wish to create a derivation containing the different machines configuration : what is the best way to pass arguments to the “building” derivation to select what machines to “build” ?
    I thought to piggy-back on the nix-build command with a specially crafted default.nix but I cannot find a way to pass an argument like nix-build --arg machine-1-name default.nix.

  • I want to make symlinks to a folder containing my dotfiles à la stow (in a granular way would be best; like only if vim is installed should we have its config laying around with something like if config.vim.enable) : where should I include those ln commands to have the configuration files ? Is there a more “idiomatic” way of doing it ?
    I have seen that home-manager seems to be the go to solution but I would like the solution to keep the configuration files separate (but maybe I am mistaken about home-manager functioning). I though (once again) to piggy back on the build process of the derivation (like the buildPhase) to symlink the relevant files but it seems convoluted.

I am sorry if I missed something obvious in the docs. Thanks in advance for your help.

1 Like
  1. Personally, I don’t think this is a great way to do it, I do it by splitting my configuration into several smaller parts and then having a machine specific configuration that I symlink to /etc/nixos. I can then include whatever parts I want into each specific machine and still do machine specific setups.
  2. home-manager is your best bet for dotfiles on NixOS in my opinion, it can work either together with the OS as a module or as a separate program, just like stow.

If you want to take a look you can see my dotfiles here.

Sounds like you’re looking for distributed builds [1]? Though it’s probably easier to build the system on that machine before uploading to a binary cache like Cachix [2]. If you want to build another machine’s config you would probably use nix build -I nixos-config={{NIXOS_CONFIG}} -f "<nixpkgs/nixos>" for the same architecture. For different architectures, you would either use a remote builder or try cross compiling the entire configuration.

For the vim scenario, you can just keep everything vim-related into a single file and import it if you need vim in the user’s environment. You can probably also use lib.mkIf or lib.mkMerge in your expressions to create custom modules and link the files in config = mkIf (config.user.vim.enable) { programs.vim.enable = true; ... }.

[1] Distributed build - NixOS Wiki

Thank you both @eadwu @sondr3 for your answers ! I realize that I might not have expressed my problem correctly.

I do not see how to integrate my already-existing dotfiles with home-manager though. Thank you for sharing your example of your dotfiles.

I find really amazing that I keep finding solution to things I was annoyed by… the binary cache is good tool to have to bootstrap a system like a Raspberry Pi but that it is not what I am looking for.

That is a real shame that the lib.* functions are not better referenced.

Since you already have all the files, you can just create symlinks for every file.

{ ... }:

  # from $HOME
  # ~/.ncmpcpp/config
  home.file.".ncmpcpp/config".source = ./ncmpcpp/config;
  # ~/.config/glava/
  xdg.configFile."glava".source = ./glava;

Oh wow ! I did not knew that I could do that ! I will mark the question as anwsered (at least for the second part of it). Thank you a lot for your time !

For future reference, I will link my dotfiles when I implement a solution.

Quick side question after peeking into the options and the manual, why is this method not cited anywhere that I could find ?
Can I make a relevant section in the book or the wiki for it ?

It’s an option specific to home-manager, if you want to use it within your NIXOS_CONFIG you need to import it as a module [1]. Otherwise you’ll configure it within each user’s ~/.config/nixpkgs/home.nix.

[1] Home Manager Manual