Exploring Docker Hub’s WASM technical preview

B Shyam Sundar
4 min readDec 4, 2022

--

WASM as an alternative to linux containers

Docker + WASM

Introduction

Docker has introduced WASM support which can run along side your containers. In this article, let us explore about how we can use this, and its implications.

To know about Docker, the platform, please refer to the following link:

Docker overview | Docker Documentation

WASM originally was conceived to bring native performance to the browsers. However, it has since grown and has shown promise outside the browser as well.

For details about what is WASM please read my earlier blog series on this:

WASM + WASI + WAGI + Web Assembly Modules in Rust

Prerequisites

To work with WASM in docker you would require docker desktop preview. If you have an existing version of docker desktop, please uninstall that and install the docker desktop tech preview using any of the following links relevant to your desktop OS:

Rust programming language

Running the sample program

Once the docker desktop has been installed. We will first run the command provided by docker itself.

docker run -dp 8080:8080 \
--name=wasm-example \
--runtime=io.containerd.wasmedge.v1 \
--platform=wasi/wasm32 \
michaelirwin244/wasm-example

The parameters runtime=io.containerd.wasmedge.v1 and platform=wasi/wasm32 specifies to the docker engine that this particular container’s runtime must be the wasm containerd shim. In this case the shim is wasmedge. From the wasmedge website:

WasmEdge is a lightweight, high-performance, and extensible WebAssembly runtime for cloud native, edge, and decentralized applications.

It powers serverless apps, embedded functions, microservices, smart contracts, and IoT devices.

In general, there are other WASM runtimes available as well. In this case wasmedge is used. In the future we should be able to use other wasm runtimes.

Once you finish running this command, you should run

docker images

You should see

docker images

Here, we can see one the of the first key advantages that WASM brings to the table. SIZE of 1.57MB. This is key advantage over regular linux container images which are typically much bigger in size.

Next now let use check what is running, by executing

docker ps
docker ps

Running the following would confirm that the web assembly is working as intended.

curl localhost:8080
curl result

Sending a POST request:

curl -X POST \
-H "Content-Type: application/json" \
-d '{"hello":"world"}' \
localhost:8080/echo
curl POST result

Now that we are certain it is working, let us inspect the code for this example code to understand how we can build one ourselves.

Creating our own WASM module

This WASM module which we saw is running a loop and is listening for requests. Typically that is how Microservices would be built.

For our understanding, let us create our own simple WASM module.

First configure rust for WASM with

rustup target add wasm32-wasi

Then, create your own rust project:

cargo new wasm-docker

Once the new project is created, inspect the main.rs file:

fn main() {
println!("Hello, world!");
}

This should be enough for our purposes now. Now build the application

cargo build --target wasm32-wasi --release

Once, the build is complete the output will be available as the ./target/wasm32-wasi/release/wasm-docker.wasm

Creating a WASM image

Using the built wasm file we now build a OCI image from this WASM app. Create a Dockerfile and copy the following contents to it.

FROM scratch
COPY ./target/wasm32-wasi/release/wasm-docker.wasm /wasm-docker.wasm
ENTRYPOINT [ "wasm-docker.wasm" ]

Now build the image by running

 docker buildx build --platform wasi/wasm -t wasm-docker:0.1 .

The key here is the platform argument. We are targeting this image to be built for WASI architecture rather than linux.

If all went well, when you run

docker images

You would be seeing the above image available.

Excellent, now it is time to

Run your WASM image

To run your docker image, issue the following command

docker container run --rm --runtime=io.containerd.wasmedge.v1 --platform=wasi/wasm32 wasm-docker:0.1

You should be seeing:

output

Success! The Hello, world! is printed from our program.

Implications

Though, this example is a simple one. What this would imply that we would able to build web services and deploy it to our existing tech stack.

If the same WASM module is deployed to a kubernetes cluster, that would mean we would be able to run our services at scale. WASM is making a lot of in-roads, in a few years I expect WASM to become a staple part of cloud native development.

If you liked this article, please clap and share. Until next time.

References

Docker+Wasm (Beta) | Docker Documentation

--

--