Why I Run NixOS on My Servers

Published on

NixOS DevOps Infrastructure

The Problem with Traditional Linux

Every SRE has lived this nightmare: you SSH into a production server, make a config change, and something breaks. You don't remember what you changed. There's no diff. The backup is three weeks old. You start grepping through /etc hoping to find what went wrong.

I spent years in this cycle. Then I found NixOS, and my servers became declarative.

What Makes NixOS Different

NixOS isn't just another Linux distribution. It's built on a fundamentally different idea: your entire system configuration is a single expression written in the Nix language. Every package, every service, every firewall rule — it's all in one file.

# /etc/nixos/configuration.nix (simplified)
{ config, pkgs, ... }:
{
  services.nginx = {
    enable = true;
    virtualHosts."example.com" = {
      root = "/var/www/example";
      enableACME = true;
      forceSSL = true;
    };
  };

  networking.firewall.allowedTCPPorts = [ 80 443 ];

  environment.systemPackages = with pkgs; [
    vim git curl jq
  ];
}

That's it. That's your web server config. Commit it to git, and you have a complete audit trail of every change ever made to your system.

The Three Killer Features

1. Atomic Rollbacks

Every time you rebuild your NixOS system, it creates a new "generation." If something breaks, you reboot into the previous generation. It's like git for your entire operating system.

# List all system generations
$ nixos-rebuild list-generations
  47   2026-04-01 14:23:15   current
  46   2026-03-28 09:15:42
  45   2026-03-25 11:30:00

# Roll back to previous generation
$ sudo nixos-rebuild switch --rollback

I've rolled back production servers in under 30 seconds. No panic, no manual config restoration. Just pick the generation that worked.

2. Reproducible Builds

My entire infrastructure is defined in a Nix flake. When I deploy to a new server, I get the exact same system. Not "mostly the same." Not "close enough." Exactly the same packages, configs, and services. Pin the flake lock, and you get bit-for-bit reproducibility.

3. Safe Experimentation

Want to test a new service? Create a nix shell or a NixOS test. It runs in isolation, doesn't touch your system, and disappears when you're done. No more "apt install" on production and hoping for the best.

# Try PostgreSQL 16 without installing it
$ nix shell nixpkgs#postgresql_16

# Test a NixOS configuration in a VM
$ nixos-rebuild build-vm --flake .#my-server

Real-World Setup

Here's what I actually run:

All configured in one flake. One git push and a rebuild deploys everything consistently.

Tip: I packaged my NixOS + K8s configs as a DevOps toolkit. If you want to get started with declarative infrastructure, it's a solid foundation.

The Learning Curve

I won't sugarcoat it: NixOS has a steep learning curve. The Nix language is functional, not imperative. Your first week will feel like you're fighting the system. Your second week will start clicking. By month two, you'll wonder how you ever managed servers without it.

Resources that helped me:

When NOT to Use NixOS

NixOS isn't for everyone. If your team is deeply invested in Ansible/Puppet and everything works fine, the migration cost might not be worth it. If you need bleeding-edge hardware support on day one, Ubuntu/Fedora might be better. And if your team doesn't want to learn a new language, Nix will be a hard sell.

Conclusion

NixOS transformed how I manage infrastructure. My servers are reproducible, rollbacks are instant, and my configs are version-controlled. It's not perfect — the learning curve is real and documentation can be sparse — but for anyone serious about infrastructure as code, it's worth the investment.

Got questions about NixOS? Drop me a line. Or check out my nix-config on GitHub for a working example.

$ subscribe --to newsletter

SRE tips, infrastructure patterns, and NixOS guides — straight to your inbox. No spam, just signal.

Delivery via newsletter service. Unsubscribe anytime.

Related Posts

← Back to Blog