Github strategies for configuration.nix?


Hi all-

I was wondering what GitHub strategies you all use to keep your configuration.nix file (and extra files that go with it) under version control.

The problem I’m having is that hardware-configuration.nix is generated by a new installation, along with a basic configuration.nix. If I then want to supply my own configuration.nix from GitHub or somewhere else, how would I go about it? Symlinks to a directory I check out into /etc?



/etc/nixos being a git repository is a common solution. I usually
clone it after I run nixos-generate-config
put the generated configs into hosts/${hostname} subdirectory,
customize it and then create a

before finishing the installation.

But you can place the configuration anywhere and run nixos-rebuild
with -I nixos-config=path/to/your/configuration.nix.


I have a separate repository for my config and symlink the configuration from there into /etc/nixos. One reason this is nice is that I have configurations for several machines in the same repo, so they can share common modules and so on.


This is amazing, thanks for providing your own configs as an example.

How do you actually wire this into your system? Do you have to symlink both configuration.nix and hardware-configuration.nix on a given machine to the files in the matching subdirectory of machines/? If you just symlink those, how do the relative import statements in, say, machines/clipper/configuration.nix work properly?




Thanks for the symlink script, and the tip about the -I flag!



You only have to symlink configuration.nix. As you’ve realised, the crucial fact is that the relative imports are resolved from the actual location of the file. So having symlinked in configuration.nix from machines/whatever/configuration.nix, the import ./hardware-configuration.nix resolves correctly to machines/whatever/hardware-configuration.nix.


Good to know. I’ve run into problems caused by this exact behavior in Node projects, so I guess I’m once-bitten twice-shy. Thanks!



I manage all my systems via nixops with all configuration in a ~/nixops (including secrets, which are encrypted with git-crypt). To deploy a system I cd into it and run make $(hostname) which expands to nixops modify -d $(hostname) systems/$(hostname) && nixops deploy -d $(hostname) and some other commands (depending on the hostname). The target system requires an SSH server, even if you’re deploying locally.

Take note of nixops#736 when working with remote servers on a different release than your local system.


I clone my repo with all my configuration after a nixos-generate-config like jtojnar and I imports the common part to the current configuration. After that I create a symlink from /etc/nixos/configuration.nix to my custom path /etc/nixos/systems/$(hostname).

I keep my git repo in /etc/nixos and I apply an acl on this folder to avoid sudo at each commit. (


I don’t have an /etc/NixOS folder, but instead deploy directly from a relocatable git repo using a custom script:


nix.nixPath = [ "nixos-config=/path/to/repo/machine.nix" ];


I don’t keep my config in /etc/nixos/configuration.nix, it just includes other files and has the stateversion so it isn’t tracked in git. I use stow to manage my dotfiles and I keep my nix configuration in the same repo, though I may move it to it’s own repo. Stow is used to symlink the configuration. nixpkgs is currently a submodule in that repository and that is how I pin it, I’m not a big fan of that but I don’t know of anything better for me.

On a new machine I do the following (c/p from repo):

git clone --recurse-submodules /etc/nixos/dotfiles # or using https git clone --recurse-submodules /etc/nixos/dotfiles
cd /etc/nixos/dotfiles
stow nixos
cp nixos/configuration.nix.skel /etc/nixos/configuration.nix
vim /etc/nixos/configuration.nix #choose what you want, and update the state version to a newer one if avilable
sudo nixos-rebuild switch


My dotfiles

# COPY hardware-configuration.nix to dotfiles to be able to modify it without sudo
cp /mnt/etc/nixos/hardware-configuration.nix.old /mnt/home/srghma/.dotfiles/nixos/root/hardware-configuration.nix


# this configuration is used only during installation
printf "import /mnt/home/srghma/.dotfiles/nixos/root/default.nix" > /mnt/etc/nixos/configuration.nix


I do something similar to this:

  nix.nixPath = [

I keep my dotfiles repo cloned at ~/p/dotfiles, and when setting up a new system I run nixos-rebuild with an explicit -I /home/benley/...../configuration.nix once. From then on, as long as the system’s own hostname is set, it looks in the right place for its nixos-config.


I deploy my nixos configuration via nixpkgs and an overlay:

My file /etc/nixos/configuration.nix just contains the following:

let mypkgs = import <nixpkgs> {}; in mypkgs.myconfig.nixos-config

and nixpkgs.myconfig.nixos-config added via the overlay which just imports the top level default.nix of my dotfiles:

To get that working I clone my dotfiles to ~/myconfig and the script ~/myconfig/ just sets up everything (e.g. adds nixpkgs-overlays=$HOME/myconfig/nix/overlays to my $NIX_PATH). I also use the hostname, defined in a file /etc/nixos/hostname to determine which configuration to deploy.

The complete (and tested) instructions how to bootstrap my nixos configuration in encapsulated in a packer script:


I also did a talk about this as well as using Nixops and a nix-darwin haskell based deployment tool at NixCon this past year: