From mirageos-devel-bounces@lists.xenproject.org Tue Oct 20 15:38:35 2026
Return-path: <mirageos-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Tue, 20 Oct 2026 15:38:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1456028.1669626 (Exim 4.92)
	(envelope-from <mirageos-devel-bounces@lists.xenproject.org>)
	id 1xJBuz-0002Qk-7w; Tue, 20 Oct 2026 15:38:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1456028.1669626; Tue, 20 Oct 2026 15:38:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <mirageos-devel-bounces@lists.xenproject.org>)
	id 1xJBuz-0002Qd-4V; Tue, 20 Oct 2026 15:38:25 +0000
Received: by outflank-mailman (input) for mailman id 1456028;
 Tue, 20 Oct 2026 15:38:24 +0000
Received: from mx.expurgate.net ([195.190.135.20])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <romain.calascibetta@gmail.com>) id 1xJBux-0002QX-Nd
 for mirageos-devel@lists.xenproject.org; Tue, 20 Oct 2026 15:38:24 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xJBuw-007Fj8-TB
 for mirageos-devel@lists.xenproject.org; Tue, 20 Oct 2026 17:38:22 +0200
Received: from [10.42.69.6] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1)
 (envelope-from <romain.calascibetta@gmail.com>)
 id 6ad78ad3-e002-0a2a0a5209dd-0a2a450689bc-42
 for <mirageos-devel@lists.xenproject.org>; Tue, 20 Oct 2026 17:38:22 +0200
Received: from [209.85.128.175] (helo=mail-yw1-f175.google.com)
 by tlsNG-16d1c6.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from <romain.calascibetta@gmail.com>)
 id 6ad78aed-195a-0a2a45060019-d15580afb098-3
 for <mirageos-devel@lists.xenproject.org>; Tue, 20 Oct 2026 17:38:22 +0200
Received: by mail-yw1-f175.google.com with SMTP id
 00721157ae682-8b0ca1ebc8bso26785167b3.2
 for <mirageos-devel@lists.xenproject.org>;
 Tue, 20 Oct 2026 08:38:22 -0700 (PDT)
X-BeenThere: mirageos-devel@lists.xenproject.org
List-Id: Developer list for MirageOS <mirageos-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/mirageos-devel>, 
 <mailto:mirageos-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:mirageos-devel@lists.xenproject.org>
List-Help: <mailto:mirageos-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/mirageos-devel>, 
 <mailto:mirageos-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: mirageos-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "MirageOS-devel" <mirageos-devel-bounces@lists.xenproject.org>
Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Type:To:Subject:Message-ID:Date:From:MIME-Version"
ARC-Seal: i=1; a=rsa-sha256; t=1792510701; cv=none;
        d=google.com; s=arc-20260327;
        b=j4NfU2M2oUqjO15voMz94vfmHPZIZNALypRzwkGelyWTzPRbiD40QrrW6WDXR5SCkN
         P2+Dbqblzwsn1nGharPKOUu/ElpHKg6nM2CSLr+PtXrkYn5mJ+Odsd32y9qObrNOdHVA
         NnvuOW8Po6XIFy04HKj4fHQD9K4NERnojJXIWOx4mD1AXelsI9E0OR9Gg8g0tjXhkBxl
         e/snlSU9OM4upRIejWB80BZhe9m600lfomnoedaTU/ID6YaMtRHZu9kwfRXhSij0Jvlk
         29zFKzD47DKFOyCdPUS9rBv2bJfRZWxYEfxlMzDzzj4H/716LDrpLhAoWku/uZFc0WbD
         nt9g==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327;
        h=to:subject:message-id:date:from:mime-version:dkim-signature;
        bh=nTIIuknWnUTTI4KRR1r6B/DrPnrMWBrh809+XVbtzAg=;
        fh=LTacc6x40HB7PYSeGDYKIZ0wcUpmns+8Y+dpYts4Epk=;
        b=ryvGOdECx0LpLQlIY06aEeIHRSDBE8WhG/TLi3BFvXrlut4kwxpKl5kmAiphlB7IbM
         hwYoPCIVRjh8BPAdAMwFD70WJxTE4HAit1taaFLBFJn8Gd8lXnLXznvnV6WjDH/BGvhY
         n7Q8XFRL7NeXI5+ommVZscVSBEQFC7RZA58GCs1HAORbx3xNxb5z/3TYLC2qf662em7F
         HD/4xkneNQG1JInhV5Xu3PVN15EE94e3NIh98jSHvrN2J5zjYxLJIc6dTeb3sTOE9Xt9
         GDo5K2jjBCjTs42yKR4EjvTsqXwJU7BE2z9fLMAjCCnYETf3bhRwRduZ6fLDgwie3wTL
         xATQ==;
        darn=lists.xenproject.org
ARC-Authentication-Results: i=1; mx.google.com; arc=none
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20251104; t=1792510701; x=1793115501; darn=lists.xenproject.org;
        h=content-type:to:subject:message-id:date:from:mime-version:from:to
         :cc:subject:date:message-id:reply-to:content-type;
        bh=nTIIuknWnUTTI4KRR1r6B/DrPnrMWBrh809+XVbtzAg=;
        b=Po+hF4wPa+cLckzli94v5CO+4pYrIHysnpUOUIrxEIn04WGsDSQ7q4tlOiyGoy4Ptp
         4lfMkAhGCZYthfbNpisz7idKlWays5DSo75lCHAeD9FNYoOX33Iw5xqiWuUrhRM2wrlC
         OPcadA2uppQ5rvqayRLiDhUqsb3rmX3gL7JADZPvBLPAZIjgstJX/K4Ixh+OVph46P0k
         yy0io2y0neymY7KnWeaU/5k4Tncc8Z5Q/O5Boj0b67EjQs85t18SgGIzMmR3bg7eJHvH
         XsIx78GbOvlpXD7XJ3vTQu/DOciUCoTxxsEg/9kUdC4Ve8PKs0B7/iyIgAqa7eNd3YNx
         dePA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20260707; t=1792510701; x=1793115501;
        h=content-type:to:subject:message-id:date:from:mime-version:x-gm-gg
         :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to
         :content-type;
        bh=nTIIuknWnUTTI4KRR1r6B/DrPnrMWBrh809+XVbtzAg=;
        b=vp48cXQh6kMMdUupINdk395eMaEQ+lZ+G0skKXhCm44xorjFZQzxzDwdn0O1RVyjKD
         VMf7DBZLiEh0E4I/XQCIEJtyX2/NAxNxRQT2q5HWYOkMEIizRboMKeG+ovipCGnbSYfA
         yb0RAOeVOJFAz+quSFzx4SFs/ZiNqft000wUYbw2yY4J/fzvRWnZDF2CP4NqVTM07UFI
         KD10fuafTLklJ5haZ/cjaUcOumkQyPu3UvVn1B0WrU4eHMI478Fpa4hrbfSqaY605TIt
         63r6PZTxJtuAm8oQ/z2cQyCJutjXNnoWDaCZWDD9wbBvqtrNJO8vhCB5udXIfGr9E1w6
         kQ0g==
X-Gm-Message-State: AFq9FYKyXpr8jqw26ASFkbXQEH9AJNgHivt5M7RBVZpxEdueMIgF3CSs
	ioqPqUuMMyUgWALk91LsyRtJ5hx4rU/6/appSVk/pBoA2HgmBMvs4LUBCVYo2fGXPgNyrSnHmcq
	R3Ek2wQoRZArS8rfDFq52LhA7XbST2ydtksL4b70UsZSD
