From 40e706c9feee9454020895657298038d34fa5131 Mon Sep 17 00:00:00 2001 From: Nachiket Roy Date: Sun, 14 Jun 2026 12:46:23 +0300 Subject: [PATCH] documentation and building steps for unikernel examples Signed-off-by: Nachiket Roy --- docs/examples.md | 38 ++++++++++++++++++++++++++++++++++ examples/httpreply/Dockerfile | 26 +++++++++++++++++++++++ examples/httpreply/README.md | 36 ++++++++++++++++++++++++++++++++ examples/nginx/Dockerfile | 27 ++++++++++++++++++++++++ examples/nginx/README.md | 38 ++++++++++++++++++++++++++++++++++ examples/redis/Dockerfile | 31 ++++++++++++++++++++++++++++ examples/redis/README.md | 39 +++++++++++++++++++++++++++++++++++ mkdocs.yml | 1 + 8 files changed, 236 insertions(+) create mode 100644 docs/examples.md create mode 100644 examples/httpreply/Dockerfile create mode 100644 examples/httpreply/README.md create mode 100644 examples/nginx/Dockerfile create mode 100644 examples/nginx/README.md create mode 100644 examples/redis/Dockerfile create mode 100644 examples/redis/README.md diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 00000000..d04d272f --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,38 @@ +# urunc Examples + +This section provides complete, reproducible examples of popular applications built as Unikernels and packaged for `urunc`. + +All examples primarily use **Unikraft** as the underlying unikernel framework, as it provides a consistent, robust building experience across different applications. + +You can find the source code, `Dockerfiles`, and specific documentation for each example in the [`examples/`](https://github.com/urunc-dev/urunc/tree/main/examples) directory of the repository. + +## Available Examples + +| Application | Description | Link | +|-------------|-------------|------| +| **Nginx** | A high-performance web server built as a Unikraft unikernel. | [examples/nginx/](../examples/nginx) | +| **Redis** | An in-memory data structure store, used as a database and cache. | [examples/redis/](../examples/redis) | +| **Httpreply** | A minimal, fast HTTP server commonly used for benchmarking and testing. | [examples/httpreply/](../examples/httpreply) | + +## Building the Examples + +Each example directory contains a multi-stage `Dockerfile`. These files: +1. Use Unikraft's build tools (like `kraftkit`) to compile the application from source specifically for the `qemu` and `x86_64` targets. +2. Package the resulting unikernel binary (and any necessary files like configuration files or rootfs) into a lightweight OCI image using the `bunny` packaging format. + +You can build any example directly using a container builder like `nerdctl` or `docker`: + +```bash +cd examples/nginx +docker build -t urunc-nginx-example . +``` + +And then run it over `urunc`: + +```bash +docker run -d --runtime io.containerd.urunc.v2 urunc-nginx-example +``` + +> **Note**: For specific build options, initialization commands, and verification steps, refer to the `README.md` inside each respective example's directory. + +> **Optional workaround note for Redis**: The Unikraft `stable` branch occasionally experiences upstream bugs (such as a recent missing `` header in `libukpod`). To ensure a seamless experience, the `examples/redis/Dockerfile` implements a smart conditional build: if the standard compilation fails due to this known issue, it automatically injects the missing header and resumes the build. Once Unikraft patches the `stable` channel, the fallback will simply be ignored. diff --git a/examples/httpreply/Dockerfile b/examples/httpreply/Dockerfile new file mode 100644 index 00000000..81d0a2f6 --- /dev/null +++ b/examples/httpreply/Dockerfile @@ -0,0 +1,26 @@ +# Stage 1: Build the Unikernel using kraft +FROM ubuntu:22.04 AS builder + +RUN apt-get update && apt-get install -y \ + curl build-essential git flex bison \ + libncurses-dev wget unzip python3 \ + && rm -rf /var/lib/apt/lists/* + +RUN curl --proto '=https' --tlsv1.2 -sSf https://get.kraftkit.sh | sh -s -- -y + +# Clone the Unikraft httpreply app +RUN git clone https://github.com/unikraft/app-httpreply /src +WORKDIR /src + +# Build the Unikernel +RUN kraft build -p qemu -m x86_64 + +# Stage 2: Package into a standard OCI image for urunc +FROM scratch + +COPY --from=builder /src/.unikraft/build/httpreply_qemu-x86_64 /unikernel/kernel + +LABEL "com.urunc.unikernel.binary"="/unikernel/kernel" +LABEL "com.urunc.unikernel.cmdline"="" +LABEL "com.urunc.unikernel.unikernelType"="unikraft" +LABEL "com.urunc.unikernel.hypervisor"="qemu" diff --git a/examples/httpreply/README.md b/examples/httpreply/README.md new file mode 100644 index 00000000..da410645 --- /dev/null +++ b/examples/httpreply/README.md @@ -0,0 +1,36 @@ +# Unikraft HTTPReply Example for urunc + +This example builds a lightweight, minimal HTTP reply server as a Unikernel and packages it for deployment over `urunc`. + +## Prerequisites +- `docker` (or `nerdctl`) +- `urunc` configured in your container engine + +## Building + +The provided multi-stage `Dockerfile` will automatically fetch KraftKit, compile the Unikraft kernel from source, and output a minimal `scratch` image containing the compiled binary and the necessary `urunc` labels. + +```bash +docker build -t urunc-httpreply-example . +``` + +## Running + +Run the built image using the `urunc` runtime. + +```bash +docker run -d --rm \ + --runtime io.containerd.urunc.v2 \ + -p 8080:8080 \ + urunc-httpreply-example +``` + +> **Note**: If you are using `nerdctl`, remember to include the `--snapshotter overlayfs` flag. + +## Verification + +You can verify the unikernel is successfully serving requests by sending a `curl` to the exposed port: + +```bash +curl http://localhost:8080 +``` diff --git a/examples/nginx/Dockerfile b/examples/nginx/Dockerfile new file mode 100644 index 00000000..a9f17837 --- /dev/null +++ b/examples/nginx/Dockerfile @@ -0,0 +1,27 @@ +# Stage 1: Build the Unikernel using kraft +FROM ubuntu:22.04 AS builder + +RUN apt-get update && apt-get install -y \ + curl build-essential git flex bison \ + libncurses-dev wget unzip python3 \ + && rm -rf /var/lib/apt/lists/* + +RUN curl --proto '=https' --tlsv1.2 -sSf https://get.kraftkit.sh | sh -s -- -y + +# Clone the Unikraft Nginx app +RUN git clone https://github.com/unikraft/app-nginx /src +WORKDIR /src + +# Build the Unikernel specifying the initrd target +RUN kraft build --target nginx-qemu-x86_64-initrd + +# Stage 2: Package into a standard OCI image for urunc +FROM scratch + +# Copy the unikernel binary (which automatically embeds the rootfs) +COPY --from=builder /src/.unikraft/build/nginx-qemu-x86_64-initrd_qemu-x86_64 /unikernel/kernel + +LABEL "com.urunc.unikernel.binary"="/unikernel/kernel" +LABEL "com.urunc.unikernel.cmdline"="nginx -c /nginx/conf/nginx.conf" +LABEL "com.urunc.unikernel.unikernelType"="unikraft" +LABEL "com.urunc.unikernel.hypervisor"="qemu" diff --git a/examples/nginx/README.md b/examples/nginx/README.md new file mode 100644 index 00000000..86974dee --- /dev/null +++ b/examples/nginx/README.md @@ -0,0 +1,38 @@ +# Unikraft Nginx Example for urunc + +This example builds Nginx as a Unikernel and packages it for deployment over `urunc`. Nginx is a powerful, high-performance web server, reverse proxy, and load balancer. + +Because Nginx requires configuration files and standard library capabilities, this build specifically uses Unikraft's `initrd` target to compile a root filesystem containing the `nginx.conf` and packages it alongside the unikernel binary. + +## Prerequisites +- `docker` (or `nerdctl`) +- `urunc` configured in your container engine + +## Building + +The provided multi-stage `Dockerfile` will automatically fetch KraftKit, clone the official Unikraft Nginx app, compile the Unikraft kernel and `initramfs` from source, and output a minimal `scratch` image containing the compiled binary, rootfs, and necessary `urunc` labels. + +```bash +docker build -t urunc-nginx-example . +``` + +## Running + +Run the built image using the `urunc` runtime. + +```bash +docker run -d --rm \ + --runtime io.containerd.urunc.v2 \ + -p 8080:80 \ + urunc-nginx-example +``` + +> **Note**: If you are using `nerdctl`, remember to include the `--snapshotter overlayfs` flag. + +## Verification + +You can verify the unikernel is successfully serving requests by sending a `curl` to the exposed port: + +```bash +curl http://localhost:8080 +``` diff --git a/examples/redis/Dockerfile b/examples/redis/Dockerfile new file mode 100644 index 00000000..0f069b03 --- /dev/null +++ b/examples/redis/Dockerfile @@ -0,0 +1,31 @@ +# Stage 1: Build the Unikernel using kraft +FROM ubuntu:22.04 AS builder + +RUN apt-get update && apt-get install -y \ + curl build-essential git flex bison \ + libncurses-dev wget unzip python3 \ + && rm -rf /var/lib/apt/lists/* + +RUN curl --proto '=https' --tlsv1.2 -sSf https://get.kraftkit.sh | sh -s -- -y + +# Clone the Unikraft Redis app +RUN git clone https://github.com/unikraft/app-redis /src +WORKDIR /src + +# Build the initrd target which compiles Redis and creates the rootfs. +# Note: If the build fails due to a known upstream missing header in Unikraft stable, +# we apply a surgical patch and retry the build. +RUN kraft build --no-prompt --target redis-qemu-x86_64-initrd || \ + (sed -i '10i#include ' .unikraft/unikraft/lib/ukpod/anon.c && \ + kraft build --no-prompt --target redis-qemu-x86_64-initrd) + +# Stage 2: Package into a standard OCI image for urunc +FROM scratch + +# Copy the unikernel binary (which automatically embeds the rootfs) +COPY --from=builder /src/.unikraft/build/redis-qemu-x86_64-initrd_qemu-x86_64 /unikernel/kernel + +LABEL "com.urunc.unikernel.binary"="/unikernel/kernel" +LABEL "com.urunc.unikernel.cmdline"="redis-server /redis.conf" +LABEL "com.urunc.unikernel.unikernelType"="unikraft" +LABEL "com.urunc.unikernel.hypervisor"="qemu" diff --git a/examples/redis/README.md b/examples/redis/README.md new file mode 100644 index 00000000..7fac9840 --- /dev/null +++ b/examples/redis/README.md @@ -0,0 +1,39 @@ +# Unikraft Redis Example for urunc + +This example builds Redis as a Unikernel and packages it for deployment over `urunc`. Redis is an in-memory data structure store, used as a distributed, in-memory key-value database, cache and message broker. + +Because Redis requires configuration files and a standard filesystem to operate effectively, this build specifically uses Unikraft's `initrd` target to compile a root filesystem containing the `redis.conf` and packages it alongside the unikernel binary. + +## Prerequisites +- `docker` (or `nerdctl`) +- `urunc` configured in your container engine + +## Building + +The provided multi-stage `Dockerfile` will automatically fetch KraftKit, clone the official Unikraft Redis app, compile the Unikraft kernel and `initramfs` from source, and output a minimal `scratch` image containing the compiled binary, rootfs, and necessary `urunc` labels. + +```bash +docker build -t urunc-redis-example . +``` + +## Running + +Run the built image using the `urunc` runtime. + +```bash +docker run -d --rm \ + --runtime io.containerd.urunc.v2 \ + -p 6379:6379 \ + urunc-redis-example +``` + +> **Note**: If you are using `nerdctl`, remember to include the `--snapshotter overlayfs` flag. + +## Verification + +You can verify the unikernel is successfully serving requests by using the `redis-cli`: + +```bash +redis-cli ping +# Expected output: PONG +``` diff --git a/mkdocs.yml b/mkdocs.yml index f360ef1d..3a0ad799 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -37,6 +37,7 @@ nav: - API Reference: https://pkg.go.dev/github.com/urunc-dev/urunc/pkg/unikontainers - Tutorials: - tutorials/*.md + - Examples: examples.md theme: name: material