fermyon / spin

Spin is the open source developer tool for building and running serverless applications powered by WebAssembly.
https://developer.fermyon.com/spin
Apache License 2.0
5.06k stars 242 forks source link

running exectuable with wasm runtime like wasmtime or wasmedge #1013

Closed bluebrown closed 3 months ago

bluebrown commented 1 year ago

Hi, I am not able to run the build executable with wasmtime, docker or kubernetes.

As far as I understand, this is based on wasmtime so it should be possible to use wasmtime or wasmedge to run the binary right?

When I do spin build and then wasmtime run main.wasm, nothing happens. The process exists immediately without error. The same happens when I try to run this with docker which is using wasmedge.

FROM --platform=amd64 tinygo/tinygo:0.25.0 as build
...
RUN spin build

FROM --platform=wasi/wasm32 scratch
COPY --from=build --chmod=755 /build/main.wasm /main.wasm
ENTRYPOINT [ "/main.wasm" ]
docker buildx build --platform wasi/wasm32 -t spin-app spin-sample/
docker run --rm --runtime=io.containerd.wasmedge.v1 --platform=wasi/wasm32 spin-app

What is missing to be able to run it using some standard compliant wasm runtime?

radu-matei commented 1 year ago

The wasmtime run command tries to execute the _start function (or main) from the module. However, valid Wasm (and WASI) modules can choose not to export such a function, and instead export a different entrypoint to the module.

The entrypoint to a Spin HTTP component is an HTTP handler — called handle-http-request, which takes as parameters an HTTP request, and returns an HTTP response — which is why attempting to run it directly with Wasmtime does not generate a result.

spin up starts the web server and passes the request to the guest Wasm module, which executes, then Spin will return the response.

Spin is built on top of Wasmtime, and it runs valid Wasm modules — however, it executes a different entrypoint and requires a formed HTTP request as parameter.

Hope this helps clarify how it works, let me know if you have additional questions!

bluebrown commented 1 year ago

Hi, thanks for the swift response.

Its all a bit confusing to me as I am new to wasm.

I found this project during my research https://github.com/deislabs/containerd-wasm-shims. It contains a shim for spin. Containerd can be configured to have this shim as extra runtime which can be selected via runtime class, at least in kubernetes I have tested this.

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.spin]
runtime_type = "io.containerd.spin.v1"

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.spin.options]
BinaryName = "/usr/local/bin/containerd-shim-spin-v1"
itowlson commented 1 year ago

I'm not sure about the Docker side of things but there is info about running your Spin app under the containerd shim at:

https://github.com/deislabs/containerd-wasm-shims#running-a-shim-locally-on-linux

They use ctr in their demo but presumably it would work similarly with Docker.

Note that it still needs a Spin manifest in the Dockerfile:

https://github.com/deislabs/containerd-wasm-shims/blob/410221c7b4848f2d81080d3c20ee48b131ce07b7/images/spin/Dockerfile#L8

That is, you don't run a bare Wasm module - you need the spin.toml to tell the shim how to configure things like HTTP routes.

(Their Dockerfile also installs the Rust WASI compiler target - I'm not sure that's needed. But the spin.toml and the .wasm file definitely are.)

bluebrown commented 1 year ago

Yes, that's right, the .wasm binary and spin.toml are enough. I am able to run it in kubernetes like this. I am also fairly sure I would be able to run it with anything that lets me configure containerd, without problems. For example, using nerdctl and contained directly, or podman.

With docker, it also seems doable. It doesn't let you configure containerd directly, but it has a way to register additional runtimes: https://docs.docker.com/engine/reference/commandline/dockerd/#docker-runtime-execution-options.

"runtimes": {
    "spin-v1": {
      "path": "/usr/local/bin/containerd-shim-spin-v1"
    }
  }

Then you could run it with docker run --runtime=spin-v1 my-app.

I am using docker-desktop which makes it a bit more complicated. I am currently trying to solve this.

Mossaka commented 1 year ago

Hey @bluebrown, I am the main maintainer of containerd-wasm-shims project. It's really great that you were able to get the shim running in Docker!! I have not tried it personally, but according to this doc: enabling-the-containerd-image-store-feature, there is a way to enable containerd feature on docker desktop. So technically docker desktop also supports running the Spin shim.

Don't hesitate to reach out and let me know how I can assist you!

bluebrown commented 1 year ago

Hi @Mossaka, I have enabled this feature, but you get a pre-configured runtime using wasmedge, afaik. It's called io.containerd.wasmedge.v1. You can read about it here: https://docs.docker.com/desktop/wasm/.

That cannot run spin applications, though. For this you need to create a custom shim or use the one from deislabs. And then you need to tell docker about this custom runtime.

After consulting docker slack, I think you cannot use custom shims with docker desktop. If you were to use regular Linux, you could do it the way I have shown in my previous comment, but with docker-deskop, you are out of luck, at the moment.

Mossaka commented 1 year ago

Ahh I see your point. That's true. I will talk with my team and see what we can do with Docker folks. After all, the io.containerd.wasmedge.v1 is from Containerd's runwasi and we are the main contributor to this project.

bluebrown commented 1 year ago

Seems like you had success. Docker desktop ships now with more runtimes https://docs.docker.com/desktop/wasm/#enable-wasm-workloads

Docker Desktop downloads and installs the following runtimes that you can use to run Wasm workloads:

  • io.containerd.slight.v1
  • io.containerd.spin.v1
  • io.containerd.wasmedge.v1
  • io.containerd.wasmtime.v1
melissaklein24 commented 3 months ago

@bluebrown closing this issue. If you need anything else, please open a new one.