[Nix-dev] Multiple instances - detecting resource collisions - nixos module system question

Thomas Strobel ts468 at cam.ac.uk
Sun Jan 18 14:12:21 CET 2015

On 01/14/2015 11:17 PM, Marc Weber wrote:
> If you use multiple apaches/nginx/mysql/postgresql/whatever instances
> its likely to miss adjusting the port or whatsoever. Therefore I'd like
> to implement a simple "resource tracking" module which fails if a
> resource such as tcp/ip port or socket or such gets used multiple times.
> It should look like this: http://dpaste.com/10RKJSQ
> A test like this:
>        resources.tcp-ports."80" = {};
> causes:
>   The option `resources.tcp-ports.80.allowCollisions' defined in `/etc/nixos/nixpkgs/nixos/modules/misc/resources.nix' does not exist.
> which I don't get because the dpaste sets a default value for
> allowCollisions.
> Thus does anybody just spot what I'm doing wrong?
> If we are at it: Eelco Dolstra proposed "services.mysql.services" or
> such. What about services.mysqls ? We could deprecade services.mysql
> then and ask users to switch slowly. No naming collisions. Naming is
> short and could be adopted to other services.
> Marc Weber
> _______________________________________________
> nix-dev mailing list
> nix-dev at lists.science.uu.nl
> http://lists.science.uu.nl/mailman/listinfo/nix-dev

I think you're pushing into a very interesting direction!

So do I understand it correctly that you want to define a framework
which checks whether the port assignments for individual services are
consistent? So the port numbers are still kept in the service definitions?

I'm wondering whether it is possible to go the other way and to
centralize the port definitions and to forward the assignments to the
individual services? I think of something where I can see in one place
which service is attached to which interface, here e.g. localhost, the
external interface, an interface secured through IPsec or maybe services
run behind tor:

attach.localhost = {
   http = service.apache.privatePorts;
   "8080" = service.myPrivateProxy {config = 1};
   "8081" = service.myPrivateProxy {config = 2};
   "8082" = service.myPrivateProxy {config = 3};

attach.external = {
  http = services.apache.publicPorts;
  smtp = services.postfix;
  DEFAULT = services.dns;

attach.ipsec = {
  ipsec_configuration = {...};
  services = {
    imap = services.cyrus;

attach.tor = {
  tor_configuration = {...};
  services = {
     I_am_here = services.somethingHidden;

Services would only start if all necessary ports are assigned through an
attach statement. Firewall rules could be automatically set through the
attach framework, as suggested by Moritz. Moving a service e.g. from a
private to a public interface would then be achieved by just attaching
it to a different interface. Service parameters could be overwritten to
define multiple instances of a service, like for myPrivateProxy in the
example. I would also classify ports of services into e.g. public or
private ports, like for apache in the example. That would allow to
easily expose the public ports on a public interface and have the
private ones e.g. only accessible through localhost or maybe IPsec.
Maybe it's also possible to have default ports defined within a service
definition, and then attach a service using its default ports, e.g.
somehow like for dns in the example.

What do you think? It's just an idea that I wanted to share.


More information about the nix-dev mailing list