Push docker tgz images to registry directly

Anyone who has used the dockerImage.buildImage derivation has this same problem: how do I push these images to the registry?

Before:

docker load -i $(nix-build -A my-image --no-out-link)
# somehow know the docker image name
docker tag $oldname $remotetag
docker push $remotetag

This has multiple problems: it takes time to load and unpack the image in docker, it means that docker needs to be running, and it also means that now there is a need for a garbage-collection mechanism for the loaded images.

Thanks to @lewo for showing me the light, there is a new tool called skopeo that solves all of this (since version 0.1.19):

skopeo copy docker-image://$(nix-build -A my-image --no-out-link) docker://$remotetag

As a bonus, here is a wrapper script that makes the upload a noop if the tag already exists: https://gist.github.com/c106f1007843889d92d6bb115d43b479

4 Likes

Nice. I don’t suppose you have a nifty solution for taking a docker-compose.yml file and turning that into nixos containers?

I suppose it would involve generating a NixOS configuration and then running nixos-rebuild switch. Generally I try to keep projects self-contained and avoid requiring system configuration changes. Unless it involves installing Nix obviously :slight_smile:

How to do the same with buildah (and a .nix file)?

Nix outputs a docker image so buildah would be redundant in that context.

But how to do it (.nix file to image build) with buildah [instead of docker] - so that docker is not needed anymore

Docker is already not needed. If you use pkgs.dockerImage.buildImage from nixpkgs it’s possible to build a docker image using just Nix. It outputs an image tarball that can be pushed to the registry with skopeo. I assume that podman could also be used to run the image instead of docker.

You can try it by writing this file to hello-docker.nix, and then run nix-build hello-docker.nix.

{ pkgs ? import <nixpkgs> {} }:
pkgs.dockerTools.buildImage {
  name = "hello";
  config.Cmd = [ "${pkgs.hello}/bin/hello" ];
}

dockerImage needs docker as a dependency, right?


My question is to build (from a .nix file) without docker [daemon] -> e.g. to build with buildah

I can see where the confusion is coming from.

pkgs.dockerTools.buildImage uses its own build process and doesn’t depend on the Docker daemon at all. The only docker-related thing is that it outputs docker-compatible images.

2 Likes

I just want to add that in latest versions of skopeo the command should be something like:

# ${oci} is what nix build returns
# ${tag} is any docker registry tag like "redis:latest"
skopeo \
  --insecure-policy \
  copy \
  --dest-creds "${user}:${password}" \
  "docker-archive://${oci}" \
  "docker://${tag}"
3 Likes

Worth checking out:

It abstracts pushing to Docker Hub, Github Registry and Gitlab Registry

2 Likes