nix2container icon indicating copy to clipboard operation
nix2container copied to clipboard

How to create a docker image with nix2container that can be used to build nix2container images?

Open terlar opened this issue 1 year ago • 1 comments

Hello, thank you very much for this project. It looks quite promising.

I want to use nix2container to automate building of container images, and doing that on my CI requires to be executed within a container image. What better way than to build that container image with nix2container?

Currently I have this:

{
  # Build support
  buildEnv,
  nix2container,
  writeShellApplication,
  # Runtime
  curl,
  gnugrep,
  jaq,
}:

let
  get-access-token-from-metadata-server = writeShellApplication {
    name = "get-access-token-from-metadata-server";
    runtimeInputs = [
      curl
      jaq
    ];
    text = ''
      curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
        --silent \
        -H "Metadata-Flavor: Google" |
        jaq --raw-output .access_token
    '';
  };

  root = buildEnv {
    name = "container-builder-root";
    paths = [
      get-access-token-from-metadata-server
      gnugrep
    ];
    pathsToLink = "/bin";
  };

  nix-flakes = nix2container.pullImage {
    imageName = "nixpkgs/nix-flakes";
    imageDigest = "sha256:89c86767d32fb27675f7bcb4f5f3a1f9f481b0fd9a4c4a4e08b283fde265e4c5";
    sha256 = "sha256-r6rGUpJZDY11NdC6ToxCegybkdZsq1vmK6rVdytsk8k=";
  };
in
nix2container.buildImage {
  name = "europe-docker.pkg.dev/seb-k8s-ci-cd-junxa/seb-k8s-ci-cd/container-builder";

  fromImage = nix-flakes;

  copyToRoot = [ root ];

  config = {
    entrypoint = [ "/bin/bash" ];
    env = [ "SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt" ];
  };
}

This is working, but then the image has to build (or pull from cache I guess, haven't enabled yet):

  • /nix/store/y7pja4n2b04j45sknwmivkl27mg3dgg1-skopeo-1.14.2.drv
  • /nix/store/p387dfxsh9myf2bc6lbdpngp8idilvrg-nix2container-1.0.0-go-modules.drv
  • /nix/store/699r95xr9zxdd013z06h7i3y954li8w0-nix2container-1.0.0.drv

But I wanted these derivations to be part of the image, I thought I could achieve this with:

  layers = [
    (nix2container.buildLayer {
      deps = [
        nix2container-bin
        skopeo-nix2container
      ];
    })
  ];

However, that just added a bunch of stuff, but it still built those derivations. I guess it is due to the drv files not being copied, but just the resulting outpath?

Is there a way to add "nix cache" to the image itself?

PS. I'm also using the nixpkgs nix-flakes docker image as base as it seemed quite difficult to get a working nix image otherwise. First it complained about build users not working and when I got that working it refused to build the same image I built within that image, seems those derivations were "locked" and caused issues.

terlar avatar Mar 16 '24 16:03 terlar

I've been trying to do something similar, with the following thought process:

  • I can use the devenv base image in ci and run devenv shell to build the environment, but this is relatively slow
  • I'd therefore like to build the shell environment with devenv container build shell and use that in my devenvironment
  • This then works for most cases, but for building dockerfiles with nix2container it runs into issues (error below)
Failed accessing path "/nix/store/si43v2qd4yl8if9ibwcxnl9rdx0h1c6x-devenv-container-etc": lstat /nix/store/si43v2qd4yl8if9ibwcxnl9rdx0h1c6x-devenv-container-etc: no such file or directory

*Note that this is using nix2container from devenv, so it might not be a nix2container issue (I will also post there)

rob-mur avatar Nov 10 '25 10:11 rob-mur