I have a project where we’re using
nix-shell to provide a standard development environment. It’s been pretty great! As a next step I’d like to set up CI so it uses the the same derivation we’re using for our development environment. I’m not sure what the best approach is here and was wondering if anyone had some tips for me.
Currently we run CI in an Ubuntu based Docker image, in Jenkins. In an effort to make small steps I’d ideally like to replace the docker image (currently created from a fairly massive Dockerfile) with either a nix-based or nix-generated docker file.
The first thing I tried was building a docker with nix, based on the pretty awesome blogpost Cheap Docker images with Nix. While I can get this to work, there’s two aspects of this approach I’m not very fond of:
The generated image is pretty large. Around 8 times larger than the ubuntu-based image we’re using now.
Using this approach I’m not responsible for caching this step of the build, and I’m not sure what the best way would be to set this up. Building the docker image takes a pretty long time, so I don’t want to run it on every build.
We use the Jenkins equivalent of
docker build .to build our current ubuntu-based image in our CI process, which builds the Dockerfile only when it changes, and then only part of the layers.
nixisn’t installed on the Jenkins host, I need to run the command that sees nix building the ci container inside of a container itself. But that means that at the end of the build, I throw away the docker container used to run the build along with its nix store, meaning the next build will have to start from scratch. Is there an easy way to cache the nix store in the container at the end of a build?
Are there other approaches I could try? Should I stick with the current approach and, if so, are there things I might improve about it?