NixOS modules rendezvous

I started working on some personal servers and web services on them, and found that I needed (or wanted) to author quite a bit of raw modules code to make things work.

In part this is because I wanted to be deploying behind Apache, and while there are modules for Apache, and there are Ruby webservice modules for Nginix, there’s no clear way to connect those up. The webservice modules assume an Nginx host. I wound up writing Apache modules and cribbing from the Nginx ones.

It seems like there’s a fairly common pattern here, and I wonder if there’s a common way to address it. For instance, there are several window managers and display managers, and they work together in some combinations. All the NixOS daemon scripts assume systemd. I’m sure there’s other examples that haven’t sprung immediately to mind.

What I contemplate is a kind of “rendezvous” layer. In my motivating example, I’d’ve configured a “webservice” style module, and it would get the generic “webserver” as one of its parameters. The webserver set would have functions for adding a webservice (or a static web site, which I also wanted), that the webservice could call.

Before I get too much further, is that making sense? I think it looks a little like virtual packages in other distros (Gentoo, for sure) or the “provides” attribute for some packaging systems.

First of all, I think that the following blog post would be of interest for you [1].

Your idea definitely makes sense, but as many good ideas, it was never implemented. There are some technical difficulties and the inevitable implementation bikeshedding.

From an implementation perspective, there is always the issue of managing the O(n²) combinations of modules and “master” modules. In this case, most services will need some extraConfig, which must be defined for each httpd/apache/lighttpd…
To avoid that, it is possible to define some module interface for all the options, but that is a larger effort.

As for the general pattern, yes, all services rely on systemd, and making them more generic to other inits would again require a lot of work.

May I suggest that you start a simple implementation for a frequently used web service behind both apache and nginx to give a hands-on mwe of your design ?
You would get useful feedback(shedding ;-)).

– Layus

[1] https://lastlog.de/blog/posts/advanced_webservices_on_nixos.html

Upping the ante: There could be a more advanced representation of resources like ports, hosts and urls, such that a webserver could be configured behind a port and nix would ensure that there is only one service behind each ip. So apache could own port 80 and 8080. Apache in turn would provide resources for hostname/port/url{prefix/pattern} behind which modules of the web service kind could reside. The whole architecture could be made agnostic to systemd or nginx, at the cost of testing aggressively all the n² combinations lest we end up with a severely broken set of less used alternatives.

See also Develop a universal web service definition · Issue #22067 · NixOS/nixpkgs · GitHub

I think it’s a great idea but I know that it will be a ton of work which is probably why nobody has actually done it yet. But the itch hasn’t been sufficiently annoying for someone to do something about it.