Put NixOS config into a Git repository
This tutorial will show how to consolidate NixOS configuration and home-manager configuration into one Git repository.
Prerequisite: Have a working NixOS install, with git, git-crypt, gnupg and home-manager installed.
Make a directory where the Git repo will be placed. In my case it's inside the Development folder in my home directory.
cd ~/Development
mkdir nixos-config
Make a directory where the system configuration will be stored (NixOS config).
mkdir nixos-config/hosts
Make a directory where the user config (home-manager config) will be stored for particular users.
mkdir nixos-config/users
Make a directory for particular user.
mkdir nixos-config/users/eric
Initialise the git repository.
cd nixos-config
git init
Configuring the system directory.
Copy the NixOS configuration files to the nixos-config/hosts/ folder.
cd system
cp /etc/nixos/*.nix .
Double check that he permissions are fine (i.e check that the user is correct and has appropiate permissions).
ls -lAh
-rw-r--r-- 1 eric users 5.2K May 18 20:46 configuration.nix
-rw-r--r-- 1 eric users 935 May 18 20:46 hardware-configuration.nix
To make the NixOS run the configuration in the git directory:
sudo nixos-rebuild switch -I nixos-config=~/Development/nixos-config/hosts/configuration.nix
Configuring the users directory.
Copy the home-manager configuration files to the nixos-config/user/eric/ folder.
cd ~/Development/nixos-config/users/eric
cp ~/.config/nixpkgs/home.nix .
Double check that he permissions are fine (i.e check that the user is correct and has appropiate permissions).
ls -lAh
-rw-r--r-- 1 eric users 935 May 18 20:46 home.nix
To make the NixOS run the home-manager configuration in the git directory:
home-manager switch -f ~/Development/nixos-config/users/eric/home.nix
Making scripts to automate running the config files.
To make it easier to rebuild the configurations, instead of having to type long commands each time.
Script to run system rebuild.
cat > ~/Development/nixos-config/apply-system.sh
#!/bin/sh
pushd ~/Development/nixos-config # Change to the nixos-config directory
sudo nixos-rebuild switch -I nixos-config=./hosts/configuration.nix # Rebuild configuration.nix.
popd # Return to previous directory.
Script to run home-manager rebuild.
cat > ~/Development/nixos-config/apply-user.sh
#!/bin/sh
pushd ~/Development/nixos-config # Change to the nixos-config directory
home-manager switch -f ./users/eric/home.nix # Rebuild home-manager.
popd # Return to previous directory.
Make the scripts executable:
chmod +x ~/Development/nixos-config/*.sh
To run configurations:
cd ~/Development/nixos-config
./apply-system.sh
./apply-user.sh
Making scripts to automate updating.
Script to update the system:
cat > update-system.sh
#!/bin/sh
sudo nix-channel --update
Script to update the user:
cat > update-user.sh
#!/bin/sh
nix-channel --update
Make the scripts executable:
chmod +x ~/Development/nixos-config/*.sh
To run configurations:
cd ~/Development/nixos-config
./update-system.sh
./update-user.sh
Setting up git-crypt
When using a service like GitHub to host repositories, if there are any secrects stored in the repositories, such as passwords for wifi,or other sensitive information. git-crypt can be used to encrypt (with a GPG key) parts of a repository that may contain secrets. It is best practice to encrypt secrets even in private repositories, just in case they are made public later on, because even if the files that contain secrets are removed, the history will still have the secrets in it.
Add gpg-agent setup to the home-manager configuration, add the pinentry package, then execute the apply-user.sh script.
{ config, pkgs, ... }: {
programs.gpg-agent = {
enable = true;
};
services.gpg-agent = {
enable = true;
pinentryFlavor = "qt";
};
home.packages = with pkgs; [
pinentry_qt
# Etcetera ...
];
# Etcetera ...
}
Generate the gpg key and follow the prompts, fill in name and email and password.
gpg --generate-key
Double check to ensure the key is trusted. First, list all keys.
gpg --list-key
Backup the public key.
gpg --output ~/public.gpg --armor --export mail@cebo.ooo
Backup the private key (follow thw prompt and fill in password).
gpg --output ~/private.gpg --armor --export-secret-key mail@cebo.ooo
Trust the key.
gpg --edit-key mail@cebo.ooo
If the key is showing as ultimate, then the key is being trusted. if it doesn't, type in "trust" in the gpg prompt. Select 5 to trust it ultimately. Click 'y' to confirm and then type quit when finished.
Setting the repository up to git-crypt
Before continuing, with this step, ensure git is setup with username and email address. To check is it is already setup:
git config --list
If name and email are setup correctly, then they should be displayed. If no name and email appear, then git has to be setup. To setup git with username and email, add git setup to ~/NixOS/users/eric/home.nix:
{ config, pkgs, ... }: {
rograms.git = {
enable = true;
userName = "Eric C Chiruka";
userEmail = "mail@cebo.ooo";
};
# Etcetera ...
}
In the repository, generate the git-crypt key.
git crypt init
This then creates a file ~/Development/nixos-config/.git/git-crypt
Add the gpg key to the repository so that it can be encrypted when needed.
git crypt add-gpg-user mail@cebo.ooo
This then creates a few files in the keys directory ~/Development/nixos-config/.git/git-crypt/keys/. Essentially, now, any user with an authorised gpg key can decrypt the main key and decrypt the contents of all the secrets stored in the repository. Multiple users can be added and also revoked at will by adding/revoking their gpg key.
Backup the git-crypt key:
git crypt export-key ~/gitgpg.key
Encrypting secrets
Create a secrets directory in the repository:
mkdir .secrets
Create a secret file:
echo "testing" > ./secrets/test.txt
Create a .gitattributes file in the repository.
cat > .gitattributes
.secrets/** filter=git-crypt diff=git-crypt
Add and commit changes (use git status to ensure all files are added.)
git add .
git status
git commit -m "Initial commit"
Lock the repository (encrypts secrets)
git crypt lock
Now if we try viewing encrypted content, it should be encrypted.
cat ~/Development/nixos-config/.secrets/test.txt
To unlock/decrypt secrets
git crypt unlock
Now if we try viewing encrypted content, it should be decrypted.
cat ~/Development/nixos-config/.secrets/test.txt