What are WASM, WASI, WASMRuntime and WASM Module?

What are WASM, WASI, WASMRuntime and WASM Module?

Docker recently announced the WASM integration and published a technical preview ever since everyone has been wondering what this means and why there are blogs out there stating that WASM will replace Docker and Kubernetes.

Solomon Heights the founder of Docker tweeted that if WASM and WASI existed in 2008 they wouldn't have had to build Docker since then we've been receiving a lot of questions about what WASM is. what does it have to do with Docker the difference between Docker and WASM and how does the integration work and whether WASM will replace Docker Kubernetes or both?

Welcome to my Blog in this blog, I'm going to try and answer these questions for you but before I begin hit that like button. If you like this blog then do share it with your friends.

What is WASM?

so let's begin so what is WASM? so first it is important to understand exactly what wasm is all on its own so I'll try to explain it in the simplest of simplest terms you've also seen Photoshop right I mean I remember when I first used Photoshop about years ago I had to download this gigabyte sized application then go through this hour-long installation process to finally be able to work with it today what if you could just access Photoshop by going to photoshop.adobe.com right how's this complex application like Photoshop served through the web and run in a browser.

Have you ever wondered how tools like Figma that let you create Advanced wireframes can be run right in your browser without requiring any installation or configuration have you ever seen high-end video games being played in a web browser and wondered how that's possible the web applications that we know today are typically built in HTML CSS and JavaScript.The structure is built using HTML these are designed beautifully using CSS and then made highly interactive by using JavaScript Frameworks like react VJs next.js and whatnot.

Now we can use these to create beautiful web pages and games however they have their limitations you can't use JavaScript alone to create tools like Figma or programs like Photoshop or games as I showed before these are developed in programming languages like C or C++ or rust and are usually run as an executable desktop application so how do you port these complex applications to work online within browsers and that's where web assembly comes in.

WebAssembly

You see traditionally programming languages written in a text or code format cannot be understood by computers so we need to convert a given source code written in a programming language to machine-understandable code we call this a compilation process and refer to the transformed code format a compilation Target.

so web assembly is a new type of compilation Target for languages like C/C++ or rush and is used to run native apps inside browsers it is possible to compile the native language code to what is known as the WASM binary with an online version assembler-like WASM Explorer or WASM fiddle or a tool such as M scripting ultimately the generated web was in binary can be loaded and run inside the browser along with the JavaScript code the web assembly code can be loaded into a web app using JavaScript wherever simply APIs and interact with each other as needed.

Demo On WASM

so now let's see a simple demo to see this in action so first, we're going to see how to compile a simple C program and run it locally and then we will compile the same into a WASM binary and run it inside a web page.

Compile the code With the GCC

so here's a code for a simple hello world program written in C that prints the hello world to the screen right super simply we then use the GCC compiler to compile it into a binary.

we can now see the hello world.exe file here and then when you run this file you see the text hello world printed on the screen simply and straight.

Compile the with emscripten

Now we will compile the same program into a WASM binary and run it inside a browser. so earlier we used GCC to compile this into an executable and now we will use the emscript and tool to compile these Tools in binary.

so following the documentation from the emscript website, we use the EMCC command to compile the hello world.c file and generate an awesome binary a very helpful additional option is the -o option of the EMCC command that generates an HTML file with the supporting JavaScript code required to load the wasn't binary as well isn't that cool?

Now we see the hello world HTML file a hello world JavaScript file and a hello world wasn't a binary file all automatically generated by the EMCC command.

now if you look closely into the Javascript file you'll see that the WASM binary is being loaded as a file into the page and now when we view the HTML file we see that the C code has been executed and prints the expected output on the page.

so we have successfully compiled and at the same C code into a wasn't binary and loaded it within a web page okay so we now understand how WASM helps run complex applications in a browser but is that all wasn't can do if the web assembly does a great job at packaging applications and enabling them to run in a browser while limited to just browsers instead of using it to package and run applications anywhere even outside the web

Now when you compile an application program written in a language like go or Rust, or C++ into a web assembly format you end up with a binary that can be executed on any WASM runtime some of the awesome runtimes are WAGI, web assembly-micro-runtime, wasmtime, WasmEdge, Etc. now web assembly runtime is similar to JVM or V8 engine or even Ruby or python runtimes that you must be familiar with already they help run applications written in those specific languages.

Now the web assembly binary however is platform neutral which means you don't need to worry about the underlying operating system or the processor architecture so the application can run on all major operating systems however the application might need access to system resources such as files and directories environment variables or system time these are bound to the WASM module during startup by what's known as the web assembly system interface.

