--- layout: post.njk title: Using Git to Deploy Nix Configurations tags: post date: 2024-01-20 ---

Lately I have been learning Nix, which is configured using a declarative programming language. What is nice about that is that allows us to reproduce a system very easily. However, I googled around and tried to figure out how to easily deploy my config from a local machine to a Nix machine. I started off SSHing into the machine and making edits using nano in the config, but it’s tedious and I’d rather use my local machine to change the configurations. There is also little advantage to having a declarative config if I can’t reuse it elsewhere.

There are tools out there like deploy-rs and Nixops. I found them a bit overkill for my need, which was just to make changes to a personal development machine, so I came up with a script to make the setup easy. It makes use of git, and levarages hooks to validate and apply changes with a simple push. In the end, it creates a workflow similar to Heroku. Here is what the script looks like, which you can run on a new machine with a fresh Nix installation:

# Start of by adding git to our configuration.nix, we will levarage this to
# be able to easily make changes to our machine without SSH.
sed -i 's/}/  programs.git.enable = true;\n}/g' /etc/nixos/configuration.nix

# Rebuild nix so we have git available
nixos-rebuild switch

# Set up a git repository where our nixos configuration lives
cd /etc/nixos
git init

# Change branch name to main instead of master
git branch -m main

# Add existing config and commit
git add .
git commit -m "Initial commit"

# Allow us to push changes to our machine and have those changes immediately reflected in the files
git config receive.denyCurrentBranch updateInstead

# Add a git hook to validate incoming changes
echo -e '#!/bin/sh \nnixos-rebuild dry-run' > /etc/nixos/.git/hooks/pre-receive

# Make the hook executable
chmod +x /etc/nixos/.git/hooks/pre-receive

# Add a git hook to apply the changes afterward
echo -e '#!/bin/sh \nnixos-rebuild switch' > /etc/nixos/.git/hooks/post-receive

# Make the hook executable
chmod +x /etc/nixos/.git/hooks/post-receive

Once set up, you can clone the repo on your local computer:

git clone root@your-machine:/etc/nixos

And if you’d like to set up a backup on Sourcehut, you can do so easily:

git remote add backup git@git.sr.ht:~username/reponame
git push backup main

This script can be ran on a new machine. I used Nixos-infect to setup NixOS on a VPC that I rent on Hetzner cloud.