There are number of tools claiming to support proxy-wasm module distribution as an OCI container image. However, the standard seems to be changing rapidly and most of the tools I found simply do not work as advertised or are proprietary and expect you’ll be publishing your images to a public or proprietary registry. Luckily, modern versions of Docker can be used to build and publish WASM OCI images without any custom tooling.

Anatomy of a Proxy Wasm OCI Image

The OCI spec defines a standard format for container images. This format is used by Docker, but now supports WASM modules, Helm charts, and other types of artifacts.

Unlike Docker images, a wasm-proxy OCI image should have a single layer containing the compiled WASM module and nothing else.

Building from scratch

The Dockerfile specification supports this by replacing the FROM someimage:version directive with FROM scratch. This constructs an empty image with no layers and no base image.

From there, it’s simply a matter of copying the compiled WASM module into the image and publishing it to your registry of choice.

COPY ./target/wasm32-wasi/release/my_plugin.wasm ./plugin.wasm

The full Dockerfile looks like:

FROM scratch
LABEL org.opencontainers.image.title my-plugin
COPY ./target/wasm32-wasi/release/my_plugin.wasm ./plugin.wasm

The build command, assuming you’re using Rust (and why wouldn’t you be!) is:

$ cargo build --target wasm32-wasi --release
$ docker build -t my-registry/my-plugin:version .
$ docker push my-registry/my-plugin:version

* Note: including a LABEL directive is not currently required, but it is recommended

Optional Multi-stage builds

If your prefer to use Docker multi-stage builds rather than compile your WASM module directly on your CI infrastructure, you can use a multi-stage build instead. This allows you to compile your WASM module in a temporary container and copy the compiled code to the scratch image.

FROM rust:1.70-bullseye as builder

RUN rustup target add wasm32-wasi

WORKDIR /usr/src/wasm-plugin
ADD Cargo.toml .
ADD Cargo.lock .
ADD src src

RUN cargo build --target wasm32-wasi --release

FROM scratch
LABEL org.opencontainers.image.title my-plugin
COPY --from=builder /usr/src/wasm-plugin/target/wasm32-wasi/release/my_plugin.wasm ./plugin.wasm