Wasm Builders 🧱

Cover image for Deploy Capsule Functions on Fly.io in a flash
Philippe Charrière
Philippe Charrière

Posted on

Deploy Capsule Functions on Fly.io in a flash

If you don't know Capsule, read this section: What is Capsule.

The release of Capsule v0.2.8 🦤 [dodo] comes with two new tools to increase the developer experience:

  • A Capsule Docker Image to easily use and deploy the Capsule Runner on CaaS and Kubernetes. It's an 16.8M sized Docker image!
  • The Capsule Builder (you can call it cabu) project, a CLI composed of a script and a Docker image embedding the TinyGo and Golang compilers and some templates to create easily Capsule functions projects.

By the way, all the other modules than the Capsule Runner have been externalized. From now, the Capsule project is dedicated to the Capsule Runner for clarity and simplicity.

But let's see how to use all this to create a function and deploy it on Fly.io quickly.

To reproduce all the steps you only need Docker, an account at Fly.io (there is a free plan) and the flyctl CLI (from Fly.io).

Install cabu (Capsule Builder)

Use the commands below:

CAPSULE_BUILDER_VERSION="v0.0.2"
wget -O - https://raw.githubusercontent.com/bots-garden/capsule-function-builder/${CAPSULE_BUILDER_VERSION}/install-capsule-builder.sh | bash
Enter fullscreen mode Exit fullscreen mode

The script will be installed in $HOME/.local/bin

🖐 On macOS:

  • create the $HOME/.local/bin directory
  • add it to your path:
  export CAPSULE_PATH="$HOME/.local"
  export PATH="$CAPSULE_PATH/bin:$PATH"

if you want to install it somewhere else, override the CAPSULE_BUILDER_PATH variable (default value: CAPSULE_BUILDER_PATH="$HOME/.local/bin") when running the install script.

Generate a new function project with cabu

Type the following command:

cabu generate service-post hello
Enter fullscreen mode Exit fullscreen mode

At the first use, cabu will pull the capsule-builder image. Then cabu will generate a hello project from the service-post template (use cabu templates to get the templates list).

hello
├── go.mod
└── hello.go
Enter fullscreen mode Exit fullscreen mode

You can have a quick look to the hello.go file, it's a vey simple nano wasm service and you can call it through HTTP with a simple curl command curl -X POST http://localhost:8080 -H 'content-type: application/json' -d '{"name": "Bob"}':

package main

import (
  hf "github.com/bots-garden/capsule/capsulemodule/hostfunctions"
  "github.com/tidwall/gjson"
  "github.com/tidwall/sjson"
)

func main() {
  hf.SetHandleHttp(Handle)
}

func Handle(request hf.Request) (response hf.Response, errResp error) {

  hf.Log("📝 Body: " + request.Body)
  hf.Log("📝 URI: " + request.Uri)
  hf.Log("📝 Method: " + request.Method)

  name := gjson.Get(request.Body, "name")

  headersResp := map[string]string{
    "Content-Type": "application/json; charset=utf-8",
  }

  jsondoc := `{"message": ""}`
  jsondoc, _ = sjson.Set(jsondoc, "message", "👋 hello " + name.Str)

  return hf.Response{Body: jsondoc, Headers: headersResp}, nil
}
Enter fullscreen mode Exit fullscreen mode

Build the wasm function with cabu

Type the following commands:

cd hello
cabu build . hello.go hello.wasm
# don't forget the dot
Enter fullscreen mode Exit fullscreen mode

cabu will produce a wasm file (hello.wasm)

Serve hello.wasm

Type the following commands:

cd hello # if needed
docker run \
  -p 8080:8080 \
  -v $(pwd):/app --rm k33g/capsule-launcher:0.2.8 \
  /capsule \
  -wasm=./app/hello.wasm \
  -mode=http \
  -httpPort=8080
Enter fullscreen mode Exit fullscreen mode

The capsule-launcherimage will be pulled and then the hello function will be served. Try it with this command:

curl -v -X POST http://localhost:8080 \
-H 'content-type: application/json' \
-d '{"name": "Bob"}'
Enter fullscreen mode Exit fullscreen mode

You'll get:

{"message":"👋 hello Bob"}
Enter fullscreen mode Exit fullscreen mode

If you prefer, you can install the Capsule Runner directly:

CAPSULE_VERSION="v0.2.8"
wget -O - https://raw.githubusercontent.com/bots-garden/capsule/${CAPSULE_VERSION}/install-capsule-launcher.sh| bash
Enter fullscreen mode Exit fullscreen mode

And serve the function with this command:

capsule \
  -wasm=./hello.wasm \
  -mode=http \
  -httpPort=8080
Enter fullscreen mode Exit fullscreen mode

The service is working, it's time to deploy it on Fly.io.

Deploy the hello function on Fly.io

Install flyctl

The installation of flyctl is very straightforward, have a look to https://fly.io/docs/hands-on/install-flyctl/. On Linux, I used curl -L https://fly.io/install.sh | sh.

Get your token from your Fly.io account, and set a FLY_ACCESS_TOKEN variable with the token's value.

Dockerize the hello function

Create a Dockerfilein the hello directory:

FROM k33g/capsule-launcher:0.2.8
ADD hello.wasm ./
EXPOSE 8080
CMD ["/capsule", "-wasm=./hello.wasm", "-mode=http", "-httpPort=8080"]
Enter fullscreen mode Exit fullscreen mode

Deploy hello for the first time

Type the commands below:

cd hello
fly launch
Enter fullscreen mode Exit fullscreen mode

And reply to the questions:

  • App Name: tiny-hello (or whatever you want)
  • Select region: cdg (Paris, France) (or whatever you want)
  • Would you like to set up a Postgresql database now: N

flyctl will detect the Dockerfile, and then, generate a config file fly.toml:

hello
├── Dockerfile
├── fly.toml
├── go.mod
├── go.sum
├── hello.go
└── hello.wasm
Enter fullscreen mode Exit fullscreen mode

So, answer Y to the question ? Would you like to deploy now? (y/N). Then the function should be deployed in some seconds

You can call it like this:

curl -X POST https://tiny-hello.fly.dev \
-H 'content-type: application/json' \
-d '{"name": "Bob"}'
Enter fullscreen mode Exit fullscreen mode

That's pretty impressive simplicity! 🚀

If you change your code, then after the rebuild of your function, you can quickly redeploy with the following commands:

cd hello
fly deploy

That's all for now.

Next episodes (not necessarily in this order):

  • Deploy a Capsule function on Kubernetes
  • Develop a GitHub/GitLab web hook with Capsule
  • Develop a Bot with Capsule

Photo by Zdeněk Macháček on Unsplash

Latest comments (0)