Wasm Builders

Cover image for A "WebAssembly FaaS" platform on a Pi without Kubernetes: say ๐Ÿ‘‹ to Procyon
Philippe Charriรจre
Philippe Charriรจre

Posted on

A "WebAssembly FaaS" platform on a Pi without Kubernetes: say ๐Ÿ‘‹ to Procyon

My title is too long? ๐Ÿค”

Introduction

When I started to use Sat, I was sure that it was the perfect tool for my day-to-day use cases.

"Sat (as in satellite) is a tiny WebAssembly edge compute server". Sat loads and serves through http, WebAssembly modules called Runnables.

Context: I'm working at GitLab; I use GitLab CI a lot, and one of my duty is to explain GitLab CI & CD to my customers in a simple way, si I need to be able to deploy small applications (like functions) simply and quickly on a "platform." I can do that with Kubernetes, but it's painful to set up and maintain. The complexity of deploying a tiny web application tempers the simplicity of the GitLab CI/CD scripts. Another duty is to create "DevOps" tools like hooks and bots.

So, Sat seemed to be the perfect citizen for this, but I needed a platform to operate several functions.

It was the perfect moment to improve my GoLang skills (I'm a baby GoLang programmer) and found my inspiration in this book: "Build an Orchestrator in Go". So, I decided to write a mono-node "Sat orchestrator" to help me deploy (and operate) Wasm functions as simply as possible.

My other source of inspiration is the Knative project, which is a fantastic layer of simplicity for Kubernetes, especially its CLI, allowing you to deploy (and redeploy) applications without the usage of Yaml, even if you're not a "Kube Guru".

It was the birth of Procyon.

DISCLAIMER: Procyon and Sat are so small that you can run them on a RaspberryPi, but they fit perfectly on any computer, VM, and container (I even run a version on Fly.io, and it works like a charm).

So, now, I will explain what Procyon is, how it works, how to use it with its CLI (procyon-cli), and then, in the end, I will explain how to install it on a RaspberryPi or somewhere else.

You can read these posts about Sat:

The main operation of Procyon

Procyon is composed of three components:

  • Procyon Launcher
  • Procyon Reverse
  • Procyon CLI

Procyon CLI is the CLI of the Procyon project, it's the simplest way to send commands to Procyon Launcher and Procyon Reverse.

Procyon Launcher is a kind of task orchestrator. Its primary function is to spawn a Sat process every time you ask.

Deploy three revision of a function to Procyon:

procyon-cli functions deploy \
  --wasm https://registry-cdn.wapm.io/contents/k33g/hey/1.0.0/hey.wasm \
  --function hey \
  --revision ๐Ÿ”ต

procyon-cli functions deploy \
  --wasm https://registry-cdn.wapm.io/contents/k33g/hey/1.0.1/hey.wasm \
  --function hey \
  --revision ๐ŸŸข

procyon-cli functions deploy \
  --wasm https://registry-cdn.wapm.io/contents/k33g/hey/1.0.2/hey.wasm \
  --function hey \
  --revision ๐ŸŸ 
Enter fullscreen mode Exit fullscreen mode

What does it mean?:

  • You can run several versions of a function on Procyon
  • A revision allows you to call a specific version of a function
  • ๐ŸŽ‰ yes, you can use emoji to name a revision (but it's not mandatory)

Remarks:

  • The --wasm flag explains to the Sat process where to download the wasm module. I use wapm.io ti publish my wasm modules, but any HTTP file sever should work. ๐Ÿ–๏ธ The URL must be HTTPS and must have a .wasm suffix (according to the Sat documentation).
  • You should read this post on how to deploy to wapm.io: Publish your Runnables on wapm.io.

Procyon Reverse is a sort of reverse proxy allowing you to call the deployed functions (with the CLI or with a simple curl command)

Call the ๐ŸŸ  revision of the hey function:

procyon-cli functions call \
  --function hey \
  --revision ๐ŸŸ  \
  --method POST \
  --data 'Jane Doe'
Enter fullscreen mode Exit fullscreen mode

๐Ÿ‘‹ of course you can use a curl command: curl https://procyon.fly.dev:8043/functions/hey/๐ŸŸ  -d 'Jane Doe'

Image description

I'm an artist ๐Ÿ˜‚

Play with revisions

You can define a revision as the default revision of a function.

Define the ๐ŸŸข revision of the hey function as the default revision:

procyon-cli functions revision \
  --function hey \
  --revision ๐ŸŸข \
  --switch on
Enter fullscreen mode Exit fullscreen mode

Now you can call the hey function like this:

curl https://procyon.fly.dev:8043/functions/hey -d 'Jane Doe'

But you can still call the other revisions:

curl https://procyon.fly.dev:8043/functions/hey/๐ŸŸ  -d 'Jane Doe'
curl https://procyon.fly.dev:8043/functions/hey/๐Ÿ”ต -d 'Jane Doe'

I tried to keep things as simple as possible. Now let's get to the fun stuff.

Install Procyon on a Pi

Image description

Prerequisites

I installed Procyon on a Pi3 A+, but it should work on a Pi Zero 2 (on a Pi4, it's ok). So, the setup is done with a Pi3 A+ on Raspberry Pi OS 64 bit. I wrote a quick guide to install Raspberry Pi OS: https://github.com/bots-garden/rpi-docs/wiki/OS-(Raspbian-64-bit)-Install-on-Pi-3---and-Pi-4

Installation

You need to ssh connect to the Pi: ssh k33g@procyon.local (use the appropriate user, IP, password, ...)

Then, install screen on the Pi: sudo apt-get install screen

Install Procyon Launcher

RELEASE="0.3.7"
ARCHITECTURE="arm64"
wget https://github.com/bots-garden/procyon/releases/download/${RELEASE}/procyon-launcher-${RELEASE}-linux-${ARCHITECTURE}.tar.gz
mkdir procyon-launcher
tar -zxf procyon-launcher-${RELEASE}-linux-${ARCHITECTURE}.tar.gz --directory procyon-launcher

cd procyon-launcher

procyon_json="$(cat <<-EOF
{
  "executors": {
    "satExecutorPath": "/usr/local/bin/sat"
  },  
  "functions": {
    "wasmFilesDirectory": "./functions"
  },
  "http":{
    "start": 3000
  }
}
EOF
)"

echo "${procyon_json}" > procyon-launcher.json
cd ..
Enter fullscreen mode Exit fullscreen mode

Install Procyon Reverse

wget https://github.com/bots-garden/procyon/releases/download/${RELEASE}/procyon-reverse-${RELEASE}-linux-${ARCHITECTURE}.tar.gz
mkdir procyon-reverse
tar -zxf procyon-reverse-${RELEASE}-linux-${ARCHITECTURE}.tar.gz --directory procyon-reverse

cd procyon-reverse
procyon_json="$(cat <<-EOF
{
  "procyonUrl": "http://localhost:9090",
  "procyonDomain": "http://localhost"
}
EOF
)"
echo "${procyon_json}" > procyon-reverse.json

cd ..
Enter fullscreen mode Exit fullscreen mode

Install Sat

๐Ÿ–๏ธ You will need an arm version of Sat. I built one for you on a Pi4 (don't try on a Pi3, it's toooo long): https://github.com/bots-garden/sat-arm.

wget https://github.com/bots-garden/sat-arm/raw/main/sat-0.1.2
chmod +x sat-0.1.2
sudo cp sat-0.1.2 /usr/local/bin/sat
Enter fullscreen mode Exit fullscreen mode

If you want to build sat, I write a little documentation: https://github.com/bots-garden/rpi-docs/wiki/Build-Sat-on-a-RPI-4

Start Procyon components

We will use screen

Start Procyon Launcher

screen
cd procyon-launcher;
PROCYON_WASM_WORKER_PORT=9090 \
PROCYON_ADMIN_TOKEN="ilovepandas" \
./procyon-launcher
Enter fullscreen mode Exit fullscreen mode

use the keys combination ctrl + a + d to come back to the main process

Start Procyon Reverse

screen
cd procyon-reverse;
PROXY_HTTP=8080 \
PROCYON_ADMIN_TOKEN="ilovepandas" \
./procyon-reverse
Enter fullscreen mode Exit fullscreen mode

some screen commands

  • screen -r # to come back to the process
  • screen -ls # get the list of the running 'screen'

Install the Procyon CLI on your laptop

๐Ÿ‘‹ I had to add this line to my /etc/hosts file:

192.168.1.32 procyon.local
Enter fullscreen mode Exit fullscreen mode

Where 192.168.1.32 is the IP address of my RPI3

RELEASE="0.3.7"
ARCHITECTURE="amd64"
OS="darwin" # or OS="linux"

wget "https://github.com/bots-garden/procyon/releases/download/${RELEASE}/procyon-cli-${RELEASE}-${OS}-${ARCHITECTURE}.tar.gz"
mkdir procyon-cli
tar -zxf procyon-cli-${RELEASE}-${OS}-${ARCHITECTURE}.tar.gz --directory procyon-cli

cd procyon-cli

procyon_yaml="$(cat <<-EOF
procyon-launcher:
  url: http://procyon.local:9090
  admin-token: ilovepandas

procyon-reverse:
  url: http://procyon.local:8080
EOF
)"

