Getting Started


Platform Model

Jerboa currently runs in three ways:

Notes:

Prerequisites

Linux

Required for native execution:

Optional:

Windows

Required:

The actual daemon and hypervisors run inside the imported jerboa WSL2 distro. Firecracker still requires KVM.

macOS

Required:

Optional:


Install

macOS Apple Silicon

On macOS 26+, download the release’s Jerboa Desktop DMG (https://releases.jerboa.dev/desktop/vVERSION/jerboa-desktop-VERSION-macos-arm64.dmg), move the app to Applications and open it. It bundles the CLI, the daemon and the Firecracker runtime, starts the daemon and offers to add jerboa to /usr/local/bin.

The DMG is not signed or notarized by Apple yet, so macOS blocks the first launch: allow it in System Settings → Privacy & Security → Open Anyway.

install.sh does not support macOS yet. For step-by-step instructions and the differences from Linux, see Using Jerboa on macOS. To build from source, see Firecracker on macOS.

Linux

For a native Linux host, the repo ships a one-shot installer:

sudo scripts/install.sh
jerboa status

That path provisions the Linux-side runtime, including the daemon service.

If you are building from source instead:

git clone https://github.com/AitorConS/jerboa.git
cd jerboa
make build

Artifacts are written to dist/. make build builds both binaries; use make build-cli or make build-daemon for one side, or make -j2 build to build both in parallel. Source builds use -trimpath; distro/build.sh also builds jerboad with -s -w, making the WSL rootfs artifact about 9 MiB smaller.

Windows

On Windows the jerboa CLI ships with the Jerboa Desktop app, whose installer puts jerboa on your PATH. Install the app, then import the dedicated WSL2 distro that hosts the daemon:

jerboa daemon install
jerboa daemon start
jerboa daemon status

The desktop app can also manage this runtime for you from its GUI. jerboa daemon install --rootfs <tarball> imports a locally built distro rootfs instead of downloading the release artifact from the signed manifest.


First Start

Linux daemon

Typical native daemon start:

sudo jerboad --host unix:///var/run/jerboad.sock

Useful daemon flags:

sudo jerboad \
  --host unix:///var/run/jerboad.sock \
  --metrics-addr :9090 \
  --ui-addr :8080 \
  --vm-store sqlite

Windows daemon

The daemon lives inside WSL2 and is usually started through the CLI:

jerboa daemon start
jerboa daemon logs -f

The Windows client auto-starts the daemon for daemon-backed commands when needed.

macOS daemon

The Jerboa Desktop app starts the daemon when it opens. From the terminal:

jerboa daemon start
jerboa daemon status

The daemon runs as your user (no sudo) while you are logged in and logs to ~/.jerboa/jerboad.log. It does not start automatically at login yet.


Build An Image

jerboa build requires a reachable daemon. If unikernels are new to you, read Build Concepts first — it explains the one-process model, packages, and everything unikernel.toml can do.

Scaffold a project

jerboa init

jerboa init detects the project language and writes a fully commented unikernel.toml documenting every field and its pitfalls. Use --lang raw for package-driven builds (databases, prebuilt binaries).

From a Go project

jerboa build examples/hello --name hello --lang go

Go source builds use size-oriented defaults (-trimpath and stripped linker flags) unless later custom build args override them.

From a source directory with auto-detection

jerboa build examples/flaskapp --name flaskapp --port 8080
jerboa build examples/nextapp --name nextapp --port 3000

Supported build modes:

Runtime packages (the Node/Python runtimes, database servers, shared libraries) come from the ops ecosystem by default (--pkg-source ops); unikernel.toml can override build/run defaults, declare packages (pkgs = [...]), and run pre-build steps.

Before assembling the image, the build runs preflight checks (is the program a bootable Linux ELF? are all its shared libraries in the image?) and aborts with an explanation and a fix hint when something would fail at boot. Add --smoke to also boot the image once right after building and scan its output for known failure signatures:

jerboa build examples/flaskapp --name flaskapp --port 8080 --smoke

From a prebuilt static ELF

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o hello ./examples/hello
jerboa build ./hello --name hello

If a build or a boot fails, check Troubleshooting — it decodes every common error message.


Run A VM

jerboa run hello:latest
jerboa ps
jerboa logs <vm-id>

Attach to serial output:

jerboa run hello:latest --attach

Follow buffered logs:

jerboa logs <vm-id> -f

Networking And Ports

Port publishing is tied to managed networking. There is no SLIRP fallback.

jerboa network create app
jerboa run myapp:latest --network app -p 8080:80 --name web
jerboa dns list --network app

Joining a network assigns the VM a guest IP automatically: the daemon’s IPAM hands out the next free address from the network’s subnet. Pass --ip only when you need a fixed address:

jerboa run myapp:latest --network app --ip 10.100.0.10 -p 8080:80

Important (Linux and Windows):

macOS: -p works without --network, and both TCP and UDP ports are forwarded. Firecracker VMs cannot reach the internet unless you allow it. See Networking on macOS.

Publish bind address

By default a published port listens on all interfaces (0.0.0.0), so it is reachable from the LAN. To restrict a port to the local host, prefix the mapping with a bind address, Docker-style:

jerboa run myapp:latest --network app -p 127.0.0.1:8080:80   # localhost only
jerboa run myapp:latest --network app -p 8080:80             # all interfaces

Windows / WSL2: the daemon and the published port live inside the dedicated jerboa WSL2 distro. With WSL2’s default NAT networking the port is not reachable at localhost:<port> on the Windows host — reach it at the distro IP instead (the host shown by jerboa daemon status, e.g. http://172.25.x.x:8080). To make localhost work like Docker Desktop, enable mirrored networking by adding the following to %USERPROFILE%\.wslconfig and running wsl --shutdown:

[wsl2]
networkingMode=mirrored

Service Discovery (Guest DNS)

VMs on the same network resolve each other by name. The daemon runs a small DNS server that answers from live VM state, so an app can connect to a peer by its VM/service name instead of a hardcoded IP:

jerboa network create app
jerboa run mysql:latest   --network app --name db -p 3306:3306
jerboa run myapp:latest   --network app --name web -p 8080:8080 -e DB_HOST=db
# inside `web`, the hostname `db` resolves to the db VM's IP

How it works:

Inspect the records the resolver would return:

jerboa dns list --network app
jerboa dns resolve db --network app

Volumes

jerboa volume create data --size 1G
jerboa run myapp:latest -v data:/var/data
jerboa volume inspect data

A fresh volume is empty — mounting it over a path that has baked data (e.g. a pre-initialized database) shadows that data. Create and seed in one step:

jerboa volume create pgdata --size 1G --seed-pkg eyberg/postgresql:11.3.0 --src /db
jerboa run postgresql -v pgdata:/db --network pgnet -p 5432:5432

See Build Concepts → Volumes And Seeding for why seeding is needed.


Compose

Compose stack:

jerboa compose up stack.yaml
jerboa compose ps stack.yaml
jerboa compose logs stack.yaml api
jerboa compose down stack.yaml --volumes

Updating

Update CLI and daemon together for 0.51.2: this release uses wire protocol 2. Before upgrading existing Compose stacks, follow the stack migration instructions.

The CLI has no self-update command. How you update depends on the platform:

Check what you have against the latest published release with jerboa version:

jerboa version          # installed CLI/kernel vs latest of every component
jerboa kernel check     # is a newer kernel available?
jerboa kernel update    # install the latest kernel toolchain

Next