Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions docs/examples.md
Original file line number Diff line number Diff line change
@@ -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 `<uk/assert.h>` 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.
26 changes: 26 additions & 0 deletions examples/httpreply/Dockerfile
Original file line number Diff line number Diff line change
@@ -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"
36 changes: 36 additions & 0 deletions examples/httpreply/README.md
Original file line number Diff line number Diff line change
@@ -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
```
27 changes: 27 additions & 0 deletions examples/nginx/Dockerfile
Original file line number Diff line number Diff line change
@@ -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"
38 changes: 38 additions & 0 deletions examples/nginx/README.md
Original file line number Diff line number Diff line change
@@ -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
```
31 changes: 31 additions & 0 deletions examples/redis/Dockerfile
Original file line number Diff line number Diff line change
@@ -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 <uk/assert.h>' .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"
39 changes: 39 additions & 0 deletions examples/redis/README.md
Original file line number Diff line number Diff line change
@@ -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
```
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down