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 (NixOS - NixOS 22.05 manual), put the generated configs into hosts/${hostname} subdirectory, customize it and then create a symlink before finishing the installation.

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

Edit: I switched to doing the latter as it does not require fiddling with permissions in /etc.


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.

1 Like

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. (Access Control Lists(ACL) in Linux - GeeksforGeeks)

I don’t have an /etc/NixOS folder, but instead deploy directly from a relocatable git repo using a custom script: nixos-stuff/ at 8e165977bd39b73c8dee5fc75d599d6bb35465f8 · arianvp/nixos-stuff · GitHub

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 dotfiles/ at 6457ffdb5926a769c785f134c04ccdab83c0afac · srghma/dotfiles · GitHub

# 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: Samuel Leathers - Nix at Home - Configuration management for your house (NixCon 2018) - YouTube


My way of doing it is having a sync script that automatically copy and lint the code, add files and commit & push it.
here it is: GitHub - LEXUGE/nixos: A fully automated replicable nixos configuration set

I use git-crypt for secret management. When files are not (yet) decypted, my configuration uses fallback parameters and disables some features (e.g. VPN, backup scripts).

1 Like

Thank you mentioning git-crypt; that looks like it might be just what I need for some of my development repos.

My NixOS configuration is modular; the files are in a github repo, along with my dotfiles.

My configuration files are the same on each machine I use, with the following exceptions:

  • For each machine I use, I have a configuration file called something like hostname.nix. It has any machine-specific stuff I need.
  • /etc/nixos/configuration.nix is very short; it sets the hostname, and then imports all the other NixOS configuration files.

Here’s what /etc/nixos/configuration.nix looks like on one of my machines.

{ config, pkgs, options, ... }:

let hostname="wombat9000";
  networking.hostName = hostname;

  imports =
    [ # Include the results of the hardware scan.
      (/home/amy/dotWombat/nixos + "/${hostname}.nix")

You can see the rest of my configuration files here: dotWombat/nixos at master · mhwombat/dotWombat · GitHub

1 Like