How to Install Mirage on Debian 11 Bullseye
If you’re looking to run a MirageOS unikernel on your Debian machine, this guide will get you there in less than an hour – no fancy cloud setup required.
What You’ll Need
- A Debian 11 (Bullseye) system with internet access
- Root or `sudo` privileges
- Some patience for the inevitable “OCaml version mismatch” moments
Step 1: Update Packages and Install Essentials
sudo apt update && sudo apt upgrade -y
sudo apt install -y git build-essential ocaml opam libev-dev \
pkg-config ca-certificates
Why this matters: `build-essential` pulls the compiler toolchain, while `libev-dev` gives you the event‑loop library Mirage needs. Skipping any of these and you’ll hit a cryptic “missing dependency” error later.
Step 2: Bootstrap OPAM
opam init -y --disable-sandboxing
I’ve seen this fail on older Debian releases because `opam` expects `/usr/local` to be writable. If that happens, just add the `--disable-sandboxing` flag.
Step 3: Configure OPAM for a Stable OCaml
eval $(opam env) opam switch create mirage ocaml-base-compiler.4.14.0 --quiet
Mirage ships with tests that only compile on OCaml 4.13+. Using a newer compiler can break the build, so pin it to 4.14.0.
Step 4: Install MirageOS and Its Toolchain
opam install mirage dune-compiler
The `dune` build system is what turns your `.ml` files into a unikernel image. Don’t skip this – without Dune, the rest of the steps are pointless.
Step 5: Clone Your Mirage Project
git clone https://github.com/mirage/mirage-demo.git cd mirage-demo
I usually start from the official demo because it has a working `dune` file and a simple network stack. If you’re building your own, just make sure to add a `mirage` stanza in your `dune-project`.
Step 6: Build the Unikernel
make
Behind the scenes, `make` runs Dune to compile the OCaml code and then links it with Mirage’s runtime. If you get “No such file or directory” errors pointing at `_build/default`, delete that folder and try again.
Step 7: Run It With QEMU
qemu-system-x86_64 -nographic \ -m 512 -cpu host \ -device e1000,netdev=net0 \ -netdev user,id=net0,hostfwd=tcp::2222-:22 \ -kernel _build/default/mirage-demo.native
Mirage is a unikernel – it’s just a binary that runs directly on the hypervisor. QEMU gives you an isolated VM without touching your host kernel.
Step 8: Test SSH Into Your Unikernel
ssh -p 2222 root@localhost
You should see a prompt that says “Welcome to Mirage!” If it asks for a password, use `root` with no password – Mirage ships that way by default. Feel free to tweak the network config in `dune` if you want more advanced setups.
Common Pitfalls
- “Could not find libmirage”: Make sure you ran `opam install mirage`.
- Permission denied on `/usr/local/bin`: OPAM tries to write there; add `--disable-sandboxing` during init.
- QEMU hangs: Check that your CPU supports virtualization (`-cpu host`). On older CPUs, drop the flag.
That’s it – you now have a running MirageOS unikernel on Debian 11. Play around with the source files to see how tiny a kernel can be, and enjoy the delight of a minimal OS that just does what you tell it to do.