Remix.run Logo
chuckadams 7 hours ago

Nix is wonderful for reproducible and declarative infrastructure, but how do you manage multiple server instances with it? I have a handful of projects active at any time, and am currently running four web servers, three mysql instances, two postgres, and a partridge in a pear tree. Should I run Nix in Docker, Docker from Nix, or is there a nix-only solution for this?

__MatrixMan__ an hour ago | parent | next [-]

I couldn't speak to separate physical machines, but I run several "servers" as part of my dev environment.

You'd have to ensure that their ports and data directories don't collide, but I don't think you'll have a problem having "process-compose up" start multiple separate mysql, postgres, or webserver instances.

I just dedicate a terminal pane to it so I can arrow around and see the logs and health status of my databases (plus things like Prometheus and Grafana, I like to be able to nuke the cluster and have everything flatline, rather than having telemetry itself die when k8s goes away).

Both mysql and postgres are included in https://github.com/juspay/services-flake which you might find interesting.

wkrp 7 hours ago | parent | prev | next [-]

There are tools such as deploy-rs, colmena, and morph that let you deploy nixOs configs using nix. I can't speak to how good they are personally, I use ansible to push my nix configs.

gf000 7 hours ago | parent | prev | next [-]

I may misunderstand your problem, but I just have a configuration repository for various "hosts". There are a couple of settings I share between them, and then just specify the differences.

"Deploying" one is as simple as `nixos-rebuild switch --flake .#hostName`

chuckadams 7 hours ago | parent [-]

These are all dev environments running at the same time. I wasn't sure if Nix had some kind of port mapping or proxy config for this sort of thing. I'm still partial to having containers as self-contained build artifacts, I just like to have options as dev environments go, and "Docker from Nix" looks like the best option so far. But it's a vast ecosystem, and there's plenty I might be missing.

pxc an hour ago | parent | prev [-]

You just plug Nix into a service manager that you have Nix bring along for you. Many years ago, I did this for a proof-of-concept at work with supervisord[1] and flake.nix. Devenv[2] builds in[3] support for process-compose[4], which GP mentioned. A few years ago, one long-time Nixer even created[5] a framework, nix-processmgmt[6] that abstracts over various service managers including supervisord and s6[7], which can both be used in a self-contained way regardless of the init system on the host.

There are a ton of other open-source process supervisors you can use to manage long-lived processes in a portable way, too, notably Foreman[8] and various clones written in languages other than JS, and GNU Shepherd[9]. In the course of writing this post, I discovered one called dinit[10] which looks sort of similar to s6 and the GNU Shepherd in that it supports both pure usermode operation as well as functioning as an OS's init system. Anyway, all of 'em are in Nixpkgs, so you can pick them up and use them without any packaging work, too.

Service orchestration and containers are basically orthogonal concerns. Before Docker was born, there were already plenty of portable tools for standalone "process supervision", "service management", whatever you wanna call it. So it is after Docker, as well.

If I needed this for one of my dev environments I would take a look at process-compose to decide if it's acceptable to me. If it isn't, then after surveying the contemporary landscape of usermode service managers, I'd then write a devenv module that generates configs for it, and use that.

> Should I run Nix in Docker, Docker from Nix, or is there a nix-only solution for this?

I'd do this in a "Nix-only" way if possible, but if it's convenient for you to run a service via Docker (or Podman or any other container runtime), you can still do that.

If you can safely assume that all of your devs have it available, you can ship the client (`docker` or `podman` CLI or whatever) as part of your Nix environment, then have your process manager launch it via that command line interface. I'd avoid running Nix from within Docker for the purposes of development environments.

--

1: https://supervisord.org/

2: https://devenv.sh/

3: https://devenv.sh/supported-process-managers/process-compose...

4: https://f1bonacc1.github.io/process-compose/

5: https://sandervanderburg.blogspot.com/2020/02/a-declarative-...

6: https://github.com/svanderburg/nix-processmgmt

7: https://skarnet.org/software/s6/

8: https://github.com/ddollar/foreman

9: https://shepherding.services/

10: https://davmac.org/projects/dinit/