Home Explore Blog Models CI



nixpkgs

5th chunk of `doc/build-helpers/images/dockertools.section.md`
2647becc3f1c0b5751da7c0339f5da8b11f66e3329a8fb2c0000000100000fb6
$ docker image load -i /nix/store/p4dsg62inh9d2ksy3c7bv58xa851dasr-docker-image-redis.tar.gz
(some output removed for clarity)
Loaded image: redis:latest
```
:::

:::{.example #ex-dockerTools-buildImage-runAsRoot}
# Building a Docker image with `runAsRoot`

The following package builds a Docker image with the `hello` executable from the `hello` package.
It uses `runAsRoot` to create a directory and a file inside the image.

This works the same as [](#ex-dockerTools-buildImage-extraCommands), but uses `runAsRoot` instead of `extraCommands`.

```nix
{
  dockerTools,
  buildEnv,
  hello,
}:
dockerTools.buildImage {
  name = "hello";
  tag = "latest";

  copyToRoot = buildEnv {
    name = "image-root";
    paths = [ hello ];
    pathsToLink = [ "/bin" ];
  };

  runAsRoot = ''
    mkdir -p /data
    echo "some content" > my-file
  '';

  config = {
    Cmd = [ "/bin/hello" ];
    WorkingDir = "/data";
  };
}
```
:::

:::{.example #ex-dockerTools-buildImage-extraCommands}
# Building a Docker image with `extraCommands`

The following package builds a Docker image with the `hello` executable from the `hello` package.
It uses `extraCommands` to create a directory and a file inside the image.

This works the same as [](#ex-dockerTools-buildImage-runAsRoot), but uses `extraCommands` instead of `runAsRoot`.
Note that with `extraCommands`, we can't directly reference `/` and must create files and directories as if we were already on `/`.

```nix
{
  dockerTools,
  buildEnv,
  hello,
}:
dockerTools.buildImage {
  name = "hello";
  tag = "latest";

  copyToRoot = buildEnv {
    name = "image-root";
    paths = [ hello ];
    pathsToLink = [ "/bin" ];
  };

  extraCommands = ''
    mkdir -p data
    echo "some content" > my-file
  '';

  config = {
    Cmd = [ "/bin/hello" ];
    WorkingDir = "/data";
  };
}
```
:::

:::{.example #ex-dockerTools-buildImage-creatednow}
# Building a Docker image with a creation date set to the current time

Note that using a value of `"now"` in the `created` attribute will break reproducibility.

```nix
{
  dockerTools,
  buildEnv,
  hello,
}:
dockerTools.buildImage {
  name = "hello";
  tag = "latest";

  created = "now";

  copyToRoot = buildEnv {
    name = "image-root";
    paths = [ hello ];
    pathsToLink = [ "/bin" ];
  };

  config.Cmd = [ "/bin/hello" ];
}
```

After importing the generated repository tarball with Docker, its CLI will display a reasonable date and sort the images as expected:

```shell
$ docker image ls
REPOSITORY   TAG      IMAGE ID       CREATED              SIZE
hello        latest   de2bf4786de6   About a minute ago   25.2MB
```
:::

## buildLayeredImage {#ssec-pkgs-dockerTools-buildLayeredImage}

`buildLayeredImage` uses [`streamLayeredImage`](#ssec-pkgs-dockerTools-streamLayeredImage) underneath to build a compressed Docker-compatible repository tarball.
Basically, `buildLayeredImage` runs the script created by `streamLayeredImage` to save the compressed image in the Nix store.
`buildLayeredImage` supports the same options as `streamLayeredImage`, see [`streamLayeredImage`](#ssec-pkgs-dockerTools-streamLayeredImage) for details.

:::{.note}
Despite the similar name, [`buildImage`](#ssec-pkgs-dockerTools-buildImage) works completely differently from `buildLayeredImage` and `streamLayeredImage`.

Even though some of the arguments may seem related, they cannot be interchanged.
:::

You can load the result of this function in Docker with `docker image load`.
See [](#ex-dockerTools-buildLayeredImage-hello) to see how to do that.

### Examples {#ssec-pkgs-dockerTools-buildLayeredImage-examples}

:::{.example #ex-dockerTools-buildLayeredImage-hello}
# Building a layered Docker image

The following package builds a layered Docker image that runs the `hello` executable from the `hello` package.
The Docker image will have name `hello` and tag `latest`.

```nix
{ dockerTools, hello }:
dockerTools.buildLayeredImage {
  name = "hello";
  tag = "latest";

  contents = [ hello ];

  config.Cmd = [ "/bin/hello" ];

Title: dockerTools.buildImage: Additional Examples and Introduction to buildLayeredImage
Summary
This chunk continues with examples for `dockerTools.buildImage`, demonstrating how to use `runAsRoot` and `extraCommands` to create directories and files within an image, noting the difference in path handling between the two. It also shows an example of setting the image creation date to the current time using `created = "now"`, while cautioning about its impact on reproducibility. The text then introduces `buildLayeredImage`, explaining that it leverages `streamLayeredImage` to create a compressed Docker-compatible repository tarball saved to the Nix store. It clarifies that `buildLayeredImage` and `buildImage` are distinct functions despite some similar arguments, and provides an example of how to build and load a layered Docker image.