echo "${procyon_yaml}" > .procyon-cli.yaml

sudo cp ./procyon-cli /usr/local/bin/procyon-cli
cp .procyon-cli.yaml $HOME/.procyon-cli

cd ..
rm -rf procyon-cli
Enter fullscreen mode Exit fullscreen mode

๐ŸŽ‰ now you are ready to play with Procyon:

Deploy a module (it already exists on wapm.io):

procyon-cli functions deploy \
  --wasm https://registry-cdn.wapm.io/contents/k33g/yo/1.0.0/yo.wasm \
  --function yo \
  --revision 1.0.0
Enter fullscreen mode Exit fullscreen mode

You should get something like this:

๐Ÿš€ deployment of wasm module in progress
๐Ÿ“ https://registry-cdn.wapm.io/contents/k33g/yo/1.0.0/yo.wasm โ›Ž yo ๐Ÿ“ฆ 1.0.0
๐ŸŒ WasmFunctionHttpPort: 3000
โ›Ž FunctionName: yo
๐Ÿ“ FunctionRevision: 1.0.0 DefaultRevision: false
๐ŸŒ yo [1.0.0] url: http://procyon.local:8080/functions/yo/1.0.0
Enter fullscreen mode Exit fullscreen mode

Call the function:

procyon-cli functions call \
  --function yo \
  --revision 1.0.0 \
  --method POST \
  --data 'Jane Doe'
