🦀

5 分で WebAssembly + Docker = Hello World

2023/02/06に公開

テーマ: Rust と Docker Desktop で WebAssembly な Hello World アプリ を作る

Zenn をご覧な方であれば、WebAssembly (WASM) というキーワードを耳にしたり目にしたりしたことがある方は多いのではないでしょうか。昨年くらいから急に注目を集めはじめ、次世代のクラウドネイティブ技術とも言われ始めているテクノロジーです。

簡単に WebAssembly を説明すると次のように言えるでしょう。

また、WebAssembly (WASM) はブラウザ以外の環境で実行することも可能です。そのために必要となる仕様が、WebAssembly System Interface (WASI) です。WASI は、ホストのファイルやネットワークなどの資源に安全にアクセスさせるための仕様です。これは、WASM モジュールがホスト環境と対話するための標準化されたシステムコールのセットを提供します。この WASI により、WASM のコードをバックエンドで実行することができるようになります。

Rust と WebAssembly パッケージのインストール

5 分で WebAssembly アプリを作ると第していますが、ほぼほとんど全ての時間は準備をする時間です。
使用するものは、Rust と Docker Desktop です。それらの導入や構成の手順を紹介しながら、WASM バイナリを作成していきます。

Rust のインストール

まず、プログラミング言語Rust をコンピュータにインストールする必要があります。Rust は、公式サイトの説明に従ってインストールすることができます。

それでは、以下の curl コマンドでインストールを行いましょう。

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

そのコマンドにより、パッケージマネージャの Cargo と一緒に Rust がインストールされます。インストールしたら、以下のコマンドを実行して、$PATH 変数を更新します。

source "$HOME/.cargo/env"

Rust がインストールされたことを確認しておきましょう。

rustc --version

今日インストールしたなら、バージョンは 1.67.0 ですね。

rustc 1.67.0 (fc594f156 2023-01-24)

Rust のプロジェクト作成

パッケージマネージャ cargo を使用して、Rust のプロジェクトを作成します。以下のコマンドを実行します。

cargo new wasm-docker-helloworld

これにより、Rust ライブラリの基本構造を持つ "wasm-docker-helloworld" という新しいディレクトリが作成されます。
このプロジェクトの src/lib.rs にはすでに次の Hello World のコードが入っています。

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

これをビルドしてみます。以下のコマンドを実行します。

cargo build

これでバイナリファイルが作成され、target/debug の下に置かれます。これを直接実行することができます。

./target/debug/wasm-docker-helloworld

WebAssembly バイナリの作成

さて、WebAssembly ランタイム用にプロジェクトをビルドするために、新しいターゲットを追加する必要があります。

rustup target add wasm32-wasi

そして、このターゲットをビルドコマンドで使用することができます。

cargo build --target wasm32-wasi

このコマンドにより、WebAssembly バイナリを作成し、target/wasm32-wasi の下に配置します。

target
├── CACHEDIR.TAG
├── debug
│   ├── build
│   ├── deps
│   ├── examples
│   ├── wasm-docker-helloworld
│   ├── wasm-docker-helloworld.d
│   └── incremental
└── wasm32-wasi
    ├── CACHEDIR.TAG
    └── debug
        ├── build
        ├── deps
        ├── examples
        ├── wasm-docker-helloworld.d
        ├── wasm-docker-helloworld.wasm
        └── incremental

Docker イメージの作成

なお、これは現在プレビュー機能であり、Docker Desktop でのみ利用可能です。Docker Desktop で WebAssembly コンテナをビルドまたは実行できるようにするには、まず設定から containerd pulling and storing feature を有効にする必要があります。

まず、以下の内容でDockerfileを作成します。

# syntax=docker/dockerfile:1
FROM scratch
COPY ./target/wasm32-wasi/debug/hello-wasm.wasm /hello.wasm
ENTRYPOINT [ "hello.wasm" ]

次に、以下のコマンドでビルドします。

docker buildx build --platform wasi/wasm32 -t hello-wasm .

Dockerイメージを確認してみましょう。

docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
hello-wasm   latest    779ebd5f5914   56 seconds ago   519kB

イメージが作成され、サイズは半分のメガバイトになります。次のコマンドで実行してみましょう。

docker run --runtime=io.containerd.wasmedge.v1 --platform=wasi/wasm32 hello-wasm

次のように表示されます。

Hello, world!

まとめ

WebAssembly はネイティブに近いパフォーマンスを提供し、プラットフォーム非依存です。
Docker Desktop には WasmEdge ランタイムが付属しており、WebAssembly アプリを Docker コンテナにラップし Docker Compose で非 WASM コンテナと一緒に実行することも可能になります。

GitHubで編集を提案

Discussion