Runtimes Host WASI: wasmtime, wazero & Spin
Um binário wasip1/wasm é apenas metade da história.
Busque em todas as páginas da documentação
Um binário wasip1/wasm é apenas metade da história.
Algo deve instanciar o módulo, satisfazer importações WASI e, opcionalmente, mapear gatilhos HTTP ou capacidades do sistema de arquivos.
wasmtime, wazero e Spin são os três hosts que as equipes Go procuram primeiro - ferramentas CLI, incorporação in-process e HTTP na edge, respectivamente.
Compile Go com GOOS=wasip1 GOARCH=wasm, depois execute o artefato através de um host que fala WASI Preview 1.
wasmtime se destaca no desenvolvimento local e scripting.
wazero se encaixa em microsserviços Go que carregam plugins in-process.
Spin empacota manipuladores HTTP opinativos para implantações de edge no estilo Fermyon.
Cada host difere em como concede capacidades de sistema de arquivos, ambiente e rede.
Cartão de receita de referência rápida - pronto para copiar e colar.
# Loop de desenvolvimento
GOOS=wasip1 GOARCH=wasm go build -o app.wasm .
wasmtime run --env APP_ENV=dev --dir .::/work app.wasm// Incorporar com wazero (host Go)
wasi_snapshot_preview1.MustInstantiate(ctx, runtime)
mod, _ := runtime.Instantiate(ctx, wasmBytes)
_, _ = mod.ExportedFunction("_start").Call(ctx)Quando usar isso:
Convidado (guest/main.go):
package main
import (
"fmt"
"os"
)
func main() {
name, _ := os.Hostname()
fmt.Println("hostname:", name)
fmt.Println("env:", os.Getenv("GREETING"))
}Compilar:
GOOS=wasip1 GOARCH=wasm go build -o guest.wasm ./guestwasmtime:
wasmtime run --env GREETING=hello --dir .::/ guest.wasmHost wazero (host/main.go):
package main
import (
"context"
"os"
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
)
func main() {
ctx := context.Background()
r := wazero.NewRuntime(ctx)
defer r.Close(ctx)
wasi_snapshot_preview1.MustInstantiate(ctx, r)
cfg := wazero.NewModuleConfig().
WithEnv("GREETING", "hello from wazero").
WithFSConfig(wazero.NewFSConfig().WithDirMount(".", "/"))
wasm, _ := os.ReadFile("guest.wasm")
mod, _ := r.InstantiateWithConfig(ctx, wasm, cfg)
defer mod.Close(ctx)
_, _ = mod.ExportedFunction("_start").Call(ctx)
}Spin (spin.toml trecho + compilação):
spin_manifest_version = 2
[application]
name = "go-guest"
version = "0.1.0"
[[trigger.http]]
route = "/..."
component = "guest"
[component.guest]
source = "guest.wasm"
[component.guest.trigger]
route = "/"spin build
spin upO que isso demonstra:
_start (ou wrappers main exportados) é executado após a instanciação.| Runtime | Linguagem | cgo | Uso Típico | História HTTP |
|---|---|---|---|---|
| wasmtime | Núcleo Rust, bindings multilíngues | Opcional em bindings | CLI, plataformas poliglota | Via propostas WASI HTTP / incorporar customizado |
| wazero | Go Puro | Não | Serviços Go incorporando plugins | Você monta net/http em torno das chamadas do convidado |
| Spin | Runtime Rust + linguagens convidadas Go/outras | Não para convidados Go | Microsserviços de edge | Gatilhos HTTP de primeira classe |
Call limitam o tempo de CPU; combine com APIs de medição de combustível quando disponíveis.// ABI de plugin estreita: o convidado lê JSON de stdin, escreve JSON de stdout.
// O host envolve Call com buffers via substituições de stdin/stdout do ModuleConfig.Instanciação WASI ausente no wazero - Esquecer wasi_snapshot_preview1.MustInstantiate gera erros de importação obscuros. Correção: sempre registre WASI antes dos módulos convidados.
Assumindo o diretório de trabalho - Convidados veem apenas caminhos pré-abertos, não o CWD do host. Correção: monte . explicitamente em / ou /work.
Expectativas de rede Spin - Nem todo servidor Go net/http compila para um componente Spin sem adaptação. Correção: siga os padrões do SDK Go do Spin para manipuladores HTTP.
Descompasso de versão do wasmtime - Hosts mais antigos não possuem snapshots WASI mais recentes. Correção: fixe o wasmtime em CI para corresponder à produção.
Re-instanciar por solicitação sem cache - A compilação domina a latência fria. Correção: cacheie módulos compilados; reutilize wazero.CompiledModule.
Passando caminhos de host sensíveis - --dir /::/ excessivamente amplo quebra o sandboxing. Correção: monte diretórios de menor privilégio por convidado.
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Wasmer | Você já o padroniza | A equipe quer um incorporador Go puro (wazero) |
| Node + WASI experimental | Loja JS, scripts pequenos | Incorporação Go em produção |
Plugins nativos (.so) | Desempenho máximo, código confiável | Código de inquilino não confiável |
| MicroVMs Firecracker | Isolamento forte além do WASM | Inícios frios sub-milissegundo necessários |
wazero é Go puro - binários estáticos mais simples, sem cgo, propagação natural de context.
wasmtime continua excelente para CLI/dev e hosts políglotas.
Sim. Instancie múltiplos módulos em um runtime, ou isole runtimes por inquilino para separação de memória.
Não. Spin executa módulos wasip1 compilados por gc, mas limites de tamanho podem levá-lo a usar TinyGo ou -ldflags=-s -w.
fmt.Println para stdout/stderr é mapeado para logs do host.
Capture no wazero via escritores stdout do ModuleConfig.
Sim, via importações personalizadas no wazero (DefineModuleBuilder) ou APIs de linker do wasmtime.
Mantenha a ABI estreita e versionada.
Verifique o suporte a sockets WASI de cada runtime.
Spin expõe HTTP na camada de gatilho em vez de sockets brutos para muitos aplicativos.
Trate .wasm como artefatos imutáveis versionados em armazenamento de objetos.
Troque os bytes do módulo e reinstancie; Spin lida com isso via spin deploy.
wazero suporta timeouts de execução via contexto; medição avançada evolui a cada lançamento - verifique a documentação para sua versão fixada.
Sim, se as importações WASI corresponderem.
Teste ambos em CI quando você incorporar em Go, mas desenvolver com o CLI wasmtime.
Use caminhos mapeados WASI com montagens somente leitura para entradas e montagens graváveis apenas onde a persistência for necessária.
Versões da Pilha: Esta página foi escrita para Go 1.26.x (padrão Green Tea GC, go fix modernizers - verifique o patch na compilação), chi (mais recente - verifique na compilação), gin (mais recente - verifique na compilação), echo (mais recente - verifique na compilação), google.golang.org/grpc (mais recente - verifique na compilação), sigs.k8s.io/controller-runtime (mais recente - verifique na compilação), kubebuilder (mais recente - verifique na compilação), tinygo (mais recente - verifique os alvos de placa na compilação), wazero (mais recente - verifique na compilação) e golangci-lint (mais recente - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026