This is a containerd shim for running WebAssembly modules and components using wasmtime.
This shim assumes that the Wasm modules it runs are WASI modules. WASI is a system interface for WebAssembly. If no
entrypoint is specified, the shim will look for a _start
function in the module, which is an initial point of
execution when the module is loaded in the runtime. The _start
function is a WASI convention for the Command modules
(see the distinction between the Command and Reactors).
The shim adds experimental support for running WASI Preview 2 components. If no entrypoint is specified, the shim will assume that the WASI component is a component that uses the wasi:cli/command world.
The wasmtime-shim
supports wasi/http
and can be used to serve requests from a wasi/http
proxy component. The
shim code will try to detect components targeting http/proxy
, and start up a hyper server to listen for incoming
connections, and forward the incoming requests to the WASM component for handling.
This behavior is very similar to what the wasmtime serve
command currently offers. The server task is terminated
upon receiving a terminate or interrupt signal in the container.
This can be very useful on the Wasm-first platforms to allow instance-per-request isolation:
Eeach Wasm instance serves only one HTTP request, and then goes away. This is fantastic for security and bug mitigation: the blast radius of an exploit or guest-runtime bug is only a single request, and can never see the data from other users of the platform or even other requests by the same user. 3
The server can be customized by setting environment variables passed to the RuntimeContext
. These variables include:
WASMTIME_HTTP_PROXY_SOCKET_ADDR
: Defines the socket address to bind to (default: 0.0.0.0:8080).WASMTIME_HTTP_PROXY_BACKLOG
: Defines the maximum number of pending connections in the queue (default: 100).
First, we need to create a Wasm component that uses http/proxy
. You can follow the instructions in this article
to develop a Wasm application using cargo-component
.
Alternatively, you can use the pre-built Hello World example from this repository, which responds with "Hello World" text for GET requests.
- Create an OCI Image
Use oci-tar-builder
to create an OCI image with our http-handler
. Assuming our Wasm component is named wasi-http.wasm
:
cargo run --bin oci-tar-builder -- \
--name wasi-http \
--repo ghcr.io/containerd/runwasi \
--tag latest --module wasi-http.wasm \
-o ./dist/wasi-http-img-oci.tar
- Import the image:
sudo ctr image import --all-platforms ./dist/wasi-http-img-oci.tar
- Run the image:
sudo ctr run --rm --net-host --runtime=io.containerd.wasmtime.v1 \
ghcr.io/containerd/runwasi/wasi-js:latest wasi-http /wasi-http.wasm
- Finally, assuming our handler will respond to
GET
requests at/
, we can usecurl
to send a request:
curl 127.0.0.1:8080
Hello, this is your first wasi:http/proxy world!