In this post, we go through the basic steps for containerizing a unikernel application and running it on nabla runnc. Checkout nabla containers and in particular runnc.

How to Link to heading

In order to build a docker image for nabla containers, we have to build:

  • the nabla toolstack
  • the unikernel image
  • the docker image

Build the nabla toolstack Link to heading

There’s an informative blog post on how to build the nabla rumprun toolstack here. Now that our aarch64 changes are upstream, the process should be as easy as the following:

1git clone
2cd rumprun
3git submodule update --init
5. obj/

and you should end up with the toolstack (${ARCH}-rumprun-netbsd-) in your PATH variable.

Alternatively you can use one of the (unofficial) docker images with the toolstack embedded at /usr/local:

You can run these containers using the following command:

1docker run --runtime=runc --rm -v ${PWD}:/build -it cloudkernels/debian-rumprun-build:${ARCH} /bin/bash

where ${ARCH} could be x86_64 or aarch64.

Build the unikernel Image Link to heading

building the image is as easy as running the following:

1${ARCH}-rumprun-netbsd-gcc myprog.c -o myprog-rumprun
1rumprun-bake solo5-spt myprog.spt myprog-rumprun

So we have ourselves an .spt file (a unikernel). To try it out, assuming you have a solo5-spt binary lying around you can do the following:

1solo5-spt ./myprog.spt

Asumming the unikernel image is successful, its time to construct the docker image.

Build the docker image Link to heading

Rumprun is a quirky unikernel framework, with a number of assumptions we can’t ignore. Thus, in order to get the unikernel running correctly when in a nabla container environmnent, we need to be careful and include the correct stubs for a dummy root filesystem. So, clone this repo, which contains the basic rootfs from rumprun’s lib/librumprunfs_base/rootfs, and a template Dockerfile shown below:

1FROM scratch
2COPY myprog.spt /myprog.nabla
3COPY rootfs/etc /etc
4ENTRYPOINT [ "myprog.nabla" ]

Copy the spt file in this directory and run:

1docker build -f Dockerfile -t myprog-nabla:${ARCH} .

You should end up with a local docker image named myprog-nabla, tagged with your current architecture variant (x86_64 or aarch64).

Assuming you have setup runnc correctly, spawning the container is as easy as:

1docker run --rm --runtime=runnc myprog-nabla:${ARCH}