nix2container

repository·master·Indexed 21 days ago

https://github.com/nlewo/nix2container

A tool for creating efficient OCI-compliant container images using Nix. It optimizes workflows by avoiding unnecessary tarball writes to the Nix store and allowing the reuse of existing layers to skip redundant rebuilds and pushes. It provides Nix functions like buildImage, pullImage, and buildLayer, as well as a Go library used by the Skopeo nix transport and a CLI for generating image and layer JSON files from Nix storepaths.

Tokens
3.1K
Snippets
10
Records
17
Agent score
75%

What's inside nix2container

  1. Isolate dependencies in dedicated layers

    master

    To speed up build and push times, you can use the layers attribute in buildImage to specify a set of dependencies that should be isolated. If the dependencies in these layers do not change, the layers are not rebuilt or re-pushed.

    Example: Isolating a script from its dependencies

    { pkgs }: 
    let
      application = pkgs.writeScript "conversation" ''
        ${pkgs.hello}/bin/hello
        echo "Haaa aa... I'm dying!!!"
      '';
    in
    pkgs.nix2container.buildImage {
      name = "hello";
      config = {
        entrypoint = ["${pkgs.bash}/bin/bash" application];
      };
      layers = [
        (pkgs.nix2container.buildLayer { deps = [pkgs.bash pkgs.hello]; })
      ];
    }

    This configuration results in two layers: one containing the bash and hello closures, and a second containing only the script.

  2. Run nix2container tests

    master

    You can run the project's test suite using Nix. The tests build example images with Nix, load them with Skopeo, and run them with Podman to verify output logs. Note that these tests are not executed within the Nix sandbox due to current limitations regarding running containers in the sandbox.

    To run all tests:

    nix run .#tests.all

    To run only the basic tests:

    nix run .#tests.basic
  3. Get started with nix2container

    master

    To use nix2container, add it as an input to your Nix flake. You can then use nix2container.packages.<system>.nix2container.buildImage to define container images. Once defined, you can load the image into a container daemon (like Docker or Podman) using the .copyToDockerDaemon or .copyToPodman attributes provided by the package.

    {
      inputs.nix2container.url = "github:nlewo/nix2container";
    
      outputs = { self, nixpkgs, nix2container }: let
        pkgs = import nixpkgs { system = "x86_64-linux"; };
        nix2containerPkgs = nix2container.packages.x86_64-linux;
      in {
        packages.x86_64-linux.hello = nix2containerPkgs.nix2container.buildImage {
          name = "hello";
          config = {
            entrypoint = ["${pkgs.hello}/bin/hello"];
          };
        };
      };
    }

    To load and run:

    $ nix run .#hello.copyToDockerDaemon
    $ docker run hello:latest
  4. Configure registry authentication for Nix builds

    master

    If using the Nix daemon for building, follow these steps to set up registry authentication:

    1. Perform a docker login URL to the target registry.
    2. Copy ~/.docker/config.json to /etc/nix/skopeo/auth.json.
    3. Ensure the directory and files are readable by the nixbld group:
      sudo chmod -R g+rx /etc/nix/skopeo
      sudo chgrp -R nixbld /etc/nix/skopeo
    4. Bind mount the file into the Nix build sandbox using the extra-sandbox-paths option:
      extra-sandbox-paths = /etc/skopeo/auth.json=/etc/nix/skopeo/auth.json
  5. Use nix2container.pullImage to pull images from a registry

    master

    The nix2container.pullImage function pulls an image from a container registry by name and tag/digest, storing the manifest and layer tarballs in a single store path.

    Arguments:

    • imageName (required): The name of the image.
    • imageDigest (required): The digest of the image.
    • sha256 (required): The sha256 of the resulting fixed output derivation.
    • os (default: linux)
    • arch (default: x86_64)
    • tlsVerify (default: true)
  6. Use nix2container.buildImage to create images

    master

    The nix2container.buildImage function creates an OCI-compliant container image.

    Arguments:

    • name (required): The name of the image.
    • tag (default: image output hash): The image tag.
    • config (default: {}): An attribute set describing the image configuration as defined in the OCI image specification.
    • copyToRoot (default: null): A derivation (or list) to be copied into the image root. Store path prefixes (e.g., /nix/store/...) are removed to relocate them at the image /.
    • fromImage (default: null): An image used as the base image (use pullImage or pullImageFromManifest to provide this).
    • maxLayers (default: 1): Maximum number of layers to create based on store path popularity.
    • perms (default: []): A list of file permissions applied during tar layer creation. Each element is a dict: { path = "..."; regex = "..."; mode = "..."; }.
    • initializeNixDatabase (default: false): Initializes the Nix database within the image (useful for running Nix commands inside the container).
    • layers (default: []): A list of layers built with buildLayer. Store paths in these layers are skipped during the main build to allow for caching/isolation.
  7. Use nix2container.pullImageFromManifest for efficient base images

    master

    The nix2container.pullImageFromManifest function pulls a base image using a supplied manifest.json. This is more efficient than pullImage because:

    • Each layer is in its own store path, allowing for natural deduplication across multiple base images.
    • It avoids Nix-specific hashes, allowing updates by simply re-fetching the manifest.json.

    Arguments:

    • imageName (required): The name of the image.
    • imageManifest (required): The manifest file path.
    • imageTag (default: latest)
    • os (default: linux)
    • arch (default: x86_64)
    • tlsVerify (default: true)
    • registryUrl (default: registry.hub.docker.com)

    Note: imageTag, os, and arch are used for manifest-selection logic in the included getManifest script and do not affect the pulled image content itself.

  8. Use nix2container.buildLayer to isolate dependencies

    master

    The nix2container.buildLayer function allows you to explicitly isolate parts of an image into dedicated layers. This is useful for caching stable dependencies (like Python environments or Node modules) so they aren't rebuilt when application code changes.

    Arguments:

    • deps (default: []): List of store paths to include in the layer.
    • copyToRoot (default: null): Derivation(s) to copy to the image root.
    • reproducible (default: true): If false, the layer tarball is stored in the store path (useful for non-reproducible dependencies).
    • maxLayers (default: 1): Maximum number of layers to create.
    • perms (default: []): List of file permissions to set.
    • layers (default: []): List of layers built with buildLayer to skip during main build.
    • ignore (default: null): A store path to ignore.
    • metadata (default: { created_by = "nix2container"; }): Attribute set for created_by, author, and comment.
  9. Configure flags for layer generation commands

    master

    Both layers-from-reproducible-storepaths and layers-from-non-reproducible-storepaths support the following configuration flags to refine how layers are constructed:

    FlagLongDescription
    -i, --ignore--ignoreIgnore specific paths from the list of storepaths.
    -r, --rewrites--rewritesPath to a JSON file containing path rewrites (objects with path, regex, and repl).
    -p, --perms--permsPath to a JSON file containing file permissions (types.PermPath).
    -h, --history--historyPath to a JSON file containing layer history (v1.History).
    -m, --max-layers--max-layersThe maximum number of layers to generate (default: 1).
    -t, --tar-directory--tar-directory(Non-reproducible only) The directory where tar of layers are created.
  10. Generate an image.json from a Skopeo manifest and blobs

    master

    Use the image-from-manifest command to write an image.json file from a raw Skopeo manifest and a JSON file containing blobs.

    Arguments:

    • OUTPUT-FILENAME: The path where the resulting image.json will be written.
    • MANIFEST.JSON: The path to the manifest JSON file.
    • BLOBS.JSON: The path to the blobs JSON file.

    Example:

    image-from-manifest output.json manifest.json blobs.json
    image-from-manifest OUTPUT-FILENAME MANIFEST.JSON BLOBS.JSON