Wasm with Dockerを試す

2022.11.15

Introduction

先日、DockerがWasmをサポートするテクニカルプレビューを発表しました。
これにより、dockerコマンドでWasmを実行したり、
WasmイメージをDocker Hubにpushして
使うことが可能になります。

本稿ではシンプルなWasmプログラムをRustで作成し、
docker imageをDocker Hubへpushして実行してみます。

Environment

  • macOS : 13.0.1
  • Rust : 1.65.0
  • Docker : 20.10.18

Dockerはここにあるリンクから、
対象のプラットフォームにあったものをインストールしておきましょう。
また、Docker Hubへimageのpushもするので、
Docker IDも必要です。

Setup

正しくDockerがインストールしてあるかチェック。

% docker --version
Docker version 20.10.18, build b40c2f6b5d

Rustも必要なので、インストールします。
そして、RustがWasmバイナリにコンパイルできるようにターゲットを追加します。

% rustup target add wasm32-wasi

Try

セットアップできたので、RustプログラムをWasmにコンパイルしてDockerで動かしてみます。

まずはCargoをつかってRustプロジェクトを作成します。
動かすプログラムはなんでもいいです。
今回はデフォルトのまま。

% cargo new hello-wasm-container && hello-wasm-container
  Created binary (application) `hello-wasm-container` package

ターゲット指定してビルドします。
ビルドが成功すると、releaseディレクトリ下にwasmファイルができてます。

% cargo build --target wasm32-wasi --release
   Compiling hello-wasm-container v0.1.0 (/・・・/wasm-rust/hello-wasm-container)
    Finished release [optimized] target(s) in 0.69s


% ls target/wasm32-wasi/release
build  deps  examples  hello-wasm-container.d  hello-wasm-container.wasm  incremental

このアプリをOCI imageにビルドします。
Dockerfileを↓のシンプルな内容で記述します。

# /path/your/hello-wasm-container/Dockerfile
FROM scratch
COPY ./target/wasm32-wasi/release/hello-wasm-container.wasm /hello-wasm-container.wasm
ENTRYPOINT [ "hello-wasm-container.wasm" ]

OCI Imageの対象OSをwasiに指定してビルドします。

% docker buildx build --platform wasi/wasm32 -t hello-wasm-container:0.1 .

imageが作成できてます。

% docker image ls
REPOSITORY                     TAG       IMAGE ID       CREATED          SIZE
hello-wasm-container           0.1       xxxxxxxxxxxx   21 seconds ago   501kB

OCI imageが作成できたら、Docker Hubにプッシュしましょう。
Docker Hub用にタグ付けします。

% docker image tag hello-wasm-container:0.1 <Docker ID>/hello-wasm-container:0.1

pushしたら、なんかエラーでた。

% docker image push <Docker ID>/hello-wasm-container:0.1
server message: insufficient_scope: authorization failed

ドキュメントみたらdocker loginしろとあるので、
いったんログアウトしてから再度ログイン。

% docker logout
% docker login

今度はpush成功しました。

docker image push <Docker ID>/hello-wasm-container:0.1
・・・
0.1: digest: sha256:xxxxxxxxx, size: 526

DockerでWasmアプリ実行

docker container runコマンドでpushしたOCI imageを実行してみます。

% docker container run --rm --name=mydockerwasm \
--runtime=io.containerd.wasmedge.v1 \
--platform=wasi/wasm32 \
<Docker ID>/hello-wasm-container:0.1

Hello, world!

Wasmプログラムが実行されました。

WasmEdgeランタイムを使用するために
runtimeのio.containerd.wasmedge.v1を指定します。
これによりDockerfileのENTRYPOINTで指定したwasmを実行します。

Summary

今回はDocker+Wasmのプレビュー版を使って、
DockerでWasmモジュールを動かしてみました。
高速・軽量・安全のWasmは、今後さらに重要になってきそうです。

References