Enter fullscreen mode Exit fullscreen mode

Or curl http://procyon.local:8080/functions/yo/1.0.0 -d 'Jane Doe'

I will write more about Procyon shortly.

Install Procyon elsewhere

You can, of course, use Procyon on something other than a Raspberry Pi (on a VM, in Docker, somewhere on the Cloud, ...).

For example, with Docker

Let's have a look at this quick and dirty Dockerfile: https://github.com/bots-garden/procyon-docker-demo/blob/main/Dockerfile

Build and run it:

IMAGE_NAME="procyon"
IMAGE_TAG="0.0.0"
docker build -t ${IMAGE_NAME} . 
docker run -p 8080:8080 -p 9090:9090 -d procyon
Enter fullscreen mode Exit fullscreen mode

๐Ÿ‘‹ this is the script to install the CLI: https://github.com/bots-garden/procyon-docker-demo/blob/main/install-cli.sh

Or on Fly.io

And if you publish the image to the Docker Hub:

docker login -u ${DOCKER_USER} -p ${DOCKER_PWD}
docker tag ${IMAGE_NAME} ${DOCKER_USER}/${IMAGE_NAME}:${IMAGE_TAG}
docker image ls
docker push ${DOCKER_USER}/${IMAGE_NAME}:${IMAGE_TAG}
Enter fullscreen mode Exit fullscreen mode

... You will able to deploy Procyon on Fly.io:

brew install superfly/tap/flyctl
flyctl auth signup

flyctl apps create procyon --json # only at first time

flyctl deploy \
  --app procyon \
  --image ${DOCKER_USER}/${IMAGE_NAME}:${IMAGE_TAG} \ # eg: k33g/procyon:0.0.0
  --verbose --json
Enter fullscreen mode Exit fullscreen mode

๐Ÿ˜ and it works like a charm.

Disclaimer and Roadmap

  • Procyon is not ready for Production (keep in mind that I'm a JavaScript developer and it's my baby steps with GoLang)
  • Procyon is stateless (if you stop it, all the Sat processes disappears and you will need to deploy Runnable modules again)
  • Next steps:
    • Create an installation script
    • Provide useful samples (hook, bot, ...)
    • Allow to redeploy Runnable modules at re-start
    • Create my own modules registry (I have one for development tests https://github.com/bots-garden/procyon/tree/main/procyon-registry but I want something more like wapm.io)
    • Create a "Procyon Geo distribution" (disaster recovery)
    • Create a "Procyon HA distribution"
    • Document the API
    • ...

So, I'm having a lot of fun with this project, and you can follow my progress on https://github.com/bots-garden/procyon/issues

Don't hesitate to ping me here or at @k33g_org for any question and/or idea. ๐Ÿ‘‹


Header image by Denis Doukhan from Pixabay

Discussion (0)