so you have the operating system and then you have the webassembly system interface which helps the WASM runtime that sits on top of it to access the system resources and then we have the webassembly binaries that run on top of the awesome runtime now furthermore there's no need to worry about running on an Intel or arm processor as the webassembly module runs inside the WASM runtime and executes the WASN binary according to the current host operating system and processor so WASM is the packaged form of the application and its dependencies in a format which can be run on a browser and what is the system interface that makes it possible for WASM binaries to run outside of the browsers and on operating systems.

so WebAssembly enables applications to be packaged into WASM modules and along with WASI allows these applications to run anywhere on any operating system and not just in browsers.

What does it have to do with Docker?

Now that concept might ring a bell if you are familiar with containers and Docker because containers kind of work the same way so let's take a look at that next if you're not yet familiar with Docker let's go over it quickly now if you remember how we executed our C program in our local machine in the earlier demo you'll know it involved several steps.

  1. You download and install a C/C++ compiler compatible with your operating system.

  2. Then you install the necessary libraries and dependencies to work with the GCC compiler.

  3. Then you configure the path variable to use the GCC command from anywhere in your file system.

  4. Then you compile The Source program with the correct GCC command.

  5. Then you run the generated executable.

Let's say you have run this hello world program on your Windows machine you then have to be careful to download and install the C/C++ compiler dependencies and libraries that are windows OS compatible you also have to add the GCC command to the windows path variable and so on now what happens if let's say your teammate wants to run and check your fancy hello world program under Mac system maybe you can then share the C source file with your colleague but they must handle the compiling and running a program on their local machines from the very beginning they need to download and install the compatible C compiler the libraries and dependencies for their Linux or Mac OS not only that if you have used a library within your C program that is incompatible with your colleagues OS version a whole additional nightmare.

This is where you begin saying well it works on my machine to everyone on your team and has historically been one of the biggest headaches in developing building and shipping software so what if you could package your awesome program into one single package along with all the necessary dependencies and libraries and so on in a container that can be up and run by anyone you could provide this container to your colleague who'd up it and be able to run your program along with all the necessary libraries and dependencies perfectly regardless of your colleagues underlying Hardware infrastructure or operating system and that's exactly what Docker does.

Docker is capable of running one or more containers inside a virtual machine on top of its OS and Hardware infrastructure each container can talk to the others as well as the underlying OS and services but runs in a totally isolated environment practically speaking a Docker container is based on a Docker image which is a set of snapshots of a file system layered together to form a single environment if you look back at our example you'll see we can create a Docker image starting from a base image then add the supporting programs and files and utility compilers C/C++ and so on and libraries and that our hello world C program needs and finally the C program should be added and bundled as a single Docker image that can be used to run a Docker container.

let's have a quick look at how to create and run the docker container that can run your hello world program so here we are with our simple C program our goal is to containerize it so we built a Docker image for it for that we create a Docker file the docker file looks like this it is built from the GCC image it is an image that has the C compiler in it in the next few lines we copy the code from the local directory into the image using docker's copy instruction and then we build it using the GCC command with docker's run instruction and then we specify the command to be run when this container is executed using the CMD instruction we then run the docker build command to build the image and then the docker run command to run the application well pretty straightforward.

"there are better ways to do this and some best practices to be followed to separate the build process and the executable version but we're going to keep it super simple uh just for the sake of brevity"

DOCKER VS WASM

Let's compare Docker and WASM now as you probably saw already Docker and wasn't doing a lot of things the same way both can package applications and enable them to be run anywhere.

Docker Architecture

Docker's architecture diagram has first the underlying infrastructure then comes the host operating system and then the docker engine and then we have containers that have the applications libraries dependencies and binaries.

WASM ARCHITECTURE

if you look at the WASM architecture diagram you will see the infrastructure then the host operating system and then the WASI which is the webassembly system interface that's responsible for providing access to system resources for the WASM runtime and then you have the WASM runtime on which the awesome modules run.

Now if you take a closer look at these two you'll notice some distinct differences well Docker wraps the program and its dependencies into a single package that we call as an image and then runs it as a container a Docker container consists of a full file system utility programs binaries and libraries which appear to be a complete operating system for the application itself, in addition, it is key to create your Docker image according to the right system architecture like Intel, AMD, ARM and so on for example if you have a Raspberry Pi OS running Docker then you should create a Docker image for your C program based on your Linux image and compile it for ARM processor architecture otherwise your container will not run properly.

