nlewo / nix2container

An archive-less dockerTools.buildImage implementation
Apache License 2.0
501 stars 45 forks source link

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

Open terlar opened 5 months ago

terlar commented 5 months ago

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):

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.