X-Gm-Gg: AYBFou3G+sYuj9UHx9vkUMZO1CBGsK/PHyeKYWloEaLDC/aJC+SOGxnS0Nw1SjeyF+V
	8p1TUhqOZvyvRUyzJJ/NRPZp6+ty4sK0QMspbYU+a51nwMz1350KM6FP9QUjm/7zKziykZdwFn4
	xB19/nLlDjNhoYSbdhFoQqwm2Yj575Mg8h5odCcx8x/DIjYLhvEqpZNsnpjhuDT04Gw5sAcfjmL
	srq+BHsshXSJ7lsWip6mJFjleLV+B8RpuGNa34YXdchRQLezPU0WNBghggjP1gg+0LIUL+u3deP
	UnxopysNYwzPgzyrQeQdtMrnvB0nyWPG2KiVMdK0ZIvR2g/X4WSMDa8Csz/Zx7xLhMmXcMNHHZ3
	aaXUedGLCmqpFw+1PPGoz641VZI26LkgO39jaZ5qIp1IdZ6ek/eLN8PJekNBZLwzpFI55n6JoFk
	YEpQjdRnd3J/2GqaENWbv6i/L7rBiNqxAsJgoqTY/Fz9cDhsJiWz7t/y+XzTwE79l+B3Hc
X-Received: by 2002:a05:690c:6602:b0:8a8:7fda:15ee with SMTP id
 00721157ae682-8b0f21f9626mr45697977b3.50.1792510700272; Tue, 20 Oct 2026
 08:38:20 -0700 (PDT)
MIME-Version: 1.0
From: Romain Calascibetta <romain.calascibetta@gmail.com>
Date: Tue, 20 Oct 2026 15:38:08 +0000
X-Gm-Features: AclHuK8UT37GuKcEyPJcZFvWhUc8KCZNjTjfVNfag2sM0q8oPUSLfvSk7vXhMlo
Message-ID: <CAOc4sy-RkL10eUO4Sn_bXkuQoRSmWn7YxYM7AZ9qH0KufPs-ow@mail.gmail.com>
Subject: uniker.nl - a new way to develop and deploy unikernels in OCaml
To: mirageos-devel <mirageos-devel@lists.xenproject.org>
Content-Type: multipart/alternative; boundary="0000000000008bc04c065e476ba6"
X-purgate-ID: tlsNG-16d1c6/1792510702-F647377B-565AB6EA/0/0
X-purgate-type: clean
X-purgate-size: 49932

--0000000000008bc04c065e476ba6
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

This is a cross-post in Markdown format that you can find here:

We are delighted to announce the launch of our new website:
[uniker.nl][uniker.nl]. This website embodies our new approach to developin=
g
unikernels with OCaml 5. It offers a new way of developing unikernels and
now
places just as much emphasis on the deployment and use of unikernels. The
website features a comprehensive [tutorial][uniker.nl-tutorial] and
resources
to help you get to grips with our new ecosystem, providing a _first entry
point_ for anyone interested in unikernels in OCaml.

The content of this site is available [here][uniker.nl-repo], is powered by
the
excellent [YOCaml][yocaml] project, and is deployed using our
[immuable][immuable] unikernel.

## Our new ecosystem

We were able to present our new workflow at the [OCaml Workshop
2026][workshop]
([slides][slides]) and our approach can be summarised in two main points:
- the development of unikernels
- the deployment of unikernels and their uses

### To develop unikernels

Our co-operative has been developing unikernels for quite a few years now.
[Our
blog][blog-robur] showcases some of the ones we use for our infrastructure.
Based on our experience, we are well aware of the constraints and
limitations
of what we can achieve when it comes to developing an application in the
form
of a unikernel. The best-known constraint we have accepted is not to requir=
e
the POSIX interface (nor to attempt to replicate it) in terms of protocols
and
formats. One of the rules still adhered to today is, amongst other things,
[not
to depend on I/O or a scheduler][sans-io]<sup>[1][sans-io-2]</sup> when
providing implementations.

Building on this experience, we have been able to develop protocols and
formats
that are currently being used by others in contexts other than unikernels.

However, we have also seen the limits of what we can achieve, particularly
with
what MirageOS currently offers. With this in mind, and upon further
reflection
on the constraints we face when developing unikernels (particularly
regarding
cross-compilation), we have decided to structure the development of
unikernels
using two tools: [`unic`][unic] and [`mfetch`][mfetch].

#### [`unic`][unic]: how to infer dependencies and _vendor_ them

One constraint we face with unikernels is the need to recompile C files wit=
h
specific options so that they do not depend on what already exists on the
host
system. The approach taken by MirageOS 3 was to distribute the result of
this
specific compilation within libraries that contain C stubs (such as
[`digestif`][digestif] or [`mirage-crypto`][mirage-crypto]). The problem is
that we were forcing users of these libraries to install
[`ocaml-solo5`][ocaml-solo5] in order to obtain a compilation environment
for C
files specific to [Solo5][solo5], our core component for producing
unikernels.

MirageOS 4 then arrived with `dune` and its contexts, allowing us to
achieve a
consistent compilation environment for C files. However, this approach
introduced new a constraint: all dependencies of our unikernels had to use
`dune`, which is **legitimately** not the case in the OCaml ecosystem.

It is for this reason that we decided to refine the need to recompile some
of
our libraries a little further and, finally, to be able to capitalise on a
key
advantage of [`ocaml-solo5`][ocaml-solo5], namely that compiling OCaml file=
s
with this compiler produces exactly the same result as if you were using
your
host OCaml compiler: in other words, and as has been the case from the
beginning, we strictly only need to cross-compile the C files.

It is therefore at the intersection of these two features (only needing to
cross-compile the C files and being able to reuse libraries written in pure
OCaml and compiled with the host compiler) that we can offer users the
ability
to write this sort of code without involving any maintenance work on
libraries
that do not use `dune` and without necessarily having to recompile
everything:

```shell
$ opam install unic
$ cat >main.ml<<EOF
> open Digestif

> let () =3D Mkernel.run [] @@ fun () ->
>   Fmt.pr "%a\n%!" SHA1.pp (SHA1.digest_string "Hello World!")
> EOF
$ unic infer -r .
Module Digestif is provided by several ocamlfind packages:
  [0] digestif.c
  [1] digestif.ocaml
Pick one [0-1]: 0
digestif
mkernel
$ opam source digestif
$ opam source mkernel
$ dune build
$ solo5-hvt -- _build/solo5/main.exe --solo5:quiet
2ef7bde608ce5404e97d5f042f95f89f1c232871Solo5
```

`unic` is therefore a tool capable of inferring the dependencies of an OCam=
l
project without using a specific build system, and of calculating what
needs to
be cross-compiled (in this case `digestif` and `mkernel` but not `fmt`) to
produce a unikernel. The project serves our purpose first and foremost, but
it
is worth noting that it can also be useful when compiling statically linked
executables.

This tool offers a whole range of sub-tools for analysing META files,
viewing
an artefact from different perspectives (its module name, its `ocamlfind`
package name and its OPAM package name) or analysing OCaml artefacts (such
as
`*.cmxa` files).

We would particularly like to thank @Octachron for his [`codept`][codept]
project (on which `unic` is based) and for working with us to improve it.

### [`mfetch`][mfetch]: how to vendor dependencies

Having identified more precisely which dependencies need to be
cross-compiled,
we now need to download these dependencies. Although `opam source` does the
job
very well, we wanted a tool that could download the source code from variou=
s
types of source, such as:
- from a _tarball_, as is usually the case
- but also from a Git repository
- or even from a specific location on your file system

That is why we developed `mfetch`, which allows you to download software
sources based on information provided by OPAM or the user, and to create a
`vendors` folder containing all these sources.

