In 2019, Docker co-founder Solomon Hykes famously tweeted, "If WASM+WASI existed in 2008, we wouldn't have needed to create Docker." Ever since, the Docker vs WebAssembly performance comparison debate has been relentless. Many prematurely declared that "Wasm will kill Docker." However, after years of running both in production, the truth is clear: WebAssembly won’t kill Docker, but it will absolutely dominate the Serverless and API landscape.
To run a simple API today, we typically pack an entire mini-Linux OS into a Docker container. This inherently causes bloat. WebAssembly (Wasm), on the other hand, requires zero OS. Your code runs directly within a highly secure sandbox at the hardware level. In this webassembly on bare metal server tutorial, we will explore how to ditch container bloat and build lightning-fast APIs on your own Ubuntu server.
Wasm and Spin: The Engine and the Steering Wheel
WebAssembly is an ultra-fast, OS-agnostic binary format. Think of Wasm as a powerful "car engine." But you can't just hold an engine in your hands and drive; you need a steering wheel and pedals. That’s where Fermyon Spin comes in.
Much like docker run controls containers, Fermyon Spin acts as the ultimate server-side webassembly spin framework guide, allowing developers to effortlessly build, run, and scale Wasm microservices.
The 3 Core Advantages of Wasm on Bare Metal
Stop paying exorbitant bills for AWS Lambda and build your own serverless platform that is 100x faster on a Dedicated Bare Metal Server. Here is why this architecture is a game-changer:
- Zero Cold Starts (Microsecond Speed): Starting a Docker container takes seconds. Running Wasm via Fermyon Spin takes mere microseconds. This creates a true zero cold start environment for microservices on Ubuntu infrastructure.
- Extreme Server Density: While a 128-core bare metal server might comfortably run 1,000 Docker containers, that exact same server can host 10,000 to 50,000 Wasm microservices. When analyzing wasmtime vs docker memory usage, Docker consumes ~100MB per idle instance, whereas Wasm requires just ~2MB.
- Ironclad Sandbox (Security): A vulnerability in a Docker container can lead to a kernel escape. Wasm is designed with a strict "Default Deny-All" capability-based security model, ensuring unparalleled isolation.
Hidden Gems in Production (What Competitors Miss)
Most tutorials assume Wasm only runs on cloud edge platforms like Cloudflare or Fastly. Here are the real production secrets for your own infrastructure:
- The
containerd-wasm-shim(Peaceful Coexistence): You don't have to rip out Docker to use Wasm. By implementingRuntimeClass: wasmtime-spin(or your specific shim name) in your Kubernetes cluster, Docker containers and Wasm modules can run side-by-side on the same node. Run your heavy PostgreSQL databases in Docker, and your lightning-fast API gateways in Wasm.
(Note: Never use justwasmtimeas the RuntimeClass, as it is merely the engine. You must specify the exact shim likewasmtime-spinto avoid CrashLoopBackOff errors). - IoT OTA Updates with Zero Downtime: Pushing a Docker image update to an IoT device requires ~100MB of bandwidth and causes downtime. A Wasm binary update requires just ~400KB and hot-swaps in 8 seconds with absolute zero downtime.
Critical Infrastructure & Security Warnings
When running Wasm on Bare Metal, you must strictly adhere to the following security protocols:
Step-by-Step Guide: How to Install Fermyon Spin on Ubuntu 24.04
Let's dive into how to run wasm without docker and build serverless api with wasm and rust on a clean Ubuntu 24.04 server.
Step 1: Install Rust and the Wasm Target
Rust is the premier language for compiling WebAssembly microservices. Install Rust and add the standard WASI compilation target (Fermyon Spin will automatically handle the Component Model translation under the hood).
# Install Rust toolchain
curl --proto '=https' --tlsv1.2 -sSf https://rustup.rs | sh
source $HOME/.cargo/env
# Add the WebAssembly (WASI) target layer
rustup target add wasm32-wasi Step 2: Install the Fermyon Spin CLI
Fetch and install the Spin CLI directly onto your Ubuntu machine.
# Download and install Spin
curl -fsSL https://developer.fermyon.com/downloads/install.sh | bash
sudo mv ./spin /usr/local/bin/spin
# Verify the installation
spin --version Step 3: Scaffold a New Serverless Wasm Project
To effectively deploy fermyon spin on dedicated server, use Spin's built-in templates to scaffold a new API project.
spin new http-rust my-wasm-api --accept-defaults
cd my-wasm-api This generates a standard spin.toml (manifest file) and src/lib.rs (your Rust handler).
Step 4: Build and Execute the Wasm API
Compile your code into a .wasm binary and seamlessly run microservices with wasm on linux in a single command. While local testing defaults to 127.0.0.1, a true Bare Metal production deployment requires binding to all network interfaces (0.0.0.0).
# Compile and start the listener for local testing
spin build --up
# For Production Bare Metal: Expose the API to the public internet
spin build --up --listen 0.0.0.0:80 Your Bare Metal server is now running a sub-millisecond API exposed to the world at http://<your-server-ip>, executing with absolute zero container overhead!