Building docker images based on another distro


I’m trying to get familiar with building docker images in NixOS based on some other standard distro images.

The manual was a bit confusing:

The following command does not work for me:

nix run nixpkgs.nix-prefetch-docker -c nix-prefetch-docker --image-name mysql --image-tag 5

error: unrecognised flag '-c'
Try 'nix --help' for more information.

I played around a bit and I think the command should be something like:

nix run 'nixpkgs#nix-prefetch-docker' -- --image-name mysql --image-tag 5
<seemingly valid output>

Now using the command on the image I actually want:

nix run 'nixpkgs#nix-prefetch-docker' -- --image-name centos --image-tag 7
Getting image source signatures
Copying blob 2d473b07cdd5 done
Copying config eeb6ee3f44 done
Writing manifest to image destination
-> ImageName: centos
-> ImageDigest: sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4
-> FinalImageName: centos
-> FinalImageTag: 7
-> ImagePath: /nix/store/mnd9ca0nmm6zs8i4aqz08ia9j3xqd7j3-docker-image-centos-7.tar
-> ImageHash: 0jm1wba4nj4s0ra2i8n4x8b5dxxwmfq49wv1nmz9q43mqsjbjmcs
  imageName = "centos";
  imageDigest = "sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4";
  sha256 = "0jm1wba4nj4s0ra2i8n4x8b5dxxwmfq49wv1nmz9q43mqsjbjmcs";
  finalImageName = "centos";
  finalImageTag = "7";

I then copy the info into my flake which looks like this:

  description = "A test docker image flake";
  outputs = { self, nixpkgs }:
    pkgs = nixpkgs.legacyPackages.x86_64-linux;
    lib = nixpkgs.lib;
    centos_7 = pkgs.dockerTools.pullImage {
      imageName = "centos";
      imageDigest = "sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4";
      sha256 = "0jm1wba4nj4s0ra2i8n4x8b5dxxwmfq49wv1nmz9q43mqsjbjmcs";
    docker_image = pkgs.dockerTools.buildImage {
      name = "hello";
      tag = "latest";
      fromImage = centos_7;
      config = {
        Cmd = [ "${pkgs.hello}/bin/hello" ];
      packages.x86_64-linux.hello = docker_image;
      packages.x86_64-linux.default = self.packages.x86_64-linux.hello;

Trying to build:

nix build
error: hash mismatch in fixed-output derivation '/nix/store/8qml7if3ca4j29hcflv0fxcvwzmdwll5-docker-image-centos-latest.tar.drv':
         specified: sha256-mlW5pMZ1EJx+tWHzRLCrvPdWFurEoihUBppIS9TioUo=
            got:    sha256-rEY+X6CA5Pklq5VK1uM0eYWcwUJyyCfDeb3/kvIz9LQ=
error: 1 dependencies of derivation '/nix/store/kdql1s8gkli4zqgz38yrciab3y20wabm-docker-image-hello.tar.gz.drv' failed to build

One thing I’ve noticed is that it seems to break when using a non “latest” tag.
So for example if I repeat the process with out using the --image-tag argument to nix-prefetch-docker, then it seems to build correctly.
I’ve tested CentOs and Debian with the latest tag and they both work fine.

Am I doing something wrong?
Or is this possibly a bug somewhere?

Thanks in advance.

I think both of these things are bugs. The manual is indeed wrong, you need the -- after the package uri to make nix not interpret those as args to itself. Your quoting is unnecessary, though not harmful.

The latter also screams bug to me, the output should not be an incorrect hash, and it seems unlikely that you’d get such specific failures twice. Even if this was intended behavior somehow, it’s a UX bug.

As a workaround, you could just change the hash to what nix tells you it is.

1 Like

Okay, thanks.

The workaround works. I didn’t quite expect it because the hash I specified didn’t look like the one it said I specified.
Is that just a different format for the same hash?

As for the quoting, I use zsh so I think the # has some special meaning there.
I get something like: zsh: no matches found: nixpkgs#nix-prefetch-docker if I don’t quote it.
Should I report the doc bug somewhere?