Using NIX to build Python docker deployment images
This is a companion post to building Python docker deployment images using pyenv and poetry. Where in that post the image is built using standard Python tooling, in this post the images are built using the fully declarative, reproducible NIX system.
The advantage of this approach is full control of the software supply chain, easy ways to create highly optimised machine code, and hooks to modify any of the software sources as needed before compilation.
The build is straightforward:
- NiX has built-in support for building docker-compatible images
using
dockerTools.buildImage
function - The Python and needed packages environment is defined using the
python3.withPackages
function
This is all! A fully declarative image is built which can easily be modified with custom compilation options, patches etc. Here is the full NiX file:
let
pkgs = (import <nixpkgs>) { } ;
scienv = pkgs.python3.withPackages(ps: with ps; [ numpy scipy] );
in
rec {
jax = pkgs.dockerTools.buildImage {
name = "scipy";
tag = "latest";
copyToRoot = pkgs.buildEnv {
name = "image-root";
paths = with pkgs; [
coreutils
bashInteractive
scienv
];
pathsToLink = [ "/bin" ];
};
};
}