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: skopeo-push-maybe · GitHub
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
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.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.
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}"