Image

Instead of deploying a 3rd party image, we can build our own.

We rely on the upstream dockerTools package here. Specifically, we can use the buildLayeredImage function to define our image:

    image.nix
    
{ dockerTools, nginx }:
dockerTools.buildLayeredImage {
  name = "nginx";
  contents = [ nginx ];
  extraCommands = ''
    mkdir -p etc
    chmod u+w etc
    echo "nginx:x:1000:1000::/:" > etc/passwd
    echo "nginx:x:1000:nginx" > etc/group
  '';
  config = {
    Cmd = [ "nginx" "-c" "/etc/nginx/nginx.conf" ];
    ExposedPorts = {
      "80/tcp" = { };
    };
  };
}

Then we can import this package into our docker module:

    default.nix
    
{ kubenix ? import ../../../.. }:
kubenix.evalModules.${builtins.currentSystem} {
  module = { kubenix, config, pkgs, ... }: {
    imports = with kubenix.modules; [ k8s docker ];
    docker = {
      registry.url = "docker.somewhere.io";
      images.example.image = pkgs.callPackage ./image.nix { };
    };
    kubernetes.resources.pods.example.spec.containers = {
      custom.image = config.docker.images.example.path;
    };
  };
}

Now build the image with

nix build -f . --json config.docker.export

Render the generated manifests again and see that it now refers to the newly built tag:

{
  "apiVersion": "v1",
  "items": [
    {
      "apiVersion": "v1",
      "kind": "Pod",
      "metadata": {
        "annotations": {
          "kubenix/k8s-version": "1.24",
          "kubenix/project-name": "kubenix"
        },
        "labels": {
          "kubenix/hash": "ac7e4794c3d37f0884e4512a680a30d20e1d6454"
        },
        "name": "example"
      },
      "spec": {
        "containers": [
          {
            "image": "docker.somewhere.io/nginx:w7c63alk7kynqh2mqnzxy9n1iqgdc93s",
            "name": "custom"
          }
        ]
      }
    }
  ],
  "kind": "List",
  "labels": {
    "kubenix/hash": "ac7e4794c3d37f0884e4512a680a30d20e1d6454",
    "kubenix/k8s-version": "1.24",
    "kubenix/project-name": "kubenix"
  }
}

Of course, to actually deploy, we need to push the image to our registry. The script defined at docker.copyScript does just that.

$(nix build -f . --print-out-paths config.docker.copyScript)