That's nice and it showcases how Nix can create a declarative process management atop a script-based imperative manager. How is your experience with it? Also note that there's https://github.com/svanderburg/nix-processmgmt, a manager agnostic processes management framework supporting s6 among others, but your way seems a bit more straightforward.
My use case is to get my VPS run a web and mail service on Nixos but without the bloated binary logging of journalcontrol. The indexes in these log files change heavily between snapshots so they take up way more disk space than append-only text logs, that snapshots very well on ZFS.
My experiences while building:
- It's easy to use the config.system.services tree of the user-services (ssh, bind, caddy, etc) to create s6-services;
- Sometimes it needs a change to make it work [1] on s6;
- That same change seems oblivious to systemd. I guess it just starts the process and never bothers to monitor liveness. So much for a process management system ;-)
- Nixos packagers seems overworked, as my pull requests seem to get stuck ;-(
- Nixos use of systemd leaves a lot of decisions to resolve at boot time, decisions that I want to make at build time with s6;
- However, I cannot create a s6 dependency tree specification at build time, that's still at run time;
- Because S6 uses the service-directory to store state-files in the same directory (no /etc-/var split).
In NixOS it's trivial to use and define NixOS modules, which handle restarting/starting/stopping systemd units. See the wiki example[0] on how to define and use a service that greets the user with GNU Hello. Also, since you have access to Nixpkgs, you can make the ExecStart as complicated as you want with whatever dependencies you desire, and trivially share it with others.
It's basically just a nice way of composing the different parts of your system.
E.g. you could write a NixOS module to manage your web app. You declaratively
configure that you want to run Nginx, Postgres, etc. open some ports, connect to your VPN and basically everything else you might want. There are a lot of existing modules, so in most cases you have to write very little code yourself. If you want to scale your system to run on multiple systems or containers, you can do that with relative ease.
You also have a singular source of truth for all of your information, down to your application binaries. Your configuration says you are using Postgres version X.Y.Z with compilation options A, B and C, so that's exactly what is running on your systems.
You can override NixOS's predefined systemd settings from _outside_ using NixOS module options. This allows you to change default settings that are not optimal for your use case, without having to patch NixOS itself, or write your own unit config.
For example, systemd by default permanently gives up restarting services after a few number of tries (e.g. 5), even if you have set `Restart=always`. This is suboptimal for web servers that should recover by themselves after arbitrarily long failures (e.g. network downtimes outside of your control).
This sets/overrides just that specific systemd option for the existing nginx module. On other distros, you often have to resort to global mutation in `/etc` that does not compose well.
We use NixOS for our infra (having used Ansible before), and this ability to override anything cleanly and keeping defaults otherwise made for much easier to maintain infra code and less ugly/surprising compromises.
>On other distros, you often have to resort to global mutation in `/etc` that does not compose well.
Why does this "not compose well" ?
You don't have to override the whole unit as /etc/systemd/system/nginx.service , which would have problems if two things wanted to override different parts of the original unit. Just drop an override file in /etc/systemd/system/nginx.service.d/90-restart-always.conf with that one specific config you want to override.
Because you cannot easily write libraries/components that do this.
In NixOS, other modules can override the options of other modules. For example, a a web app can set the nginx options that it needs, instead of requiring you (the admin) to "drop a file" in /etc.
This is one of the reasons why on Ansible Galaxy (community repository of Ansible roles) there are 527 nginx roles [1], and in NixOS there is 1 nginx module that everybody code-reuses.
If the point is that it's not manipulating a system-level nginx service but a user-level one, then writing the systemd override file in the way I described doesn't require root either.
You'll be defining your own systemd units with ease.
systemd to you will be journalctl and systemctl. So pretty good.