```shell
$ unic infer -r . -o _mfetch
$ mfetch --with-dune-file
 digestif                 =E2=94=82=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=
=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=
=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=94=82    3.1 MiB /    3=
.1 MiB
 5.9 MiB/s
 mkernel                  =E2=94=82=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=
=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=
=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=94=82   37.3 KiB /   37=
.3 KiB
 3.4 MiB/s

digestif                         ok
mkernel                          ok
$ dune build
```

`mfetch` also allows you to check whether you have modified any of the
source
files (for a bug fix) or to generate a `*.locked` file so that you can then
verify the reproducibility of your unikernel using our other tool
[`orb`][orb].
The tool itself is not revolutionary, but it helps to streamline the
workflow.

```shell
$ mfetch status
digestif                         ok
mkernel                          ok
$ mfetch lock
2 sources locked into _mfetch.locked
```

#### Libraries for OCaml 5

Our new workflow now uses OCaml 5. As well as updating the basic building
blocks required to produce unikernels with OCaml 5, we have also developed =
a
series of libraries that primarily enable us to take advantage of effects.
Furthermore, over the past several years we have developed:
- [Miou][miou-announce], our scheduler for OCaml 5
- [`mkernel`][mkernel], a derivative of our Miou scheduler designed to
handle
  the I/O provided by Solo5
- [`mnet`][mnet-announce], a reimplementation of the TCP/IP stack (using
  [`utcp`][utcp]) in OCaml with effects
- and plenty of other libraries such as [`mhttp`][mhttp],
  [`msendmail`][msendmail], [`mfat`][mfat], [`vifu`][vifu], etc.

These libraries, currently used by some of our deployed unikernels, allow
us to
offer developers a _direct-style_ approach to implementing their unikernels=
.

But what is key to take away from this emerging ecosystem is the
retrospective
analysis of past projects to ensure we do not repeat the same mistakes. We
very
quickly realised that it could be very difficult to migrate existing
libraries
using [`lwt`][lwt] (the MirageOS scheduler) to Miou (or any other scheduler
using effects). We therefore took the opportunity not only to propose a
_direct-style_ approach using Miou, but also to rethink the implementation
of
our libraries in light of what we've learnt from deploying unikernels with
MirageOS. We have paid particular attention to memory usage, to avoiding
known
CVEs from our previous implementations (as we are also part of the OCaml
security team), and also to offering an alternative API that does not
systematically rely on functors.

The approach is still experimental, as we need to consolidate this new
ecosystem across several layers, but we are firmly convinced (based on what
we've observed in our deployed unikernels) that these new implementations
are
significantly better than what we used in the past.

### To deploy unikernels

The other side of unikernels is deployment. Indeed, it is not just a matter
of
developing unikernels (and making their development easier) but also of
deploying and using them. Our main objective remains to replace existing
services with unikernels (name servers, websites, time servers, etc.), and
the
way to compete with existing infrastructure is to actively deploy and use
our
unikernels.

That is why we have developed two projects:
- [Albatross][albatross], an OCaml service for launching unikernels
- [Aussi][aussi], an OCI runtime for Solo5

We mainly use Albatross in conjunction with our infrastructure for verifyin=
g
the reproducibility of our unikernels: [builds.robur.coop][builds.robur.coo=
p
].
In this way, we can trace the dependencies of the unikernels - particularly
their CVEs - and ensure supply-chain security.

Next comes deployment, and we are therefore seeking to integrate our
unikernels
into existing infrastructure and provide ways of monitoring them, in
particular
using [InfluxDB][influxdb], [Telegraf][telegraf] and [Grafana][grafana].

This is how we are able to offer services such as (note that some haven't
yet
been ported to `mkernel`/`mnet`, but will be soon):
- simple websites such as our https://blog.robur.coop/ (using
[`unipi`][unipi]
  or [`immuable`][immuable])
- domain name management for domains such as `robur.coop`, `reyn.ir` or
  `din.osau.re` (via our [primary][dns-primary-git] DNS server and
  [secondary][mnet-secondary] server)
- a VPN service, whether using [MirageVPN][MirageVPN] or [Zostera][zostera]
- a time server (using [Chaos][chaos]): https://chaos.osau.re/
- a [CalDAV][caldav] calendar system
- [a mailing list][mailingl.st] using the [`ptt`][ptt] project
- a TLS termination proxy such as [`tlstunnel`][tlstunnel] or
  [`contruno`][contruno] (used by sherlocode.com)
- and many more!

It is therefore through actual use that we improve our unikernels and the
libraries that depend on them. That is why part of our tutorial also
focuses on
deploying unikernels, so that you can use them and help us with your
feedback.

Finally, we are also proposing a project called [Mollymawk][mollymawk],
designed to simplify the deployment of unikernels via a web interface, so
that,
in future, we can offer access to our infrastructure to anyone who wishes t=
o
use it (and we would like to thank @kit-ty-kate for their various attempts)=
.

## About us

Finally, none of this would be possible without our co-operative and the
way we
organise our work. You can view the details of our finances
[here][robur-finance]. We accept donations and have recently secured fundin=
g
from NLnet. Private companies such as [Ahrefs][ahrefs] and
[Tarides][tarides]
also sponsor our work. We also have partnerships with [OCamlPro][ocamlpro]
and
the [OCaml Foundation][ocf]. And we contribute to the OCaml ecosystem on a
daily basis by working with individuals and companies.

You can find more details on [our website][robur.coop]. We would like to
emphasise that it is thanks to our structure (that of an association) that
we
are able to carry out this work, and we would like to thank our sponsors.

## Unikernels and MirageOS

Enthusiasts may wonder what the advantage of our approach is compared to
MirageOS, a unikernel project that remains active thanks to our maintenance
work. Our approach is characterised by five points that we have identified
as
glass ceilings to the adoption of unikernels:
- the first concerns the use of [`ocaml-cstruct`][ocaml-cstruct]. The
  fundamental issue remains the use of `bigarray` as _buffer_ instead of
  `bytes`/`string`. Our experience whilst developing [MirageVPN][miragevpn]
has
  shown us that using `cstruct` as a systematic library for the _buffer_
  concept Across our entire ecosystem was our biggest **penalty** in terms
of
  throughput for our unikernel. This is why we decided not only to develop
  [`bstr`][bstr] and [`slice`][bstr], but also to rewrite the majority of
our
  libraries by replacing `cstruct` with `bytes`/`string` (this was the case
for
  [`ocaml-tls`][ocaml-tls-pr], [`mirage-crypto`][mirage-crypto-pr],
  [`ocaml-dns`][ocaml-dns-pr] and, more recently, [`awa-ssh`][awa-ssh-pr]
and
  [`utcp`][utcp-pr]). The conclusion is quite simple: it is not a question
of
  stopping using bigarray, but rather of not making their use systematic in
our
  aPIs.
- the second point concerns the use of functors to express the devices
required
  by the unikernel. The approach of reusing interfaces to inject specific
  implementations that concretize these devices via functors may seem
  appealing, but the maintenance cost of such an ecosystem=E2=80=94constrai=
ned by
  interfaces that are no longer really up to date with new concepts=E2=80=
=94has led
us
  into [absurd situations][absurd] whenever we've needed to develop more
  specific unikernels tailored to our requirements. Once again, the rule is
not
  to stop using functors, but not to make their use systematic.
- the third point concerns the compilation of unikernels. MirageOS relies
on a
  workaround that, even today, integrates very poorly with `dune`; this can
be
  defined as: _multi-stage compilation_, where a code-generation phase is
  required depending on the desired _target_. This way of structuring the
  workflow with a set of dependencies dictated by the tool explicitly
restricts
  the developer in what they wish to do and how they wish to do it. Althoug=
