Hocker, I can't believe it's not docker!
hocker
is a suite of utilities
that:
- fetch the registry manifest for a docker image
- fetch the configuration of a docker image
- fetch any layer of a docker image
- fetch and assemble a whole docker image
- generate Nix build instructions from a registry manifest for a docker image (we won’t cover this utility in this post)
hocker
utilities support two modes of authentication with privately hosted
docker registries and “transparent” public-token authentication for the public
docker hub registry.
hocker
does not replace docker
; however, it does decouple fetching docker
images from running docker containers.
Why did you build this?
There are two motivating reasons:
- we want to assemble a docker image from our registry without requiring the docker daemon
- we want to fetch individual layers of a docker image from our registry for a
granular — and efficient — deployment of a docker image to environments where
we cannot use
docker pull
Integrating docker containers into a NixOS system (without
using docker pull
) stimulated these two requirements. Note that Nix and NixOS
are not required to use these utilities.
Fetch a docker image without using docker pull
Let’s dive right in and fetch the hello-world
docker image from
hub.docker.com
(note that the repository name for official images on the
public docker hub is “library
”):
$ hocker-image \
--out ./hello-world.tar.gz \
library/hello-world linux
Downloading layer: ca4f61b => decompressed => wrote f999ae2
./hello-world.tar.gz
The result is a complete docker image:
$ tar --list --file ./hello-world.tar.gz
manifest.json
f2a91732366c0332ccd7afd2a5c4ff2b9af81f549370f7a19acd460f87686bc7.json
f999ae22f308fea973e5a25b57699b5daf6b0f1150ac2a5c2ea9d7fecee50fdf.tar
repositories
… which we load into docker using docker load
:
$ docker load < hello-world.tar.gz
...
Loaded image: registry-1.docker.io/v2/library/hello-world:linux
… and then run:
$ docker run --rm \
registry-1.docker.io/v2/library/hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
Fetch the registry manifest and a layer, of a docker image
If we want to fetch the individual layers of a docker image then we need to
retrieve the manifest of binary blobs on the registry for the image; we can do
this using hocker-manifest
:
$ hocker-manifest library/hello-world linux | jq
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1510,
"digest": "sha256:f2a91732366c0332ccd7afd2a5c4ff2b9af81f549370f7a19acd460f87686bc7"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 985,
"digest": "sha256:ca4f61b1923c10e9eb81228bd46bee1dfba02b9c7dac1844527a734752688ede"
}
]
}
… the manifest says there is one layer we can fetch; the layer is keyed by its
digest with the sha256:
part stripped off:
$ hocker-layer \
--out ./hello-world-layer-ca4f61b.tar.gz \
--layer ca4f61b1923c10e9eb81228bd46bee1dfba02b9c7dac1844527a734752688ede \
library/hello-world linux
Downloading layer: ca4f61b => wrote ca4f61b
./hello-world-layer-ca4f61b.tar.gz
… the layer contains a hello
program:
$ tar --list --file ./hello-world-layer-ca4f61b.tar.gz
hello
… which is also the CMD
entrypoint of the container as indicated by the
image’s configuration JSON:
$ hocker-config library/hello-world linux | jq
{
...
"config": {
...
"Cmd": [
"/hello"
],
...
},
...
}
Conclusion
We’ve pulled a docker image from a registry without using the docker client or
going through the docker daemon. We also fetched three other artifacts of the
hello-world
docker image that the stock docker tooling elides from you:
- the registry’s manifest of the artifacts that compose the image
- an individual layer of the image; and,
- the image configuration — as JSON
In a follow-on blogpost, I will show how we use the hocker
utilities with
Nix and NixOS.
You can find hocker
on GitHub and Hackage.
Notes
Thanks to Gabriel Gonzalez (@GabrielG439) for reading drafts and providing feedback.