NixOS, the managed system.
Over the years I have tried many different server management solutions. “Server management” is a vague term by what I mean by it is controlling what software/data/users/configuration is on the server and what processes are running.
I have tried Puppet, SaltStack, Ansible and Chef and while I used both Puppet and Chef for a year and while far better then manual management they weren’t quite enough for me. Each solution has it’s quirks but the real annoyance from me that they are all based about “converging” your server to their computed state.
For example, if I wanted to manage a website in these services. To run this site I need a user to execute the code, the code itself, running the service and configuring the system HTTP server to direct requests to the service. All of the tools can handle this fine, but the interesting behaviour comes when you remove a service. Unless you carefully write a clean-up configuration there will be traces of the service left behind. This is because of the convergence system, they take a recipe that describes a subset of the system and make that subset look as described.
I know you could write a clean up routine but this isn’t something that I want to do for a number of reasons.
- Its error prone, it’s easy to remove something from your configuration instead of leaving a tombstone to ensure it isn’t on the server.
- It clutters your “live” configuration. You can do a manual “garbage collection” but this is back to the unnecessary work problem.
- You have to deal with shared dependencies. If I have site A and B on a server removing site A shouldn’t uninstall the web server because site B still needs it.
It all loops back to doing work for something that you aren’t interested in.
NixOS manages this differently. Conceptually deploying with NixOS is like generating an image from scratch every time, then imaging over the server. There are very few directories that aren’t recreated from scratch (so that you can keep persistent state). However it is actually more powerful then that. NixOS keeps all system data in the “Nix store”. This is the
/nix directory on the system. The store holds immutable data such as packages, config files and application data. The rest of the file system is created for program compatibility and mostly consists of links into the Nix store.
This means that if you remove something from your configuration it will still reside on the server in the store (until garbage collected) but nothing will reference it so it will never be used.
This has other benefits too. Because you can hold multiple versions of any software in the store you can easily roll back to a different configuration. For example if a kernel upgrade goes sour you can select an old revision in the bootloader and you will be in the system exactly as it was before the upgrade.
So what does this mean for server management? This means that removing a role from a server will wipe any files, users, groups and services from a system. You don’t have to worry about what services depend on what packages as they will be kept iff needed. You can even have different versions of the same packages installed simultaneously, each program will use the version it needs.
The age of servers in bad states is over, old ssh keys laying around old vulnerable services still running. No more version conflicts or path conflicts to worry about. I will shortly be writing an introduction to Nix, NixOS and NixOps tutorial to explain how to get started with your own infrastructure.
Before I go I want to make a quick list of all the advantages I have found while using NixOS:
- Easily add and remove services, and knowing that they are really gone.
- Easily customize packages for your needs.
- Add your own programs as easily as any system package.
- Very open source development. Updating and adding packages in the nixpkgs collection is incredibly easy to do and the changes are welcome.
- Ability to run multiple versions incredibly easily.