Create a deployment config file on production server – using Nix?

Hi there,

I use NixOS on a server to serve some web apps using a deployment manager called keter (for Haskell/Yesod web apps).

keter starts the web apps as child processes but doesn’t pass any environment by default (e.g. no PATH). To pass environment, there is a JSON/YAML config file saying PATH: "/nix/store/...".

How do I best generate this config file? It seems that it has to be generated on the production server because only here it can know the paths to binary dependencies. Also the web app binary and the config file has to be packaged together and copied to the deployment directory.

How can this be solved in Nix?

  • flakes seem not perfect since they are more for executing programs, not for building/packaging (in my understanding)
  • a project default.nix with build instructions? Followed by manually copying the artefact from /nix/store/… to the deployment directory?

When you interpolate a string (nix store paths having your binary deps) into a string (your config file), and then you interpolate that string (your config file represented as a store paths) into another string (entrypoint script / runnable), then the closure of that runnable will have everything you need.

That may seem cryptic, but it’s the right way of thinking about the problem.

EDIT: I’m glad @Sandro puts it in more concrete terms below. :grinning_face_with_smiling_eyes:

You can convert nix structures to json/yaml with toJson/toYaml.

If you build them with nix you can get the path beforehand. Otherwise j would recommend to hardcore some static absolute path.

flakes mostly handle how you manage your nixpkgs version. This shouldn’t make a difference here if you use them or not.

Yes. If you want to do it the proper way there should not be any manual steps involved. You can automate copying/symlinking files to somewhere or create a new derivation which created the expected file structure and start that in a service.

1 Like

Thank you both for pointing me in the right direction!

Wow – it seems that in nix there are always so many ways to do something.

I just found this describing how a config file can be integrated in /etc/nixos/configuration.nix.

Since the keter config file is pretty much deployment-specific, it may make sense to define and “generate” it in the NixOS’s configuration.nix.

And then putting a default.nix derivation into the project’s source tree to compile and package the bundle before it is copied to the deployment directory.

Does that sound reasonable? How can I access the config file in the nix store from the project’s derivation file?

It feels like it is a real programming language with all of its benefits and drawbacks.

You are describing a nixos module like services.nginx.

You either assign it to a variable or access it directly from the source with ${./file}

Thanks! I’ll read more about modules.