Web Assembly aka WASM is currently gaining a lot of attention into the container community – for legit reasons! WASM is a web-optimized code format that significantly improve web application performances running on browsers. However, it is gaining more and more attention in the container world lately, because of its sandbox/isolation hence – safety, near-native speed of executions, OS agnostic, and typically extremely small footprints in terms of sizes.
WebAssembly System interface (WASI) project allows writing and compiling code for only one, obviously virtual, but complete operating system (emulating the syscalls with certain adherences). In this way, even if you loaded it on ten different platforms, a binary Wasm module calling a certain WASI function would still get – from the runtime that launched it – a different binary object every time. But since all those objects would interact with that single Wasm module in exactly the same way, it would not matter!
The following are few key strengths of WASM:
- Fast – WASM apps executes near-native speed via the JIT/AOT capabilities of most runtimes. Noticeably faster than even a container startup time.
- Standard – it is widely adopted standard across the communities.
- Secure – WASM runtime is sandboxed and only can access resources that are explicitly allowed.
- Portable – Works across major runtimes for most CPUs (x86, ARM etc.) and most OS like Linux (all POSIX), macOS, Windows etc.
- Polyglot – WASM doesn’t force to any specific language, one can develop the application in any language as they like, and comile it down to WASM.
Let’s see how we can create a OCI image using Docker and run it.
You would need Docker desktop 4.15.0 or later versions for this. Docker WASI is currently on BETA, hence shouldn’t be used in production environment.
We need to activate a beta flag that tell Docker to use containerd for docker images. We can do that from Docker desktop as shown in the picture below:
How Docker runs a WASM image? Docker is leveraging containerd, as it provides the ability to use both OCI-compatible artifacts and containerd shims. Docker uses the OpenSource WasmEdge project to create a containerd shim. This shim extracts the Wasm module from the OCI artifact and runs it using the WasmEdge runtime. Finally, the Wasm runtime enables the use of this new shim.
Creating .net7 console application
For a quick demo, let’s create a simple dotnet application. We can use the dotnet CLI for that. (We need to make sure that NET 7 SDK is installed on the box).
dotnet new console -o SampleApp
Next, we need to compile this application, but we want to produce a WASM output than typically produced DLLs. For that we will need to add a reference to
dotnet add package Wasi.Sdk --prerelease. Let’s use the dotnet CLI again for that:
dotnet add package Wasi.Sdk --prerelease
Now, if we build the application:
We notice that the
bin folder contains a
Build OCI image
In order to build an OCI image for the above application we will use the following
FROM scratch COPY ./SampleApp/bin/debug/net7.0/SampleApp.wasm /SampleApp.wasm ENTRYPOINT [ "SampleApp.wasm" ]
Buidling is trivial, we will use docker CLI from command line:
docker build --platform wasi/wasm -t moimhossain/dotnet-wasi-helloworld:alpha .
We need to provide the
--platform wasi/wasm switch while building.
Running this image also requires specifying the
runtime switch and
docker run --rm --runtime=io.containerd.wasmedge.v1 --platform=wasi/wasm moimhossain/dotnet-wasi-helloworld:alpha
Which produces our desired output, printing Hello world into the console.
We can now push/pull this image like any other Docker images.
If we run docker images to see these images, we see the image is about 3.6MB – that is significantly smaller than any regular container images.
> docker images REPOSITORY TAG IMAGE ID CREATED SIZE moimhossain/dotnet-wasi-helloworld alpha 23a53cc7f78c About an hour ago 3.63MB
As of today, WASM/WASI with Docker is in beta stage and rough on the edges. However, it is easy to recognize the high potential of this development. I am excited and looking forward to observing how things evolve in coming future!
The sample code can be found in GitHub. Thanks for reading.