Spinで作ったWasmコンポーネントをDocker Desktopで動かすまで
マイクロサービスフレームワークであるSpinを使って作成したhello-worldサービスを、ゼロからDocker Desktopで動かすまでの記録です。
hello-worldサービスの作成については別の記事で解説しています。そちらをご覧ください。
手順
- Dockerのユーザー登録
- Docker Desktopをダウンロード
- Docker Desktopの起動と確認
- Wasmを起動できるようにWasmワークロードを有効化
- Dockerファイルの作成
- Dockerイメージの作成
- 実行
初めてなので、Dockerのユーザーを登録するところからです。多くの方は、4以降をご覧になれば十分なように思います。
ステップ1:Dockerにユーザー登録
Docker Desktopを使うためにはユーザーをDocker.comで登録しました。
"Sign In"ボタンからGoogleアカウントでサインインして登録しました。
ステップ2:Docker Desktopのダウンロード
アカウント登録後、表示された画面に表示されるDocker Desktopのダウンロードリンクがありました。こちらをクリックするとインストーラーのダウンロードが始まります。
私はM1 macを使っているので、Apple Silicon版をダウンロードしました。
ダウンロードしたdmgファイルを開き、Dockerアイコンをアプリケーションフォルダーにドラッグ&ドロップしてインストール完了です。
ステップ3:Docker Desktopの起動と確認
アプリケーションフォルダー内にあるDockerアイコンをダブルクリックして、Docker Desktopを起動します。起動後、初期設定が始まります。
私は初期設定があることを知らなかったので、早速コマンドラインからdockerコマンドを実行していました。おかげでコマンドが正しく実行できず、15分ほど浪費しました。
コマンドサーチパスの設定
初期設定終了後、シェルの設定をしてコマンドラインからDocker Desktopを利用できるように設定します。私はzshを使っているので、次のようにPATHを設定しました。
export PATH=$PATH:/Applications/Docker.app/Contents/Resources/bin
hello-worldコンテナーを実行
公式に用意されているhello-worldコンテナーを実行して、動作を確認します。
GUIで操作しても良いのでしょうが、私は以下のコマンドでコンテナーを起動しました。
% docker run hello-world
次のように表示されればインストールと、コンテナーの起動は成功です。
Hello from Docker!
This message shows that your installation appears to be working correctly.
(後略)
ステップ4:Wasmワークロードの有効化
標準の構成でインストールしたDockerはWasmを実行できません。実行するためには次の2つを有効にします。
どちらもGUIのSettings画面から設定できます。図1にある歯車アイコンからSettings画面に遷移できます。
図1:Settings(一番右の歯車アイコン)
containerdをWasmワークロードの関係はこちらの記事にある図をご覧いただくと理解の助けとなるように思います。
containerdの有効化
Settings中の"General"に選ぶとcotainerdを有効にするチェックボックスがあります(図2)。これにチェックして、Docker Desktopを再起動すると、containerdが有効になります。
図2:containerdを有効にするチェックボックス
Wasmワークロードの有効化
Settings中の"Features in Development"からWasmワークロードを有効にできます。"Beta"タブをクリックすると表示されるチェックボックスにチェックを入れ、Docker Desktopを再起動します。
図3:Wasmワークロードを有効にするチェックボックス
起動確認
次のようにrust-example-helloコンテナーを実行します。Hello WasmEdge!
と表示されれば、設定と実行は成功です。
% docker run --rm --runtime=io.containerd.wasmtime.v1 --platform=wasi/wasm secondstate/rust-example-hello:latest
Hello WasmEdge!
Hello WasmEdge!
と表示されますが、上記の例ではWasmtimeを処理系に利用しています。
ステップ5:Dockerファイルを作成
hello-worldサービスのディレクトリ構成は、次のようになっています。targetフォルダーはプロジェクトをビルドすることで作成されます。
.
├── Cargo.lock
├── Cargo.toml
├── spin.toml
├── src
│ └── lib.rs
├── target
│ ├── CACHEDIR.TAG
│ ├── debug
│ ├── release
│ └── wasm32-wasi
└── tests
プロジェクトのルートに次の内容でDockerファイルを作成します。
FROM scratch
COPY spin.toml /spin.toml
COPY target/wasm32-wasi/release/hello_world_spin.wasm /target/wasm32-wasi/release/hello_world_spin.wasm
ENTRYPOINT ["/spin.toml"]
上記のDockerファイルを行ごとに解釈すると、次のようになろうかと思います。
- LinuxやWindowを使わない、まっさらなイメージを作成します
- そのイメージにspin.tomlをコピーします
- またhello worldサービスを実装した、
hello_world_sping.wasm
もコピーします - spin.tomlの記述に従ってサービスを起動するよう設定します
ステップ6:Dockerイメージの作成
まずspin build
を実行し、プロジェクトをビルドします。ビルドしないとコピーするWasmファイルが存在せず、イメージの作成に失敗します。
次のようにbuildx
コマンドを実行して、Dockerイメージを作成します。
% docker buildx build --platform wasi/wasm --provenance=false -t docker.io/user_id/hello-world-spin:latest .
docker image ls
を実行して、作成したイメージが表示されることを確認しておきましょう。
% docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
user_id/hello-world-spin latest 28da5b0fd2d8 About an hour ago 2.56MB
secondstate/rust-example-hello latest 0e9edda42141 9 months ago 2.53MB
hello-world latest 53641cd209a4 11 months ago 21kB
ステップ7:コンテナーの実行
下記のように作成したイメージを起動します。
% docker run --runtime=io.containerd.spin.v2 --platform=wasi/wasm -p 3000:80 docker.io/user_id/hello-world-spin:latest
spinで作成したWasmコンポーネントを実行するためには、io.containerd.spin.v2
のランタイムが必要です。インストールをする必要はありませんが、起動時に--runtiime
オプションで指定する必要があります。
また--platform=wasi/wasm
を指定することも必要です。
起動したサービスはhttp://localhost:3000/
でアクセスできます。Webブラウザーでアクセスすると、次のようにHello, Spin
と表示されます。
図4:hello worldサービスにアクセスした結果
まとめと感想
Docker Desktopのインストールから、Spinを使ったWasmコンポーネントの実行までを試しました。containerdとWasmワークロードを有効にする以外は、特に難しい点もないように思います。
Dockerファイルの記述は大変と聞いていて恐怖していましたが、とてもシンプルに記述できたという印象を持ちました。また簡単なサービスだということもありますが、起動も速かったように思います。
Spinには組み込みの実行環境がありますが、合成したWasmコンポーネントを実行するといったシナリオではDocker Desktopを使うのも有用な選択肢であるように感じました。
Discussion