NixOS Servers: Reproducible Declarative Configuration in Nix
NixOS rebuilds a whole server from one declarative file: packages, services, users, and firewall in code, with rollbacks that make changes boring.
Netbay Developer Relations
Netbay Engineering
On this page
NixOS is built around a different premise: the entire machine, packages, services, users, firewall, and boot configuration, is described in a set of Nix files, and the installed state of the machine is a function of those files. There are no imperative tweaks that quietly accumulate; the configuration is the truth, and every change produces a new generation you can boot back to. For a small VPS fleet managed by one or two people that property is transformative, because it makes a server reproducible in exactly the way a build pipeline makes software reproducible.
The Machine as a Function
At its core Nix is a functional package manager: every package is built into an immutable store path under /nix/store, with every dependency hashed into the path name, so nothing is installed into shared locations where two versions can fight. A configuration imports the packages it needs and wires them together as services, and nixos-rebuild evaluates the whole machine description and produces a new activation state. If anything fails, the previous generation is still there, complete and bootable. That is the mental model: rebuild the machine, rather than editing it.
A Minimal Server Configuration
A server that needs only SSH and nginx is around fifteen lines of expression. The Nix language is small and deliberately typed; most of what you write is attribute sets describing services, users, and the firewall.
# /etc/nixos/configuration.nix (excerpt)
{ config, pkgs, lib, ... }:
{
system.stateVersion = "24.11";
networking.hostName = "web01";
networking.firewall.allowedTCPPorts = [ 80 443 ];
users.users.deploy = {
isNormalUser = true;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA..." ];
};
security.sudo.extraRules = [{
users = [ "deploy" ];
commands = [ { command = "ALL"; options = [ "NOPASSWD" ]; } ];
}];
services.openssh.enable = true;
services.nginx.enable = true;
services.nginx.virtualHosts."example.com" = {
root = "/var/www/site";
listen = [ { addr = "0.0.0.0"; port = 80; } ];
};
}Every concept you are used to configuring through a series of manual steps — a user here, a firewall rule there, an nginx vhost somewhere else — arrives in this file as a typed option with validation.
Rebuild, Switch, Roll Back
The suite of nixos-rebuild commands maps to the lifecycle. Edit the configuration, then mutate the running machine:
sudo nixos-rebuild switch
sudo nixos-rebuild build # evaluate and realise without activating
sudo nixos-rebuild --rollback # atomically flip back a generation
ls -la /nix/var/nix/profiles/systemBecause activation is atomic, a broken configuration typically fails before it replaces the running system, and runtime problems are answered by --rollback rather than by archaeology. That single command changes how you approach risky updates entirely.
Locked Inputs Make It Reproducible
Reproducibility is only as strong as the pins, which is what flakes are for. A flake records the exact nixpkgs commit and every other input in flake.lock, so the same flake evaluates to the same store paths on any machine and any day.
# flake.nix — inputs are locked to precise revisions
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
outputs = { self, nixpkgs }: {
nixosConfigurations.web01 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./configuration.nix ];
};
};
}Two rebuilds from the same lock produce the same closure hashes. That single fact makes your Git history a decidable timeline of machine states instead of an approximation of what someone once ran. Providers offer NixOS cloud images, and the pattern for a VPS is the same as anywhere else: a flake, a configuration, and a rebuild command.
Takeaway
NixOS trades one evening of learning curve for a server you can destroy and recreate from Git, and it changes incident response from archaeology into redeployment. If you run more than a couple of identical boxes, the declarative model is less magic than it sounds.
Test NixOS on a disposable Netbay VPS in under 60 seconds, rebuild it a dozen ways, and decide whether the learning curve buys your fleet anything — netbayhosts.in.
Keep reading
Follow along on a real VPS
Deploy Linux in under 60 seconds
These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.
Deploy an instance