2022 年底,Docker 釋出了對 WebAssembly 支援的預覽版本,标志着 WASM 原生時代到來。Docker 通過內建 WasmEdge 運作時支援WASM子產品。Docker 運作時已經準備就緒,那麼如何建構出 WASM 子產品呢?目前支援 Wasm 的語言有很多,這裡我們選擇凹語言來建構 Wasm 鏡像。Docker 官方博文:https://www.docker.com/blog/docker-wasm-technical-preview/
本文的例子代碼:https://gitee.com/wa-lang/wa/tree/dev-wasi/_examples/docker-wasm
1. 凹語言到WASM子產品
凹語言是針對 WebAssembly 設計的語言,也是國内第一個實作純浏覽器内編譯、執行全鍊路的自研靜态類型的編譯型通用程式設計語言。這裡我們再嘗試通過凹語言來構造 Docker 的 Wasm 鏡像。
凹語言是 Go 語言開發的編譯器,是以需要本地先安裝 Go1.17+ 版本環境。然後基于 dev-wasi 分支最新代碼構造出 wa 語言編譯器指令。或者通過以下指令安裝:
go install wa-lang.org/[email protected]
,安裝的指令預設在
$HOME/go/bin
目錄。確定本地
wa
指令行可以使用,可以通過
wa -v
檢視版本。
凹語言環境配置好之後,建立 hello.wa 檔案:
// 版權 @2019 凹語言 作者。保留所有權利。
import "fmt"
import "runtime"
func main {
println("你好,凹語言!", runtime.WAOS)
println(add(40, 2))
fmt.Println(1+1)
}
func add(a: i32, b: i32) => i32 {
return a+b
}
然後在指令行運作程式:
$ wa run hello.wa
你好,凹語言!wasi
42
2
一切正常!
2. 建構 wasm 子產品
通過
wa build hello.wa
指令生成 a.out.wasm 子產品,大小約 3.6KB。然後通過 wasmer 執行:
$ wa build hello.wa
$ wasmer a.out.wasm
你好,凹語言!wasi
42
2
也可以通過 wabt 等輔助工具測試。輸出結果說明一切正常。
3. 配置 Docker wasm 環境
完整的 Docker wasm 官方文檔可以看這裡:https://docs.docker.com/desktop/wasm/ 。按照好最新的 Docker 之後,按照 https://docs.docker.com/desktop/containerd/#enabling-the-containerd-image-store-feature 的提示(Settings頁面的Experimental菜單),打開“Use containerd for pulling and storing images”特性。
4. 建構 Docker wasm 鏡像
在目前目錄建立 Dockerfile,内容如下:
FROM scratch
ADD a.out.wasm /hello.wasm
ENTRYPOINT ["hello.wasm"]
執行以下指令建立 Docker wasm 鏡像:
$ docker buildx build --platform wasi/wasm32 -t wa-lang/hello-world .
[+] Building 5.2s (8/8) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 191B 0.0s
=> [internal] load .dockerignore 0.2s
=> => transferring context: 2B 0.0s
=> resolve image config for docker.io/docker/dockerfile:13.9s
=> [auth] docker/dockerfile:pull token for registry-1.docker.io 0.0s
=> CACHED docker-image://docker.io/docker/dockerfile:[email protected]:d2... 0.2s
=> => resolve docker.io/docker/dockerfile:[email protected]:d2d74ff22a0e4... 0.2s
=> [internal] load build context 0.1s
=> => transferring context: 3.71kB 0.0s
=> [1/1] ADD a.out.wasm /hello.wasm 0.1s
=> exporting to image 0.3s
=> => exporting layers 0.1s
=> => exporting manifest sha256:47686ab02b26ea0ed51... 0.0s
=> => exporting config sha256:95cf2c26b4bcf8ae39c99... 0.0s
=> => naming to docker.io/wa-lang/hello-world:latest 0.0s
=> => unpacking to docker.io/wa-lang/hello-world:latest 0.1s
$
需要注意的是這裡使用的是
buildx
子指令,并且輸出的是
wasi/wasm32
目标平台。完成後可以通過
docker image list
檢視新生成的鏡像。
5. 執行 Docker wasm 鏡像
通過以下指令執行 Docker wasm 鏡像:
$ docker run --rm \
--name=wasm-hello \
--runtime=io.containerd.wasmedge.v1 \
--platform=wasi/wasm32 \
docker.io/wa-lang/hello-world:latest
你好,凹語言!wasi
42
2
首先要選擇
io.containerd.wasmedge.v1
運作時,同時也u有指定
wasi/wasm32
平台類型。如果一切順利就可以看到輸出結果了。
6. 總結展望
Docker 的創始人曾經說過,如果 Wasm 技術早點出現那麼就不會有 Docker 這個技術。而目前 Docker 對 wasm 的支援也說明了其本身的應用場景。其實 Wasm 雖然誕生于 Web 領域,但是在 Web 之外也有相當廣泛的應用場景。不過目前主流程式設計語言都不是原生為 Wasm 設計的,我們希望通過新的凹語言為 Wasm 提供更好的支援和體驗。同時希望未來凹語言可以通過 Wasm 服務更多的場景。