h
  there are constraints on compiling a unikernel (such as not using the
`Unix`
  module), our cooperative has decided to provide **informative** (and not
  prescriptive) tools that assist (but do not force) the user in designing
  their unikernel (furthermore, we are also delighted to introduce
  [`unic`][unic] and [`mfetch`][mfetch]). The key point of our new approach
is
  to ensure that it is the user who has the final say, rather than the tool
(in
  this case, `mirage`), in the development of unikernels.

  It is very intricate on what the `mirage` tool does, including generation
of
  functor applications and some initialization stubs, as well as opam
version
  constraints (since the functors and initialization functions may change i=
n
  new opam packages). The `mirage` tool has a closed world assumption, and
it
  is hard to use a package not known by `mirage` - it is as well very hard
to
  use `js_of_ocaml` in a `mirage` unikernel.
- the fourth point concerns the maintenance of this ecosystem, and
specifically
  the maintenance of the tools and libraries on which MirageOS relies.
  Furthermore, we have experienced some disappointments with
`opam-monorepo`,
  and we are finding, day by day, that it is becoming increasingly
difficult to
  update `mirage-tcpip` in line with OCaml 5. Our involvement in the OCaml
  security team has also led us to wish to deprecate certain libraries due
to a
  lack of maintenance. We are therefore refocusing our ecosystem on what ou=
r
  co-operative produces and maintains.
- Finally, the last point concerns our work with the community, which
remains
  unchanged despite the emergence of AI. We have observed a certain abusive
use
  of AI to solve non-existent problems relating to unikernels, which, in ou=
r
  view, undermines our credibility regarding the security, maintenance and
  quality of our software. In this regard, we are trying to distance
ourselves
  from those who prefer _vibe-coding_ rather than deployment. This approach
is
  reflected in our use of the [AGPL][agpl] as our licence (whilst offering
the
  option of dual licensing) and a [POLICY][policy] regarding the use of AI.

All of this has led us to propose MirageOS 5, which represents a fundamenta=
l
departure from the factors that characterised the failure of MirageOS 4 (fo=
r
which I was the release manager). It is therefore, having acknowledged this
defeat (and analysed it), that we are proposing a new approach to creating
and
deploying unikernels: [uniker.nl][uniker.nl].

As regards the projects associated with the MirageOS project, we will, of
course, continue to maintain some of them, whilst at the same time offering
more up-to-date solutions to those who use some of our libraries. We would
also
be delighted to help anyone wishing to migrate to our new libraries and
tools;
we are (as we always have been) available to assist.

[unic]: https://github.com/robur-coop/unic
[mfetch]: https://github.com/robur-coop/mfetch
[agpl]: https://www.gnu.org/licenses/agpl-3.0.en.html
[policy]: https://github.com/Solo5/solo5/blob/main/AI.md
[ocaml-cstruct]: https://github.com/mirage/ocaml-cstruct
[miragevpn]: https://github.com/robur-coop/miragevpn
[tarides]: https://tarides.com/
[ahrefs]: https://ahrefs.com/
[robur-finance]: https://blog.robur.coop/articles/finances.html
[mollymawk]: https://mollymawk.robur.coop/
[bstr]: https://github.com/robur-coop/bstr
[immuable]: https://github.com/dinosaure/immuable
[uniker.nl]: https://uniker.nl/
[builds.robur.coop]: https://builds.robur.coop
[zostera]: https://github.com/robur-coop/zostera
[workshop]: https://ocaml.org/ocaml-workshop-2026
[slides]:
https://docs.google.com/presentation/d/1bOXJAPEEjPBx_8i0frThKhLpHd8C7-EPRcz=
EQjvz6JU/edit?slide=3Did.g3f7268904c5_0_1#slide=3Did.g3f7268904c5_0_1
[uniker.nl-tutorial]: https://uniker.nl/introduction/
[yocaml]: https://yocaml.github.io/tutorial/index.html
[blog-robur]: https://blog.robur.coop/
[miou-announce]:
https://discuss.ocaml.org/t/ann-miou-a-simple-scheduler-for-ocaml-5/12963
[sans-io]: https://discuss.ocaml.org/t/on-concurrency-models/15899/13
[sans-io-2]:
https://discuss.ocaml.org/t/why-ocsigen-is-staying-on-lwt-for-now/18318/27
[digestif]: https://github.com/mirage/digestif
[mnet]:
https://discuss.ocaml.org/t/ann-mnet-a-new-tcp-ip-stack-for-unikernels-in-o=
caml/17851
[mirage-crypto]: https://github.com/mirage/mirage-crypto
[solo5]: https://github.com/solo5/solo5
[mkernel]: https://github.com/robur-coop/mkernel
[lwt]: https://github.com/ocsigen/lwt
[tlstunnel]: https://github.com/robur-coop/tlstunnel
[contruno]: https://github.com/robur-coop/contruno
[mailingl.st]: https://mailingl.st
[ptt]: https://github.com/robur-coop/ptt
[albatross]: https://github.com/robur-coop/albatross
[aussi]: https://github.com/robur-coop/aussi
[chaos]: https://github.com/robur-coop/chaos
[unipi]: https://github.com/robur-coop/unipi
[mnet]: https://github.com/robur-coop/mnet
[ocaml-solo5]: https://github.com/mirage/ocaml-solo5
[utcp]: https://github.com/robur-coop/utcp
[codept]: https://github.com/Octachron/codept
[mnet-announce]:
https://discuss.ocaml.org/t/ann-mnet-a-new-tcp-ip-stack-for-unikernels-in-o=
caml/17851
[mhttp]: https://github.com/robur-coop/mhttp
[mfat]: https://github.com/robur-coop/mfat
[vifu]: https://github.com/robur-coop/vif
[msendmail]: https://github.com/robur-coop/colombe
[dns-primary-git]: https://github.com/robur-coop/dns-primary-git/
[mnet-secondary]: https://git.robur.coop/robur/dns-secondary/
[uniker.nl-repo]: https://github.com/robur-coop/uniker.nl
[orb]: https://github.com/robur-coop/orb
[grafana]: https://grafana.com/
[influxdb]: https://www.influxdata.com/
[telegraf]: https://www.influxdata.com/time-series-platform/telegraf/
[ocamlpro]: https://ocamlpro.com
[ocf]: https://ocaml-sf.org/
[robur.coop]: https://robur.coop/
[ocaml-tls-pr]: https://github.com/mirleft/ocaml-tls/pull/497
[mirage-crypto-pr]: https://github.com/mirage/mirage-crypto/pull/214
[ocaml-dns-pr]: https://github.com/mirage/ocaml-dns/pull/351
[awa-ssh-pr]: https://github.com/mirage/awa-ssh/pull/85
[utcp-pr]: https://github.com/robur-coop/utcp/pull/55
[absurd]:
https://github.com/robur-coop/dnsvizor/blob/83b32596c4a08c080067e1cd36fe578=
8b90cdd78/unikernel.ml#L610-L631
[caldav]: https://github.com/robur-coop/caldav

--=20
Romain Calascibetta - http://din.osau.re/

