Hacker News new | ask | show | jobs
by sorbits 1848 days ago
> and a few servers

The problem I see with NixOS on a typical personal server is that you have to setup all these things using nix expressions, from which the actual configuration files are generated.

That means if you e.g. want to install postfix, instead of learning about main.cf you have to learn the syntax of the nix configuration wrapper for postfix, and postfix having hundreds if not thousands of options, many referring to external files/databases, you have to hope that whoever did this configuration wrapper, supported all the features of postfix that you want to use.

I am using nixpkgs on macOS, and I run a personal server with mail (for a bunch of people), web (for a bunch of sites), DNS (for a bunch of domains), etc. and while I would love to switch to declarative configuration, I fear I would run into shortcomings with the configuration wrappers for the various software packages I use.

I am curious if anyone have experience to share?

4 comments

I run several personal NixOS servers. it's definitely doable without custom expressions (I can't remember the last time I had to write one).

lots of services defined in the NixOS options will have an "escape hatch" option named something like `extraConfig`. this usually lets you append verbose text to a complex config file, like in the case of Postfix where the options couldn't conceivably cover everything.

you can also always just write a static file to /etc if you want or need to:

    environment.etc.foo-config = {
      target = "foo.conf";
      text = ''
        enable_spline_reticulator = true
      '';
    };
as well as running one-off systemd services declaratively:

    systemd.services.foo = {
      after = [ "network-online.target" ];
      wantedBy = [ "multi-user.target" ];

      serviceConfig = {
        ExecStart = ''
          ${pkgs.foo}/bin/food \
            --config /etc/foo.conf
        '';
        User = "foo";
        Restart = "on-failure";
      };
    };
(both of those examples are copied more or less straight from my daily driver NixOS 20.09 laptop before I made the details generic)

another useful escape hatch is that you can run Docker/Podman containers declaratively. I have some things I want the flexibility to upgrade on a different cadence than NixOS itself (such as my family's "production" Jellyfin server) that I just run as standalone Docker containers with volume mounts for their data.

Your best friend is https://search.nixos.org/options

From a quick search, it seems you can use `services.postfix.config` and pass key-value pairs as arbitrary options. Not familiar with this service, but usually if a given one has more complex syntax, there is a “pass-through” option that will simply append to the given config file whatever text you provide, as well as as the sister reply says you can create manually additional files.

The thing with a lot of server software (like postfix) is that configuration is usually spread across many files.

And then there is the re-use of things between services, for example DKIM’s generated public key should be made available as a TXT record by the DNS server, the SSL certificate kept up-to-date by the web server should be used by both the smtp and imap servers, though it may need to include the full chain, and services may need to be relaunched, if the certificate is updated, etc.

I was hoping to hear from someone who had managed to get a “full” server running (with SMTP, IMAP, DKIM, DNS, DNSSec, HTTPS via ACME, etc.), because while I know that I can output raw configuration files, it seems like an extremely daunting task to weave all this together in something semantically meaningful.

Right now I have /etc under git control and a Makefile that handles all dependencies between the various pieces (i.e. to ensure proper files are regenerated/indexed as needed, and services relaunched when dependencies are updated).

I do have all these things (https://github.com/Mic92/dotfiles/blob/master/nixos/eve/modu..., https://github.com/Mic92/dotfiles/blob/master/nixos/eve/modu..., https://github.com/Mic92/dotfiles/blob/master/nixos/eve/modu... ...). Especially things like ACME work a lot better the NixOS-provided curated and unit-tested acme module compared to setting up it yourself. You can also use the Nixos simple mail server setup that already provides sane defaults and puts the individual nixos modules together: https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/
Appreciate the links, thanks!
Even better: `man configuration.nix` and `man home-configuration.nix`. I used the website first, but found out just using the quite good man pages is much much faster.
NixOS makes it easy to emit raw configuration files if you want. I do this for software where I want more control than the Nix wrapper exposes.
> I am curious if anyone have experience to share?

With one exception (nginx, because it's very well supported) I always just use raw config files and ignore the options. For TVL[0] we've written a bunch of NixOS modules[1] ourselves where the upstream one was either not flexible enough, or deviated strongly from how we wanted things to work.

Nix is the kind of tool that lends itself well to solutions that are more complicated than the problem, but once you get comfortable with the tool it's easy to sidestep that. Despite these warts it's 100% worth the investment.

[0]: https://code.tvl.fyi/about/

[1]: https://cs.tvl.fyi/depot/-/tree/ops/modules

Maybe you could propose the improvements in nixpkgs so we can all benefit from them?
In some cases the upstream modules are simply targeting a different use-case. A lot of modules are written by someone scratching a specific itch - ours are no different, but scratch different itches.

I think a better solution (long-term) is actually a redesigned way of doing service declarations where we're dealing with composable bits of data that describe services (so that a module isn't all-or-nothing anymore). Too much on the plate to design that though ...