run containers without pulling images

CRFS is a Google project that aims at running a container without pre-pulling the image first.

The idea is quite smart: an OCI layer (that is basically a compressed tarball), is modified in a way that it is possible to seek content inside of it and access a single file. It is designed around the stargz (Seekable tar.gz) format. Instead of having a single compressed tar stream, the stargz modifies it to concatenate the gzipped stream of each file. Old clients are still able to handle the stargz’ipped stream as a regular .tar.gz file.

In an attempt to support CRFS with fuse-overlayfs, I’ve worked on adding a plugin system to fuse-overlayfs ( It will make possible to extend it and support different ways to retrieve data from the lower layers.

The second step is a plugin that can handle CRFS, it is still a PoC but seems to work quite nicely:

To create a stargz image, you’d need to use stargzify

# go get -u

Once stargzify is installed, an image can be converted as:

# stargzify
2019/10/24 20:33:33 pushed blob: sha256:c7155ae298b145d79e75c396ab5cb917023c4fd8b9cf8c7ff2f0332b41ef8651
2019/10/24 20:33:34 pushed blob: sha256:5a419d36bce538fa32fc21cbe11134ccbd70597379d9320f3a32eb6be78e4ad5
2019/10/24 20:33:35 digest: sha256:ca6723c15c5b3b0947deef12048ee64126ed237e112cfbde300ce0f4066a4b4d size: 428

The image was pushed to the registry. Let’s create a container:

# mkdir lower upper workdir merged
# export DATA=$(echo -n docker:// | base64 -w0)
# OPTS=fast_ino=1,plugins=/path/to/,lowerdir=//crfs/$DATA/lower,upperdir=upper,workdir=work
# fuse-overlayfs -o $OPTS merged

The image, passed to fuse-overlayfs encoded in base 64, is mounted at the merged directory.

# ls merged/
bin   dev  home   lib    lost+found  mnt  proc  run   srv   sys  usr
boot  etc  hosts  lib64  media       opt  root  sbin  tmp  var

To run the container, we can take advantage of the Podman –rootfs feature. It tells Podman to not manage the storage for the container, but to use the specified path as its rootfs.

# podman run --rm -ti --rootfs merged /bin/sh

Now we are in a container where files from the lower layers will be loaded on demand when requested.