--0000000000008bc04c065e476ba6
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>This is a cross-post in Markdown format that you can =
find here:<br><br>We are delighted to announce the launch of our new websit=
e:<br>[<a href=3D"http://uniker.nl">uniker.nl</a>][<a href=3D"http://uniker=
.nl">uniker.nl</a>]. This website embodies our new approach to developing<b=
r>unikernels with OCaml 5. It offers a new way of developing unikernels and=
 now<br>places just as much emphasis on the deployment and use of unikernel=
s. The<br>website features a comprehensive [tutorial][uniker.nl-tutorial] a=
nd resources<br>to help you get to grips with our new ecosystem, providing =
a _first entry<br>point_ for anyone interested in unikernels in OCaml.<br><=
br>The content of this site is available [here][uniker.nl-repo], is powered=
 by the<br>excellent [YOCaml][yocaml] project, and is deployed using our<br=
>[immuable][immuable] unikernel.<br><br>## Our new ecosystem<br><br>We were=
 able to present our new workflow at the [OCaml Workshop 2026][workshop]<br=
>([slides][slides]) and our approach can be summarised in two main points:<=
br>- the development of unikernels<br>- the deployment of unikernels and th=
eir uses<br><br>### To develop unikernels<br><br>Our co-operative has been =
developing unikernels for quite a few years now. [Our<br>blog][blog-robur] =
showcases some of the ones we use for our infrastructure.<br>Based on our e=
xperience, we are well aware of the constraints and limitations<br>of what =
we can achieve when it comes to developing an application in the form<br>of=
 a unikernel. The best-known constraint we have accepted is not to require<=
br>the POSIX interface (nor to attempt to replicate it) in terms of protoco=
ls and<br>formats. One of the rules still adhered to today is, amongst othe=
r things, [not<br>to depend on I/O or a scheduler][sans-io]&lt;sup&gt;[1][s=
ans-io-2]&lt;/sup&gt; when<br>providing implementations.<br><br>Building on=
 this experience, we have been able to develop protocols and formats<br>tha=
t are currently being used by others in contexts other than unikernels.<br>=
<br>However, we have also seen the limits of what we can achieve, particula=
rly with<br>what MirageOS currently offers. With this in mind, and upon fur=
ther reflection<br>on the constraints we face when developing unikernels (p=
articularly regarding<br>cross-compilation), we have decided to structure t=
he development of unikernels<br>using two tools: [`unic`][unic] and [`mfetc=
h`][mfetch].<br><br>#### [`unic`][unic]: how to infer dependencies and _ven=
dor_ them<br><br>One constraint we face with unikernels is the need to reco=
mpile C files with<br>specific options so that they do not depend on what a=
lready exists on the host<br>system. The approach taken by MirageOS 3 was t=
o distribute the result of this<br>specific compilation within libraries th=
at contain C stubs (such as<br>[`digestif`][digestif] or [`mirage-crypto`][=
mirage-crypto]). The problem is<br>that we were forcing users of these libr=
aries to install<br>[`ocaml-solo5`][ocaml-solo5] in order to obtain a compi=
lation environment for C<br>files specific to [Solo5][solo5], our core comp=
onent for producing unikernels.<br><br>MirageOS 4 then arrived with `dune` =
and its contexts, allowing us to achieve a<br>consistent compilation enviro=
nment for C files. However, this approach<br>introduced new a constraint: a=
ll dependencies of our unikernels had to use<br>`dune`, which is **legitima=
tely** not the case in the OCaml ecosystem.<br><br>It is for this reason th=
at we decided to refine the need to recompile some of<br>our libraries a li=
ttle further and, finally, to be able to capitalise on a key<br>advantage o=
f [`ocaml-solo5`][ocaml-solo5], namely that compiling OCaml files<br>with t=
his compiler produces exactly the same result as if you were using your<br>=
host OCaml compiler: in other words, and as has been the case from the<br>b=
eginning, we strictly only need to cross-compile the C files.<br><br>It is =
therefore at the intersection of these two features (only needing to<br>cro=
ss-compile the C files and being able to reuse libraries written in pure<br=
>OCaml and compiled with the host compiler) that we can offer users the abi=
lity<br>to write this sort of code without involving any maintenance work o=
n libraries<br>that do not use `dune` and without necessarily having to rec=
ompile everything:<br><br>```shell<br>$ opam install unic<br>$ cat &gt;<a h=
ref=3D"http://main.ml">main.ml</a>&lt;&lt;EOF<br>&gt; open Digestif<br><br>=
&gt; let () =3D Mkernel.run [] @@ fun () -&gt;<br>&gt; =C2=A0 Fmt.pr &quot;=
%a\n%!&quot; SHA1.pp (SHA1.digest_string &quot;Hello World!&quot;)<br>&gt; =
EOF<br>$ unic infer -r .<br>Module Digestif is provided by several ocamlfin=
d packages:<br>=C2=A0 [0] digestif.c<br>=C2=A0 [1] digestif.ocaml<br>Pick o=
ne [0-1]: 0<br>digestif<br>mkernel<br>$ opam source digestif<br>$ opam sour=
ce mkernel<br>$ dune build<br>$ solo5-hvt -- _build/solo5/main.exe --solo5:=
quiet<br>2ef7bde608ce5404e97d5f042f95f89f1c232871Solo5<br>```<br><br>`unic`=
 is therefore a tool capable of inferring the dependencies of an OCaml<br>p=
roject without using a specific build system, and of calculating what needs=
 to<br>be cross-compiled (in this case `digestif` and `mkernel` but not `fm=
t`) to<br>produce a unikernel. The project serves our purpose first and for=
emost, but it<br>is worth noting that it can also be useful when compiling =
statically linked<br>executables.<br><br>This tool offers a whole range of =
sub-tools for analysing META files, viewing<br>an artefact from different p=
erspectives (its module name, its `ocamlfind`<br>package name and its OPAM =
package name) or analysing OCaml artefacts (such as<br>`*.cmxa` files).<br>=
<br>We would particularly like to thank @Octachron for his [`codept`][codep=
t]<br>project (on which `unic` is based) and for working with us to improve=
 it.<br><br>### [`mfetch`][mfetch]: how to vendor dependencies<br><br>Havin=
g identified more precisely which dependencies need to be cross-compiled,<b=
r>we now need to download these dependencies. Although `opam source` does t=
he job<br>very well, we wanted a tool that could download the source code f=
rom various<br>types of source, such as:<br>- from a _tarball_, as is usual=
ly the case<br>- but also from a Git repository<br>- or even from a specifi=
c location on your file system<br><br>That is why we developed `mfetch`, wh=
ich allows you to download software<br>sources based on information provide=
d by OPAM or the user, and to create a<br>`vendors` folder containing all t=
hese sources.<br><br>```shell<br>$ unic infer -r . -o _mfetch<br>$ mfetch -=
-with-dune-file<br>=C2=A0digestif =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =E2=94=82=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=
=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=
=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=94=82 =C2=A0 =C2=A03.1 MiB / =C2=A0=
 =C2=A03.1 MiB =C2=A0 =C2=A05.9 MiB/s <br>=C2=A0mkernel =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=E2=94=82=E2=96=88=E2=96=88=E2=
=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=
=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=94=82=
 =C2=A0 37.3 KiB / =C2=A0 37.3 KiB =C2=A0 =C2=A03.4 MiB/s <br><br>digestif =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 ok<br>mkernel =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ok<br>$ dune build<br>```<br><br>`=
mfetch` also allows you to check whether you have modified any of the sourc=
e<br>files (for a bug fix) or to generate a `*.locked` file so that you can=
 then<br>verify the reproducibility of your unikernel using our other tool =
[`orb`][orb].<br>The tool itself is not revolutionary, but it helps to stre=
amline the workflow.<br><br>```shell<br>$ mfetch status<br>digestif =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 ok<br>mkernel =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ok<br>$ mfetch lock<br>2 sources locked i=
nto _mfetch.locked<br>```<br><br>#### Libraries for OCaml 5<br><br>Our new =
workflow now uses OCaml 5. As well as updating the basic building<br>blocks=
 required to produce unikernels with OCaml 5, we have also developed a<br>s=
eries of libraries that primarily enable us to take advantage of effects.<b=
r>Furthermore, over the past several years we have developed:<br>- [Miou][m=
iou-announce], our scheduler for OCaml 5<br>- [`mkernel`][mkernel], a deriv=
ative of our Miou scheduler designed to handle<br>=C2=A0 the I/O provided b=
y Solo5<br>- [`mnet`][mnet-announce], a reimplementation of the TCP/IP stac=
k (using<br>=C2=A0 [`utcp`][utcp]) in OCaml with effects<br>- and plenty of=
 other libraries such as [`mhttp`][mhttp],<br>=C2=A0 [`msendmail`][msendmai=
l], [`mfat`][mfat], [`vifu`][vifu], etc.<br><br>These libraries, currently =
used by some of our deployed unikernels, allow us to<br>offer developers a =
_direct-style_ approach to implementing their unikernels.<br><br>But what i=
s key to take away from this emerging ecosystem is the retrospective<br>ana=
lysis of past projects to ensure we do not repeat the same mistakes. We ver=
y<br>quickly realised that it could be very difficult to migrate existing l=
ibraries<br>using [`lwt`][lwt] (the MirageOS scheduler) to Miou (or any oth=
er scheduler<br>using effects). We therefore took the opportunity not only =
to propose a<br>_direct-style_ approach using Miou, but also to rethink the=
 implementation of<br>our libraries in light of what we&#39;ve learnt from =
deploying unikernels with<br>MirageOS. We have paid particular attention to=
 memory usage, to avoiding known<br>CVEs from our previous implementations =
(as we are also part of the OCaml<br>security team), and also to offering a=
n alternative API that does not<br>systematically rely on functors.</div><d=
iv><br></div><div>The approach is still experimental, as we need to consoli=
date this new<br>ecosystem across several layers, but we are firmly convinc=
ed (based on what<br>we&#39;ve observed in our deployed unikernels) that th=
ese new implementations are<br>significantly better than what we used in th=
e past.<br><br>### To deploy unikernels<br><br>The other side of unikernels=
 is deployment. Indeed, it is not just a matter of<br>developing unikernels=
 (and making their development easier) but also of<br>deploying and using t=
hem. Our main objective remains to replace existing<br>services with uniker=
nels (name servers, websites, time servers, etc.), and the<br>way to compet=
e with existing infrastructure is to actively deploy and use our<br>unikern=
els.<br><br>That is why we have developed two projects:<br>- [Albatross][al=
batross], an OCaml service for launching unikernels<br>- [Aussi][aussi], an=
 OCI runtime for Solo5<br><br>We mainly use Albatross in conjunction with o=
ur infrastructure for verifying<br>the reproducibility of our unikernels: [=
<a href=3D"http://builds.robur.coop">builds.robur.coop</a>][<a href=3D"http=
://builds.robur.coop">builds.robur.coop</a>].<br>In this way, we can trace =
the dependencies of the unikernels - particularly<br>their CVEs - and ensur=
e supply-chain security.<br><br>Next comes deployment, and we are therefore=
 seeking to integrate our unikernels<br>into existing infrastructure and pr=
ovide ways of monitoring them, in particular<br>using [InfluxDB][influxdb],=
 [Telegraf][telegraf] and [Grafana][grafana].<br><br>This is how we are abl=
e to offer services such as (note that some haven&#39;t yet</div><div>been =
ported to `mkernel`/`mnet`, but will be soon):<br>- simple websites such as=
 our <a href=3D"https://blog.robur.coop/">https://blog.robur.coop/</a> (usi=
ng [`unipi`][unipi]<br>=C2=A0 or [`immuable`][immuable])<br>- domain name m=
anagement for domains such as `<a href=3D"http://robur.coop">robur.coop</a>=
`, `<a href=3D"http://reyn.ir">reyn.ir</a>` or<br>=C2=A0 `<a href=3D"http:/=
/din.osau.re">din.osau.re</a>` (via our [primary][dns-primary-git] DNS serv=
er and<br>=C2=A0 [secondary][mnet-secondary] server)<br>- a VPN service, wh=
ether using [MirageVPN][MirageVPN] or [Zostera][zostera]<br>- a time server=
 (using [Chaos][chaos]): <a href=3D"https://chaos.osau.re/">https://chaos.o=
sau.re/</a><br>- a [CalDAV][caldav] calendar system<br>- [a mailing list][<=
a href=3D"http://mailingl.st">mailingl.st</a>] using the [`ptt`][ptt] proje=
ct<br>- a TLS termination proxy such as [`tlstunnel`][tlstunnel] or<br>=C2=
=A0 [`contruno`][contruno] (used by <a href=3D"http://sherlocode.com">sherl=
ocode.com</a>)<br>- and many more!<br><br>It is therefore through actual us=
e that we improve our unikernels and the<br>libraries that depend on them. =
That is why part of our tutorial also focuses on<br>deploying unikernels, s=
o that you can use them and help us with your feedback.<br><br>Finally, we =
are also proposing a project called [Mollymawk][mollymawk],<br>designed to =
simplify the deployment of unikernels via a web interface, so that,<br>in f=
uture, we can offer access to our infrastructure to anyone who wishes to<br=
>use it (and we would like to thank @kit-ty-kate for their various attempts=
).<br><br>## About us<br><br>Finally, none of this would be possible withou=
t our co-operative and the way we<br>organise our work. You can view the de=
tails of our finances<br>[here][robur-finance]. We accept donations and hav=
e recently secured funding<br>from NLnet. Private companies such as [Ahrefs=
][ahrefs] and [Tarides][tarides]<br>also sponsor our work. We also have par=
tnerships with [OCamlPro][ocamlpro] and<br>the [OCaml Foundation][ocf]. And=
 we contribute to the OCaml ecosystem on a<br>daily basis by working with i=
ndividuals and companies.<br><br>You can find more details on [our website]=
[<a href=3D"http://robur.coop">robur.coop</a>]. We would like to<br>emphasi=
se that it is thanks to our structure (that of an association) that we<br>a=
re able to carry out this work, and we would like to thank our sponsors.</d=
iv><div><br></div><div>## Unikernels and MirageOS<br><br>Enthusiasts may wo=
nder what the advantage of our approach is compared to<br>MirageOS, a unike=
rnel project that remains active thanks to our maintenance<br>work. Our app=
roach is characterised by five points that we have identified as<br>glass c=
eilings to the adoption of unikernels:<br>- the first concerns the use of [=
`ocaml-cstruct`][ocaml-cstruct]. The<br>=C2=A0 fundamental issue remains th=
e use of `bigarray` as _buffer_ instead of<br>=C2=A0 `bytes`/`string`. Our =
experience whilst developing [MirageVPN][miragevpn] has<br>=C2=A0 shown us =
that using `cstruct` as a systematic library for the _buffer_<br>=C2=A0 con=
cept Across our entire ecosystem was our biggest **penalty** in terms of<br=
>=C2=A0 throughput for our unikernel. This is why we decided not only to de=
velop<br>=C2=A0 [`bstr`][bstr] and [`slice`][bstr], but also to rewrite the=
 majority of our<br>=C2=A0 libraries by replacing `cstruct` with `bytes`/`s=
tring` (this was the case for<br>=C2=A0 [`ocaml-tls`][ocaml-tls-pr], [`mira=
ge-crypto`][mirage-crypto-pr],<br>=C2=A0 [`ocaml-dns`][ocaml-dns-pr] and, m=
ore recently, [`awa-ssh`][awa-ssh-pr] and<br>=C2=A0 [`utcp`][utcp-pr]). The=
 conclusion is quite simple: it is not a question of<br>=C2=A0 stopping usi=
ng bigarray, but rather of not making their use systematic in our<br>=C2=A0=
 aPIs.<br>- the second point concerns the use of functors to express the de=
vices required<br>=C2=A0 by the unikernel. The approach of reusing interfac=
es to inject specific<br>=C2=A0 implementations that concretize these devic=
es via functors may seem<br>=C2=A0 appealing, but the maintenance cost of s=
uch an ecosystem=E2=80=94constrained by<br>=C2=A0 interfaces that are no lo=
nger really up to date with new concepts=E2=80=94has led us<br>=C2=A0 into =
[absurd situations][absurd] whenever we&#39;ve needed to develop more<br>=
=C2=A0 specific unikernels tailored to our requirements. Once again, the ru=
le is not<br>=C2=A0 to stop using functors, but not to make their use syste=
matic.<br>- the third point concerns the compilation of unikernels. MirageO=
S relies on a<br>=C2=A0 workaround that, even today, integrates very poorly=
 with `dune`; this can be<br>=C2=A0 defined as: _multi-stage compilation_, =
where a code-generation phase is<br>=C2=A0 required depending on the desire=
d _target_. This way of structuring the<br>=C2=A0 workflow with a set of de=
pendencies dictated by the tool explicitly restricts<br>=C2=A0 the develope=
r in what they wish to do and how they wish to do it. Although<br>=C2=A0 th=
ere are constraints on compiling a unikernel (such as not using the `Unix`<=
br>=C2=A0 module), our cooperative has decided to provide **informative** (=
and not<br>=C2=A0 prescriptive) tools that assist (but do not force) the us=
er in designing<br>=C2=A0 their unikernel (furthermore, we are also delight=
ed to introduce<br>=C2=A0 [`unic`][unic] and [`mfetch`][mfetch]). The key p=
oint of our new approach is<br>=C2=A0 to ensure that it is the user who has=
 the final say, rather than the tool (in<br>=C2=A0 this case, `mirage`), in=
 the development of unikernels.<br>=C2=A0 <br>=C2=A0 It is very intricate o=
n what the `mirage` tool does, including generation of<br>=C2=A0 functor ap=
plications and some initialization stubs, as well as opam version<br>=C2=A0=
 constraints (since the functors and initialization functions may change in=
<br>=C2=A0 new opam packages). The `mirage` tool has a closed world assumpt=
ion, and it<br>=C2=A0 is hard to use a package not known by `mirage` - it i=
s as well very hard to<br>=C2=A0 use `js_of_ocaml` in a `mirage` unikernel.=
<br>- the fourth point concerns the maintenance of this ecosystem, and spec=
ifically<br>=C2=A0 the maintenance of the tools and libraries on which Mira=
geOS relies.<br>=C2=A0 Furthermore, we have experienced some disappointment=
s with `opam-monorepo`,<br>=C2=A0 and we are finding, day by day, that it i=
s becoming increasingly difficult to<br>=C2=A0 update `mirage-tcpip` in lin=
e with OCaml 5. Our involvement in the OCaml<br>=C2=A0 security team has al=
so led us to wish to deprecate certain libraries due to a<br>=C2=A0 lack of=
 maintenance. We are therefore refocusing our ecosystem on what our<br>=C2=
=A0 co-operative produces and maintains.<br>- Finally, the last point conce=
rns our work with the community, which remains<br>=C2=A0 unchanged despite =
the emergence of AI. We have observed a certain abusive use<br>=C2=A0 of AI=
 to solve non-existent problems relating to unikernels, which, in our<br>=
=C2=A0 view, undermines our credibility regarding the security, maintenance=
 and<br>=C2=A0 quality of our software. In this regard, we are trying to di=
stance ourselves<br>=C2=A0 from those who prefer _vibe-coding_ rather than =
deployment. This approach is<br>=C2=A0 reflected in our use of the [AGPL][a=
gpl] as our licence (whilst offering the<br>=C2=A0 option of dual licensing=
) and a [POLICY][policy] regarding the use of AI.<br><br>All of this has le=
d us to propose MirageOS 5, which represents a fundamental<br>departure fro=
m the factors that characterised the failure of MirageOS 4 (for<br>which I =
was the release manager). It is therefore, having acknowledged this<br>defe=
at (and analysed it), that we are proposing a new approach to creating and<=
br>deploying unikernels: [<a href=3D"http://uniker.nl">uniker.nl</a>][<a hr=
ef=3D"http://uniker.nl">uniker.nl</a>].<br><br>As regards the projects asso=
ciated with the MirageOS project, we will, of<br>course, continue to mainta=
in some of them, whilst at the same time offering<br>more up-to-date soluti=
ons to those who use some of our libraries. We would also<br>be delighted t=
o help anyone wishing to migrate to our new libraries and tools;<br>we are =
(as we always have been) available to assist.</div><div><br></div><div>[uni=
c]: <a href=3D"https://github.com/robur-coop/unic">https://github.com/robur=
-coop/unic</a><br>[mfetch]: <a href=3D"https://github.com/robur-coop/mfetch=
">https://github.com/robur-coop/mfetch</a><br>[agpl]: <a href=3D"https://ww=
w.gnu.org/licenses/agpl-3.0.en.html">https://www.gnu.org/licenses/agpl-3.0.=
en.html</a><br>[policy]: <a href=3D"https://github.com/Solo5/solo5/blob/mai=
n/AI.md">https://github.com/Solo5/solo5/blob/main/AI.md</a><br>[ocaml-cstru=
ct]: <a href=3D"https://github.com/mirage/ocaml-cstruct">https://github.com=
/mirage/ocaml-cstruct</a><br>[miragevpn]: <a href=3D"https://github.com/rob=
ur-coop/miragevpn">https://github.com/robur-coop/miragevpn</a><br>[tarides]=
: <a href=3D"https://tarides.com/">https://tarides.com/</a><br>[ahrefs]: <a=
 href=3D"https://ahrefs.com/">https://ahrefs.com/</a><br>[robur-finance]: <=
a href=3D"https://blog.robur.coop/articles/finances.html">https://blog.robu=
r.coop/articles/finances.html</a><br>[mollymawk]: <a href=3D"https://mollym=
awk.robur.coop/">https://mollymawk.robur.coop/</a><br>[bstr]: <a href=3D"ht=
tps://github.com/robur-coop/bstr">https://github.com/robur-coop/bstr</a><br=
>[immuable]: <a href=3D"https://github.com/dinosaure/immuable">https://gith=
ub.com/dinosaure/immuable</a><br>[<a href=3D"http://uniker.nl">uniker.nl</a=
>]: <a href=3D"https://uniker.nl/">https://uniker.nl/</a><br>[<a href=3D"ht=
tp://builds.robur.coop">builds.robur.coop</a>]: <a href=3D"https://builds.r=
obur.coop">https://builds.robur.coop</a><br>[zostera]: <a href=3D"https://g=
ithub.com/robur-coop/zostera">https://github.com/robur-coop/zostera</a><br>=
[workshop]: <a href=3D"https://ocaml.org/ocaml-workshop-2026">https://ocaml=
.org/ocaml-workshop-2026</a><br>[slides]: <a href=3D"https://docs.google.co=
m/presentation/d/1bOXJAPEEjPBx_8i0frThKhLpHd8C7-EPRczEQjvz6JU/edit?slide=3D=
id.g3f7268904c5_0_1#slide=3Did.g3f7268904c5_0_1">https://docs.google.com/pr=
esentation/d/1bOXJAPEEjPBx_8i0frThKhLpHd8C7-EPRczEQjvz6JU/edit?slide=3Did.g=
3f7268904c5_0_1#slide=3Did.g3f7268904c5_0_1</a><br>[uniker.nl-tutorial]: <a=
 href=3D"https://uniker.nl/introduction/">https://uniker.nl/introduction/</=
a><br>[yocaml]: <a href=3D"https://yocaml.github.io/tutorial/index.html">ht=
tps://yocaml.github.io/tutorial/index.html</a><br>[blog-robur]: <a href=3D"=
https://blog.robur.coop/">https://blog.robur.coop/</a><br>[miou-announce]: =
<a href=3D"https://discuss.ocaml.org/t/ann-miou-a-simple-scheduler-for-ocam=
l-5/12963">https://discuss.ocaml.org/t/ann-miou-a-simple-scheduler-for-ocam=
l-5/12963</a><br>[sans-io]: <a href=3D"https://discuss.ocaml.org/t/on-concu=
rrency-models/15899/13">https://discuss.ocaml.org/t/on-concurrency-models/1=
5899/13</a><br>[sans-io-2]: <a href=3D"https://discuss.ocaml.org/t/why-ocsi=
gen-is-staying-on-lwt-for-now/18318/27">https://discuss.ocaml.org/t/why-ocs=
igen-is-staying-on-lwt-for-now/18318/27</a><br>[digestif]: <a href=3D"https=
://github.com/mirage/digestif">https://github.com/mirage/digestif</a><br>[m=
net]: <a href=3D"https://discuss.ocaml.org/t/ann-mnet-a-new-tcp-ip-stack-fo=
r-unikernels-in-ocaml/17851">https://discuss.ocaml.org/t/ann-mnet-a-new-tcp=
-ip-stack-for-unikernels-in-ocaml/17851</a><br>[mirage-crypto]: <a href=3D"=
https://github.com/mirage/mirage-crypto">https://github.com/mirage/mirage-c=
rypto</a><br>[solo5]: <a href=3D"https://github.com/solo5/solo5">https://gi=
thub.com/solo5/solo5</a><br>[mkernel]: <a href=3D"https://github.com/robur-=
coop/mkernel">https://github.com/robur-coop/mkernel</a><br>[lwt]: <a href=
=3D"https://github.com/ocsigen/lwt">https://github.com/ocsigen/lwt</a><br>[=
tlstunnel]: <a href=3D"https://github.com/robur-coop/tlstunnel">https://git=
hub.com/robur-coop/tlstunnel</a><br>[contruno]: <a href=3D"https://github.c=
om/robur-coop/contruno">https://github.com/robur-coop/contruno</a><br>[<a h=
ref=3D"http://mailingl.st">mailingl.st</a>]: <a href=3D"https://mailingl.st=
">https://mailingl.st</a><br>[ptt]: <a href=3D"https://github.com/robur-coo=
p/ptt">https://github.com/robur-coop/ptt</a><br>[albatross]: <a href=3D"htt=
ps://github.com/robur-coop/albatross">https://github.com/robur-coop/albatro=
ss</a><br>[aussi]: <a href=3D"https://github.com/robur-coop/aussi">https://=
github.com/robur-coop/aussi</a><br>[chaos]: <a href=3D"https://github.com/r=
obur-coop/chaos">https://github.com/robur-coop/chaos</a><br>[unipi]: <a hre=
f=3D"https://github.com/robur-coop/unipi">https://github.com/robur-coop/uni=
pi</a><br>[mnet]: <a href=3D"https://github.com/robur-coop/mnet">https://gi=
thub.com/robur-coop/mnet</a><br>[ocaml-solo5]: <a href=3D"https://github.co=
m/mirage/ocaml-solo5">https://github.com/mirage/ocaml-solo5</a><br>[utcp]: =
<a href=3D"https://github.com/robur-coop/utcp">https://github.com/robur-coo=
p/utcp</a><br>[codept]: <a href=3D"https://github.com/Octachron/codept">htt=
ps://github.com/Octachron/codept</a><br>[mnet-announce]: <a href=3D"https:/=
/discuss.ocaml.org/t/ann-mnet-a-new-tcp-ip-stack-for-unikernels-in-ocaml/17=
851">https://discuss.ocaml.org/t/ann-mnet-a-new-tcp-ip-stack-for-unikernels=
-in-ocaml/17851</a><br>[mhttp]: <a href=3D"https://github.com/robur-coop/mh=
ttp">https://github.com/robur-coop/mhttp</a><br>[mfat]: <a href=3D"https://=
github.com/robur-coop/mfat">https://github.com/robur-coop/mfat</a><br>[vifu=
]: <a href=3D"https://github.com/robur-coop/vif">https://github.com/robur-c=
oop/vif</a><br>[msendmail]: <a href=3D"https://github.com/robur-coop/colomb=
e">https://github.com/robur-coop/colombe</a><br>[dns-primary-git]: <a href=
=3D"https://github.com/robur-coop/dns-primary-git/">https://github.com/robu=
r-coop/dns-primary-git/</a><br>[mnet-secondary]: <a href=3D"https://git.rob=
ur.coop/robur/dns-secondary/">https://git.robur.coop/robur/dns-secondary/</=
a><br>[uniker.nl-repo]: <a href=3D"https://github.com/robur-coop/uniker.nl"=
>https://github.com/robur-coop/uniker.nl</a><br>[orb]: <a href=3D"https://g=
ithub.com/robur-coop/orb">https://github.com/robur-coop/orb</a><br>[grafana=
]: <a href=3D"https://grafana.com/">https://grafana.com/</a><br>[influxdb]:=
 <a href=3D"https://www.influxdata.com/">https://www.influxdata.com/</a><br=
