{"id":15692030,"url":"https://github.com/flavio/hermit-wasm","last_synced_at":"2025-05-07T02:28:46.774Z","repository":{"id":66493611,"uuid":"598689699","full_name":"flavio/hermit-wasm","owner":"flavio","description":"A Unikernel running WebAssembly code","archived":false,"fork":false,"pushed_at":"2023-04-06T08:06:04.000Z","size":952,"stargazers_count":51,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-07T02:28:33.495Z","etag":null,"topics":["rust","unikernel","webassembly"],"latest_commit_sha":null,"homepage":"https://flavio.castelli.me/2023/02/07/building-a-unikernel-that-runs-webassembly---part-1/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flavio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-07T16:08:47.000Z","updated_at":"2025-04-24T02:11:37.000Z","dependencies_parsed_at":"2024-10-24T00:07:53.920Z","dependency_job_id":"7a237f92-9f26-4288-a507-e507f58b22c4","html_url":"https://github.com/flavio/hermit-wasm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flavio%2Fhermit-wasm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flavio%2Fhermit-wasm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flavio%2Fhermit-wasm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flavio%2Fhermit-wasm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flavio","download_url":"https://codeload.github.com/flavio/hermit-wasm/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252801227,"owners_count":21806278,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["rust","unikernel","webassembly"],"created_at":"2024-10-03T18:28:04.126Z","updated_at":"2025-05-07T02:28:46.709Z","avatar_url":"https://github.com/flavio.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hermit-wasm\n\nThis is a POC of a Unikernel designed to run WebAssembly code.\n\nThe project has been done as part of [SUSE Hackweek 2023](https://hackweek.opensuse.org/22/projects/build-a-unikernel-that-runs-webassembly).\nThe code has been written over a week as a learning experiment, hence some\nshortcuts have been taken 😅\n\nThe code has some limitations, that are described below.\n\nFor more details, checkout [this series](https://flavio.castelli.me/2023/02/07/building-a-unikernel-that-runs-webassembly---part-1/) of blog posts.\n\n## Goal of the POC\n\nThe goal of this Hackweek project has been to learn about\n[RustyHermit](https://github.com/hermitcore/rusty-hermit) and figure\nout how hard it would be to create a Unikernel capable of running WebAssembly.\n\nWASI support has not been a goal of this project. I instead targeted a portion\nof the [SpiderLightning project](https://github.com/deislabs/spiderlightning)\nAPIs.\n\nI wanted to be able to show the same WebAssembly module being run both\nby the vanilla [`slight`](https://github.com/deislabs/spiderlightning#getting-started)\nruntime and by this Unikernel.\n\n## Bill of materials\n\n* Unikernel: [RustyHermit](https://github.com/hermitcore/rusty-hermit)\n* WebAssembly runtime: [wasmi](https://crates.io/crates/wasmi) - this runtime has\n  been used because it's written in pure Rust and can be built into the unikernel.\n  Other WebAssembly runtimes are currently assuming the availability of `libc`, hence\n  they cannot be built as a RustyHermit application.\n* [WIT definitions](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md)\n  are taken from the [SpiderLightning project](https://github.com/deislabs/spiderlightning).\n  The WASMI bindings are generated using [this fork](https://github.com/flavio/wit-bindgen/tree/wasmi)\n  of `wit-bindgen` that adds WASMI support.\n\n## Requirements\n\n* [rustup](https://www.rust-lang.org/tools/install)\n* [NASM](https://nasm.us/)\n* [QEMU](https://www.qemu.org/)\n* A Redis server\n\n\u003e **Note:** Currently RustyHermit supports only the x86_64 platform.\n\n## The demo application\n\nThe unikernel will run the SpiderLightning [`http-server-demo`](https://github.com/deislabs/spiderlightning/tree/main/examples/http-server-demo) example.\n\nThis code makes use of two SpiderLightning interfaces:\n  * [KeyValue](https://github.com/deislabs/spiderlightning/blob/main/wit/keyvalue.wit)\n  * [HttpServer](https://github.com/deislabs/spiderlightning/blob/main/wit/http-server.wit)\n\nThe WebAssembly module will start a HTTP server listening on `0.0.0.0:3000` of\nthe unikernel.\n\nThe web server exposes the following routes:\n\n* `GET` `/hello`: this prints back a message\n* `GET` `/foo`: this returns the value of the `my-container:key` key inside of the K/V store\n* `PUT` `/bar`: this sets the value of the `my-container:key` key inside of the K/V store\n\n\u003e **Note:** the code runs a polished version of the example based on [this PR](https://github.com/deislabs/spiderlightning/pull/318).\n\nThe WebAssembly module can be found under the `/wasm` directory. The code has\nthen been compiled targeting the `wasm32-unknown-unknown` Rust target.\n\n## Known limitations\n\nThe POC suffers from the following limitations.\n\n### The WebAssembly module is embedded into the unikernel\n\nI didn't find an easy way to get the `.wasm` file into the running VM.\nRight now the code is embedded at compile time into the unikernel by using the\n[`include_bytes`](https://doc.rust-lang.org/std/macro.include_bytes.html)\nRust macro.\n\n### No TLS support\n\nTLS support via openssl is of course not doable from within the unikernel. \n\nUnfortunately [rustls](https://github.com/rustls/rustls) depends on the\n[`ring`](https://crates.io/crates/ring) crate, which does not compile when\ntargeting RustyHermit.\n\nBecause of that, it's not possible to connect to a TLS terminated Redis instances.\nMoreover, the http server ran by the unikernel is not doing TLS termination.\n\n### RustyHermit scheduler\n\nThe scheduler of RustyHermit seems to have some problems managing the different\nthreads ran by my application (connection pool towards Redis, workers for the\nHTTP server, the `main` that handles the WebAssembly engine).\n\nBecause of that, the response time of the web server are fluctuating a lot.\n\n## Usage\n\n### Build the unikernel\n\nThe unikernel can be built using the following Makefile target:\n\n```\nmake build\n```\n\n### Run the application\n\nThe unikernel must be run using QEMU, the\n[uhyve](https://github.com/hermitcore/uhyve)\nhypervisor cannot be used because it doesn't have network support yet.\n\nThe demo application needs to interact with a Redis server. This can be\nstarted with the help of docker:\n\n```console\ndocker run --name some-redis --net host redis\n```\n\n\u003e **Note:** the container will have access to the network stack of the\n\u003e host. This is convenient because it will make the Redis server\n\u003e reachable by the unikernel at the `10.0.2.2` address.\n\nOnce Redis is running, the unikernel can be run using the following\nMakefile target:\n\n```console\nmake run\n```\n\n\u003e **Note:** this has been tested only on a Linux host.\n\nThis will start QEMU using the [\"user networking (SLIRP)\"](https://wiki.qemu.org/Documentation/Networking#User_Networking_.28SLIRP.29)\nstack. This is slower than using a `tap` device, but it works out of the box\nand doesn't require root privileges.\n\nPort 3000 on the host will be forwarded to port 3000 of the guest. This is the\nport used by the web server of the unikernel.\n\n\u003e **Note:** The unikernel application has different cli flags. These can be set as kernel flags.\nThis is done inside of the `Makefile`, using QEMU `-append` flag.\n\n### Demo\n\n![A screencast of the unikernel application running the Spiderlightning http-server demo](https://flavio.castelli.me/images/unikernel-webassembly/demo.gif \"It's alive!\")\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflavio%2Fhermit-wasm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflavio%2Fhermit-wasm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflavio%2Fhermit-wasm/lists"}