Build a Nix docker image in Gitlab CI
Frustrated with fetching, checksum checking, and extracting of the
packages in a Dockerfile that I need for a project, this week finally
found a way to build docker images with Nix. Embedded in nixpkgs
there are the functions buildImage and buildLayeredImage. With
these functions you can build docker images that are assembled from
Nix packages. How wonderful is that?
Here is the Nix derivation that I have used:
with import <nixpkgs> {};
pkgs.dockerTools.buildLayeredImage {
name = "k8s-deployer";
tag = "latest";
created = "now";
contents = with pkgs; [
kubectl
kubernetes-helm
terraform
yq
jq
bash
coreutils # mkdir and such
python3
moreutils # for sponge
git
cacert
curl
];
extraCommands = ''
mkdir -p usr/bin
ln -sf ${pkgs.coreutils}/bin/env usr/bin/env
mkdir tmp
chmod 1777 tmp
'';
config = {
Cmd = [ "/bin/bash" ];
WorkingDir = "/";
Env = [
"SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt"
];
};
}
Test it by building it locally and loading it into Docker:
nix-build -o image.tar.gz
docker load -i ./image.tar.gz
docker run -it --rm k8s-deployer:latest
… and here is how to build it in Gitlab CI, and push it to the Gitlab Container Registry:
stages:
- build
build:
stage: build
image: nixos/nix:latest
script:
# For pinning:
# - export NIX_PATH="nixpkgs=https://github.com/NixOS/nixpkgs/archive/ab593d46dc38b9f0f23964120912138c77fa9af4.tar.gz"
- nix-channel --update
- nix-build -o image.tar.gz
- |
nix run nixpkgs.skopeo -c skopeo \
--insecure-policy \
copy \
--dest-creds $CI_REGISTRY_USER:$CI_REGISTRY_PASSWORD \
docker-archive:image.tar.gz \
docker://$CI_REGISTRY_IMAGE:latest
This currently always builds from unstable, but by uncommenting the
line with export NIX_PATH=... you can pin to a specific Nixpkgs
version.
For more examples on how to use buildImage and buildLayeredImage
see this link.