>[telegraf]: <a href=3D"https://www.influxdata.com/time-series-platform/tel=
egraf/">https://www.influxdata.com/time-series-platform/telegraf/</a><br>[o=
camlpro]: <a href=3D"https://ocamlpro.com">https://ocamlpro.com</a><br>[ocf=
]: <a href=3D"https://ocaml-sf.org/">https://ocaml-sf.org/</a><br>[<a href=
=3D"http://robur.coop">robur.coop</a>]: <a href=3D"https://robur.coop/">htt=
ps://robur.coop/</a><br>[ocaml-tls-pr]: <a href=3D"https://github.com/mirle=
ft/ocaml-tls/pull/497">https://github.com/mirleft/ocaml-tls/pull/497</a><br=
>[mirage-crypto-pr]: <a href=3D"https://github.com/mirage/mirage-crypto/pul=
l/214">https://github.com/mirage/mirage-crypto/pull/214</a><br>[ocaml-dns-p=
r]: <a href=3D"https://github.com/mirage/ocaml-dns/pull/351">https://github=
.com/mirage/ocaml-dns/pull/351</a><br>[awa-ssh-pr]: <a href=3D"https://gith=
ub.com/mirage/awa-ssh/pull/85">https://github.com/mirage/awa-ssh/pull/85</a=
><br>[utcp-pr]: <a href=3D"https://github.com/robur-coop/utcp/pull/55">http=
s://github.com/robur-coop/utcp/pull/55</a><br>[absurd]: <a href=3D"https://=
github.com/robur-coop/dnsvizor/blob/83b32596c4a08c080067e1cd36fe5788b90cdd7=
8/unikernel.ml#L610-L631">https://github.com/robur-coop/dnsvizor/blob/83b32=
596c4a08c080067e1cd36fe5788b90cdd78/unikernel.ml#L610-L631</a><br>[caldav]:=
 <a href=3D"https://github.com/robur-coop/caldav">https://github.com/robur-=
coop/caldav</a></div><div><br></div><span class=3D"gmail_signature_prefix">=
-- </span><br><div dir=3D"ltr" class=3D"gmail_signature" data-smartmail=3D"=
gmail_signature">Romain Calascibetta - <a href=3D"http://din.osau.re/" targ=
et=3D"_blank">http://din.osau.re/</a></div></div>

--0000000000008bc04c065e476ba6--


