How to use nix only in docker for a project?

Hi, folx!

I’m not new to nix, but I am a bit shaky on where to go with this concept. Instead of installing Nix globally, for a project, I’d like to try to have it installed in a Docker container then leverage docker compose to run nix commands like nix build or even nix develop, if that’s possible.

Let’s say I was using an Ubuntu image; are there any guides out there for pinning and installing nix on that and using it to build your project?

Thanks for your time :purple_heart:

There is a bit of weirdness if you really want to have a single-user install. So you grab a few dependencies for the installer to work, make a user, install in single-user mode (anything that is non-root), then you should be good.

docker run --rm -it ubuntu
apt update
apt install curl xz-utils
adduser someUsername # follow prompts
mkdir /nix
chown someUsername /nix
su someUsername
sh <(curl -L --no-daemon
. $HOME/.nix-profile/etc/profile.d/
nix --help
nix-built '<nixpkgs>' -A hello

I’ll add the caveat that normally you can use the nix docker image:

docker run --rm -it nixos/nix
nix-build '<nixpkgs>' -A hello

(if you want nix build/develop you’ll need to modify the nix.conf with experimental-features = nix-command flakes)
As for pinning, you can use a specific docker image with a sha256 hash, or use an image like nixos/nix:2.5.0 or specify a more specific nix version you’d like to use after installation.


Thanks for the quick reply! This is super helpful. With regard to the nix docker image and the nix.conf, is that just adding nix-command and flakes to experimental-features, or is it something else?

I got to this point with the Dockerfile,

FROM nixos/nix

WORKDIR /my-project
COPY . /my-project

# Enable flakes
RUN echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf

but I’m going to see if there are patterns for copying over a configuration.nix or some other things in order to set up a full-on dev environment. I also think COPY might also not be quite the right move, and I’ll need to volume things in. TBD…gotta work on my docker-fu.

are you wanting a configuration.nix for NixOS? that probably won’t work, that is meant to manage an entire OS. You can do that with nixos-container or LXC, but not in docker (there are some advanced caveats here, but it’s very likely not what you should be doing).

1 Like

@tomberek Thanks for the feedback! I’ll keep to the simple path, then.

Following up: I managed to get Docker (nixos/nix) + nix flakes + rust working together! Dockerize by rpearce · Pull Request #23 · rpearce/ · GitHub

I’m sure I could do things more efficiently, but this works for now. Feedback welcome!

Last follow up: I updated my nix-rust-template with this. Thanks!

Repo: GitHub - rpearce/nix-rust-template: A reasonable way to start developing a reproducible Rust project

Is there a canonical way to use the nixos/nix image but running as non root? I’m trying to use the postgresql package by way of initdb but it refuses to run as root.

I’d much rather not build my own image and leverage the pre-built one.

I tried USER 30001 (a user that exists on that image already) but no luck.

Also, where is the source for this image now? The old source is archived on GitHub - NixOS/docker: DEPRECATED! Dockerfiles to package Nix in a minimal docker container

Thanks for all your help!

1 Like

The linked repository says “it’s now build in nixos/nix”, where I found these:

1 Like

Helpful, thanks! I should have suspected the repo uses nix itself for building the image, instead of a Dockerfile.

Here’s the actual source: nix/docker.nix at 6524eb4b770380b5a2f17e87a7d1b99a47dbb8f8 · NixOS/nix · GitHub

I don’t understand much of it, but it doesn’t seem super easy to add an extra user and have it support multi platforms. I don’t actually see how multiplatform images are built with docker, but there’s some background here: Is there a `docker buildx` command on NixOS?

1 Like

I ran into the same issues with trying to run as non-root! I even tried the USER 3001 business.

That docker image builder is indeed quite dense. It looks like there’s a ton of root in there :thinking:. Thanks for sharing your finds!

This seems to work ok, give it a try:

FROM ubuntu
RUN apt update
RUN apt install -y curl xz-utils
RUN useradd -m guest
RUN mkdir /nix && mkdir /app && chown guest /nix && chown guest /app

USER guest
ENV USER=guest
RUN curl -L | sh

ENV PATH="/home/guest/.nix-profile/bin:${PATH}"
1 Like

Thanks! @tomberek has a similar setup above, except for the explicit USER setting. I wonder if that’s necessary, as I think a multi-user install is the default? My info could be dated.

Not sure what makes it a single-user install, maybe the fact that it detects it’s not running as root.

But yea, I can confirm the above is a single user install.

@tomberek’s was imperative though, and the sh <(curl -L --no-daemon wouldn’t work for me as RUN command.

Note also that su doesn’t work in a Dockerfile unless you inline it with the command. Same with . or source.

Still, his code was definitely the inspiration.

1 Like