NixOS Home Server Series - Part 2
Coming from any other Linux distro, NixOS can be a bit of a shift in thinking. So I will be approaching this in small steps. After part one we have a simple one file configuration.nix file that lives in /etc/nixos.
In part 2 I will cover.
- Moving the configuration to the home user directory for easier management
- Dividing your config into multiple files for better organization
Moving config to home
Let’s start with moving your config to the home directory. The reason I chose to do this from the beginning is I want to be able to copy, paste and make use of all the features in my IDE when editing them.
This is a personal preference, but I find it much easier to work with remotely, as otherwise all config files are owned my root. This way I can mount my home with sftp without connect as root.
But there are some steps to take to make this work. I will be essentially redirecting the NixOS config to a different location.
cd /etc/nixos
cp -r * ~/nixos-config/
Then we need to edit the configuration.nix file to point to the new location.
Open the original ‘/etc/nixos/configuration.nix’, and replace the contents with the following:
Here we introducing some new syntax, imports. This is how we include other files in our configuration. We are also setting the nixPath to set the new location of the config file.
Then we need to edit the ‘/etc/nixos/hardware-configuration.nix’ file to point to the new location.
{ config, pkgs, ... }:
{
nix.nixPath = [
"nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
"nixos-config=/home/<username>/nixos-config/configuration.nix" # new config location
];
imports = [ "/home/<username>/nixos-config/configuration.nix" ];
Then we need to edit the new configuration.nix file.
Here we use imports again to set the location of our hardware-configuration.nix file. And going forward we will be referencing all future modules.
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
];
system.stateVersion = "24.11";
}
Now we can run the following command to test the configuration.
sudo nixos-rebuild switch --show-trace
Now you can use your favourite code editor to mount your home directory and edit the configuration.nix file. This makes it much easier to manage and edit going foward.
Divide and conquer
Moving your config into multiple files and folders is a natural progression, as things can start to get messy and confusing fast with everything in one place.
Here is how I have my config organized:
```bash
[nix-shell:~]$ tree nixos-config/
nixos-config/
├── configuration.nix
├── hardware-configuration.nix
└── modules
├── boot.nix
├── filesystems.nix
├── networking.nix
├── system.nix
└── users.nix
```
Create your files and folders as above, starting with boot.nix.
Now move the boot declaration from the original configuration.nix file like so.
{ config, pkgs, ... }:
{
boot.loader = {
efi = {
canTouchEfiVariables = true;
efiSysMountPoint = "/boot";
};
systemd-boot.enable = true;
};
}
Then we need to edit the configuration.nix file to point to the new location of the boot.nix file.
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./boot.nix
];
system.stateVersion = "24.11";
}
Do this step by step for each module, and you will end up with a clean and organized structure to build out from.
# configuration.nix
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./boot.nix
./filesystems.nix
./networking.nix
./system.nix
./users.nix
];
system.stateVersion = "24.11";
}
# users.nix
{ config, lib, pkgs, ... }:
{
users.users.root.initialPassword = "temp";
users.users.admin = {
isNormalUser = true;
extraGroups = [ "wheel" ];
initialPassword = "temp";
};
users.users.robin = {
isNormalUser = true;
extraGroups = [ "wheel" ];
initialPassword = "temp";
};
}
# filesystems.nix
{ config, lib, pkgs, ... }:
{
fileSystems."/boot" = lib.mkForce {
device = "/dev/disk/by-label/BOOT";
fsType = "vfat";
};
fileSystems."/storage" = lib.mkForce {
device = "/dev/disk/by-label/STORAGE-POOL";
fsType = "btrfs";
options = [ "compress=zstd" "noatime" ];
};
fileSystems."/backup" = lib.mkForce {
device = "/dev/disk/by-label/BACKUP-POOL";
fsType = "btrfs";
options = [ "compress=zstd" "noatime" ];
};
}
# networking.nix
{ config, lib, pkgs, ... }:
{
networking.hostName = "nixos";
services.openssh = {
enable = true;
ports = [22];
};
networking.firewall.allowedTCPPorts = [22];
}
# system.nix
{ config, lib, pkgs, ... }:
{
time.timeZone = "Europe/London";
}
Test it out with the following command:
sudo nixos-rebuild switch --show-trace
That’s it for now.
I realy enjoyed this part of the process, starting to get a sense of flow and control over my system I hadn’t experienced before.
Apr 27, 2025