On the other hand webassembly modules and binaries are pre-compiled C/C++, rust or go applications these WASM binaries can be easily executed on a webassembly runtime such a Wasmtime, WasmEdge or WASI as we talked about earlier it does not rely at all on the host operating system or processor architecture because it wasn't binary does not contain any pre-packaged file system or low-level operating system Primitives every directory or environment variable or clock utility and system resource is attached to the WASM module during the runtime facilitated by the webassembly system interface or WASI so the WASM modules are not coupled with the host Os or processor architecture this is a major difference between how Docker and WASM works.

Now from a performance standpoint, there are some significant advantages for WASM when compared to docker WASM binaries start up in milliseconds compared to several seconds for Docker containers as such WASM programs are almost native speed when it comes to Performance the size of a WASM module is just several MBs as it does not have any OS components but a container image may be 10s or 100s of MBs at times if there are too many operating system dependent packages.

since wasm was built for browsers it also runs in a browser of course but one of the key differences is that WASM runs cross-platform whereas Docker has a limitation on specific CPU architectures or operating systems Windows containers don't natively run on Linux and vice versa.

As we have just discussed WASM is a powerful way to compile and run your existing native code written in C/C++, rust or go inside the browser as well as outside of browsers or on top of any WASM runtime while confidently enjoying near-native performance high security and quicker startup times.

Docker enables you to package your application code along with all of its necessary dependencies and ship it as one convenient single image with high portability and runtime isolation features over the past decade we have invested in learning about containers and Docker and also building infrastructure to support Docker containers such as swam and Kubernetes clusters.

Should we Unlearn Docker + Kubernetes?

so do we unlearn all of that and relearn WASM? now do we have to ditch all of the infrastructure and rebuild? new infrastructure for WASN? not necessarily.

what if we took wasam's a high performance high security and quicker startup aspects and combined it with docker's high portability features this is where the docker + WASM integration becomes more valuable than anyone could have ever dreamed with Dockers of WASM support you can run WASM containers parallel to Linux and windows containers which enables you to run your native application code inside a wasm container and share it as a Docker image since Docker makes it easy to build share and reuse your application code and developers are familiar with Docker workflows it is easier to use wasm's high performance and security aspects to build and power up your native applications inside a container environment with quicker startup times.

so how does it work currently you have a Docker engine which is the docker API server that serves all your requests when you run a Docker run the command a container process is created by a container runtime called runC.

so runC is responsible for creating and starting container processes runC exits after the container is created so you need some kind of manager to monitor the container and that's the containerD-shim now one container-shim process is created for each container and it is the container the shim process that initiates the creation of container by the runC and also monitors and manages the container process and it captures its logs and redirects them and helps you attach the container when you run the docker attach command there is a higher level manager that manages all the containers and that is the containerD process.

Now to run WASM containers with Docker we use the WasmEdge runtime this is one of the supported webassembly runtimes that were mentioned before and to integrate the WasnEdge runtime with Docker the folks at Docker worked with the folks at WasnEdge to create a new container-D-shim called containerD-WASM-shim.

DOCKER + WASM Integration

so in the next demo, we'll better understand the power of Docker and WASM integration and note that Docker plus awesome integration is only supported as a beta feature on a special technical preview build of the Docker desktop app as the blog is written also refer to this article published by Docker on while testing it out by yourselves.

so as before we first compiled the C program into a wasm binary for this we run the EMCC command and pass in the path to the source code of the hello world program and the output of a wasm file then we build a Docker image from it the docker file looks like this it's built from scratch means there is no base OS image there's nothing really there then we copy the hello world.WASM binary into the image and the entry point is the binary as well here's the interesting part when we build the docker image now we provide a platform flag to specify that this is a container for WASM the image has now been built successfully and the next we run this using the docker run command and we specify the runtime as io.containerd.wassamedge.v1 and the platform as WASI/WASM32 and followed by the image name that we just built we have now successfully built an image with the WASM binary and run the WASM container.

Conclusion

so what's the future looking like the integration of webassembly and webassembly system interface has the potential to change the way applications are developed and run in the future the integration of WASM and WASI is likely to become more prevalent as more developers adopt these Technologies>

WASI and WASM can be used in conjunction with containerization and orchestration Technologies such as Docker and Kubernetes allowing for more efficient deployment and scaling of web-based applications. while WASM may be used as an alternative to some use cases currently handled by containerization it's unlikely that it will replace these Technologies entirely.

THE END

I hope you enjoyed and got a brief idea of WASM and how it works with Docker if you liked the Blog don't forget to LIke and share it with your friends if you think this is going to be valuable well thank you so much and until next time goodbye

Did you find this article valuable?

Support Sourav Kumar by becoming a sponsor. Any amount is appreciated!