WASMアプリをIBM Cloud Code Engineにデプロイしてみた
はじめに
本記事はサクッとRustプロジェクトをWASMにコンパイルしてコンテナで動かしてみたの続編となります。
今回は通常の Linux コンテナ内で WebAssembly runtime を起動し、.wasm を実行します。
前回(Rancher Desktop の Wasm ランタイム上で FROM scratch の超軽量イメージを動かす)から一歩進めて、同じ Wasm アプリを Code Engine にデプロイしてみたいと思います。
必要ツール
- Rust 1.85 以上(Edition 2024 対応)
- rustup 利用を前提
- wasm32-wasip1
-
% rustup target list --installed
で確認可能
-
- Spin
- Docker
- IBM Cloud CLI + Code Engine プラグイン
手順
spin new
でRustプロジェクトを作成します。今回はシンプルなAPIを作成するためhttp-rust
を選択します。
1. % spin new
Pick a template to start your application with:
http-c (HTTP request handler using C and the Zig toolchain)
http-empty (HTTP application with no components)
http-go (HTTP request handler using (Tiny)Go)
http-grain (HTTP request handler using Grain)
http-js (HTTP request handler using JavaScript)
http-php (HTTP request handler using PHP)
http-py (HTTP request handler using Python)
> http-rust (HTTP request handler using Rust)
http-ts (HTTP request handler using TypeScript)
http-zig (HTTP request handler using Zig)
redirect (Redirects a HTTP route)
redis-go (Redis message handler using (Tiny)Go)
redis-js (Redis message handler using JavaScript)
redis-rust (Redis message handler using Rust)
redis-ts (Redis message handler using TypeScript)
static-fileserver (Serves static files from an asset directory)
プロジェクト名は今回はhello-wasm-ce
としました、あとはEnterでOKです。
.wasm
のビルド(ローカル)
2. rustup target add wasm32-wasip1
cargo build --target wasm32-wasip1 --release
# → ./target/wasm32-wasip1/release/hello_wasm_ce.wasm が生成される想定
.wasm
はアーキ非依存!
M1 Mac 上でビルドしたものを、そのまま x86_64 コンテナ内で実行できます。ターゲット名は wasm32-wasip1 に統一しましょう。
3. spin.tomlの更新
spin.toml
を以下のように更新
/// 省略
[component.hello-wasm-ce]
source = "hello_wasm_ce.wasm" # コンテナ内にコピーする wasm の“ファイル名”に合わせる
///
spin.toml の書式(manifest v2)は公式リファレンス参照。 source は“コンテナ内の相対パス” で指定します。
4. Dockerfileの追加
すでにローカルで .wasm を作ってある前提です。Spin バイナリだけ入れて実行します。
生成AIにDockerfile作ってもらいました。
Code Engineは現在WASMをサポートしていないため、通常のLinuxコンテナ内でspin up
してWASMアプリを動かします。
FROM debian:bookworm-slim
ARG SPIN_VERSION=2.4.0
ARG SPIN_ARCH=linux-amd64
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl \
&& rm -rf /var/lib/apt/lists/*
# Install Fermyon Spin CLI (Linux/amd64)
RUN curl -fsSL -o /tmp/spin.tgz \
https://github.com/fermyon/spin/releases/download/v${SPIN_VERSION}/spin-v${SPIN_VERSION}-${SPIN_ARCH}.tar.gz \
&& tar -xzf /tmp/spin.tgz -C /usr/local/bin spin \
&& rm -f /tmp/spin.tgz \
&& /usr/local/bin/spin --version
RUN useradd -m app
USER app
WORKDIR /app
# ※ spin.toml の component.source が "hello_wasm_ce.wasm" であることを想定
COPY spin.toml /app/spin.toml
COPY target/wasm32-wasip1/release/hello_wasm_ce.wasm /app/hello_wasm_ce.wasm
ENV RUST_LOG=info
EXPOSE 8080
# Code Engine provides $PORT (default 8080). Bind Spin to it.
CMD ["/bin/sh","-lc","exec /usr/local/bin/spin up --from /app/spin.toml --listen 0.0.0.0:${PORT:-8080}"]
5. イメージのビルド & プッシュ
IBM Cloud, Container Registoryにログイン
% ibmcloud login -a https://cloud.ibm.com --sso
% ibmcloud cr login
Buildします。
us.icr.ioはリージョンに合わせてください。RESOURCE_GROUP
は環境に合わせ、PACKAGE
やPROJECT
, VERSION
は任意です。
% docker build . \
--platform linux/amd64 \
-t ${PACKAGE}:latest
% docker tag ${PACKAGE}:latest ${PACKAGE}:${VERSION}
% docker tag ${PACKAGE}:${VERSION} \
us.icr.io/${RESOURCE_GROUP}/${PROJECT}/be:${VERSION}
Pushします。
% docker push us.icr.io/${RESOURCE_GROUP}/${PROJECT}/be:${VERSION}
以下参照です
6. 動作確認
うまく動きました!
% curl https://hoge.us-south.codeengine.appdomain.cloud/
Hello, Fermyon
7. WASMにするメリット
-
強力なサンドボックス(WASIの能力ベース権限)
ファイルやネットワーク等は「明示的に与えた権限」だけに限定。モジュールはホストOSや他プロセスから隔離され、万一のバグでも被害半径を絞れます。これは“Linuxコンテナの内側”でも効き続ける価値です。 -
起動の速さ(モジュール初期化が軽い)
コンテナ自体は必要でも、アプリロジックは Wasm モジュールのロード・実行。JVM/Python等の重量ランタイムより初動が軽くなりやすく、Code Engine のスケールtoゼロ(アイドル時ゼロ→需要で起動)と相性が良いです。低レイテンシが必須なら min-scale や scale-down delay を調整しつつ、Wasm の軽さでコールドスタート影響を抑えやすい。 -
ポータビリティ & 将来性(アーキ非依存+コンポーネントモデル)
.wasm は OS/CPU を跨いで再配布でき、他の Wasm ホスト(Fermyon Cloud など)にも移しやすい。 -
サプライチェーンの単純化
実アプリは .wasm だけ更新、ランタイム層(ベースOS+Spin/Wasmtime)は固定化しやすい。結果として更新差分(push/pull)も小さく、脆弱性対応も層を分けて管理できます。
まとめ
WASMエコシステムはまだまだ発展途上ですが、期待できる恩恵も大きいです!
引き続きキャッチアップしていきます📦
Discussion