Dockerfile for nixos/nix

Where can I find the Dockerfile that creates the nixos/nix image from Download | Nix & NixOS?

I see a lot of examples for creating Docker images with nix, but I am looking for best practices for creating nixos-based containers using standard docker/podman tooling…

Thanks!

I too am pondering on this topic. But I just want to add few more specifications on that.

Baseless image is considered lightweight as it doesn’t have a base image.
And there are 2 ways to create baseless image in nix.
Layered image and non layered image.
Even I would like to which is more the nix way i.e most reproducible while locking the versions etc.

I wish someone could help with this topic with much more clarity

Reasonably certain there is none, it’s built with this nix file: nix/docker.nix at e4bda20918ad2af690c2e938211a7d362548e403 · NixOS/nix · GitHub

Both of these can also produce images with a “base”, i.e., something equivalent to what you would put in FROM in a Dockerfile.

There is no difference in this regard.

The only difference is that you can create fine-grained layers with the layered image, which can make the image more space efficient in large, multi-image deployments if you build all your images with it, and do so with some planning. The output of the non-layered image is equivalent to the other if you don’t do this planning, and its builder is much easier to use.

If you don’t fully understand the difference, you should probably use buildImage, it will be exactly as good as the other function in your hands.

1 Like

Thanks for the explanation. And wondering that, by space efficient u mean each layers will be in nix store and for other image creations it might utilise the layer?
And that’s what u mean by planning it right? :thinking:

If I follow correctly, you are suggesting I base of the docker image with a Dockerfile like this:

FROM docker.io/nixos/nix
...

…and then proceed to configure the container with follow-up commands?

No, from the nix store size perspective both are equivalent. buildLayeredImage doesn’t actually create the layers independently, it creates a script that will build them all one-by-one, and then runs that script to produce the final image. In either case you will have to store the full image in the nix store, and all its build/input components will also take up space in the store (until garbage collected, assuming they aren’t used by anything else). Nix treats the final image as one archive, completely independent from its inputs.

Once imported into docker, however, the layers can be de-duplicated in the docker storage space, which is where the layered image can help.

I’ve not suggested anything for your situation, just pointed out that the nix image itself also isn’t built with a Dockerfile, since you were asking where it is. I’m not aware of anyone writing a set of best practices either, otherwise I would have pointed it out. Personally, I wouldn’t use docker to build docker images, it’s an awful build system.

That said, if I had to do anything involving dockerfiles and nix, that’s indeed pretty much the only way to start.

After that it depends on the use case. Using garbage collection and splitting layers intelligently may come into play, but heavily depends on what it is you’re aiming to do. If for example you want to build something with nix inside a docker context, but not actually deploy nix into the final image, you may want to create a split image and export the nix build as a nix bundle into a google distroless container. This’d mean you would want to maximize the intermediate layers to maximize build caching. It’s all very awkward and use-case specific, docker is not a good build system.

If you actually build images with FROM docker.io/nixos/nix you aren’t persisting the nix store, so you lose most of nix’ features. Using nix to build the images directly is pretty much always best.

There’s a pretty good chance this is an XY problem anyway, if you tell us what you want to achieve we may be able to give better advice :wink:

1 Like

I’m actually a Bluefin user, and I mostly work within podman/toolbox for my development toolchain (nothing installed in the host system).

I have heard good things about Nix so I wanted to try it. My plan was to just try and install nix into a toolbox, then enter it and create my entire toolchain inside it using nix itself.

Efficiency does not matter much at this point I have plenty of space and it’s mostly a learning exercise at this point.

1 Like

I’ve actually found a couple of interesting projects that may help use nix on the host?:

So it seems that other people are doing away with the toolbox approach and installing Nix on the host, along with its toolset?

I guess if I install these tools on the host, I should be able to build podman images using nix itself on the host right? This would allow me to keep my workflow of doing all development inside a toolbox… Would you suggest I take this route?

Yep, that was pretty much what I was going to say. Using nix in a container will give you nothing but headaches, since persisting the nix store through volumes is impractical - the store holds all binaries, so removing what is in the image and replacing it with an empty mount doesn’t work, and anything else requires awkward hacks.

Thanks, I think I will start with the Determinate Nix Installer as it seems a better starting point for learning bottom-up, then progress to Nix home manager (ublue-os/fleek is deprecated and redirects there) which seems to be doing more on top of regular nix.

It’s a more of a framework for managing dotfiles built on top of nix. If you want to configure your desktop with a nix-based tool, go right ahead, but if you just want to build software nix is what you want.