Build docker images "derived" from NixOS module?

Imagine you have a fairly complex application that relies on multiple services and uses many configuration options.

For example

  • PostgreSQL
  • Redis
  • NGINX
  • Long shell scripts
  • etc.

I now make this service available as a NixOS module, so everyone can use it easily via the configuration options if they are running NixOS.

So far so good, but what if you want to have a Docker image in addition to the NixOS module?
Within dockerTools.buildLayeredDockerImage you cannot use the NixOS configuration options, and you end up duplicating a lot of the logic you already have in your NixOS module. Also, if you change something about your configuration in the module, you have to change the Docker stuff too, etc. You can work around these issues at least somewhat by using some sort of shared configuration, I suppose, but this seems less than ideal.

What I am basically asking is – is there a tool that allows me to take my existing NixOS module, have this tool inspect it and try to automatically create a docker image from it without so much manual configuration? Or how would you guys approach this?

For background, I am not currently using Docker at all, anything like Compose, and no third party nix libraries like devenv. I basically do something similar to GitHub - Mic92/nixos-shell: Spawns lightweight nixos vms in a shell for the dev environment. So I want to use nix for everything and just need this docker image.

Update: I found this older post, which is also what I am looking for:

@augu5te I saw you commented on this topic with a few options, but I don’t think any of these tools really meet my expectations. What would you do for my given scenario? Just manually reproduce the necessary module options for the docker image, or is there some kind of new tool specifically for this usecase?

Docker adds its set of constraints and it’s not designed to integrate easily with systemd. So developing a tool which converts a bunch of systemd managed services from NixOS to Docker images is not simple and raises several issues.
We’re developing a tool which explores this kind of question but not in the same terms, you can have a look as inspiration NixOS Compose

This looks interesting.

So it basically allows you to use the NixOS module options to declare the environment and then deploy it for different use cases (vms, docker images, etc.), here called flavors?

Yes, the main goal is that the “composition” (which describes Nixos configuration for each nodes) can be used without modification for each flavor (bare metal, vm, container…). This greatly simplifies developments, testings and benchmarking. We have a docker’s flavor, but it does not generate a standalone image(s), we generate a thin layer with host’s nix store mounts (as Aron). A standalone approach suppose a bundle phase, it’s feasible but need some devs.

There’s been some talk about generalizing nixos modules to be less dependent on systemd - in theory that would allow sharing more code between nixos, home-manager, nix-on-non-nixos, docker, etc.

The main RFC is https://github.com/NixOS/rfcs/pull/163 I think, and it was recently discussed at in the Brainstorm for RFC: Assimilate home-manager into Nixpkgs monorepo - #14 by waffle8946 thread.

I love the goal, but I’m not sure yet whether ‘more layers of indirection’ will work out - sometimes ‘multiple simple abstractions’ turns out to be simpler than ‘one general abstraction’, however much we’d like that not to be the case :slight_smile: