Getting started with wasmCloud

Cartoon rocket ship taking off. Used for aesthetic purposes.
Photo by Andy Hermawan on Unsplash

The wasmCloud docs includes a handy Getting started guide that lets you quickly try out and develop with wasmCloud on your local machine. In this guide I want to go a little deeper by using a local OCI registry to which I can deploy my application for use in my local wasmCloud instance.

Before I get started, let’s quickly describe some key wasmCloud concepts:

  1. An actor is the unit of deployment — in our case, a WebAssembly module
  2. Much like a serverless function, the actor doesn’t include code or infrastructure to serve HTTP requests — it relies on a provider to deliver this capability. We’ll use the HTTP Server provider in this guide — for a list of first-party capability providers, check out the wasmcloud/capability-providers repo.
  3. A link aligns the actor and the provider and provides configuration (such as which port to run on).

In this guide, we’ll:

  1. Get an OCI registry (Docker Registry 2.0) running via Podman
  2. Compile a template Rust code base to WebAssembly (WASM) and deploy it to the registry
  3. Launch the app in wasmCloud

Let’s get started!

Note: I’m running a Ubuntu 22.04 environment.

Step 1: Install Podman

Instead of using Docker, why not try out Podman? I won’t dive into the differences between the two, instead check out Podman and Buildah for Docker users.

Installation is quite straight-forward, check out the Podman Installation Instructions. I’m running version 3.4.4 — unfortunately, the current version (4.x) is not easily available on Ubuntu but that doesn’t cause an issue for this guide.

If you’d like a GUI tool for handling containers, try out Podman Desktop — I’ve been finding that it’s quite nice to use.

The instructions in the following steps should all work fine, regardless of your decision to use Podman or Docker.

Step 2: Setup a container image registry

As we’ll deploy our local code to a Docker registry, we’ll need a registry. The shell commands below will perform the following:

  1. Setup a local directory to store the images files etc
  2. Podman will start a registry using that local directory
mkdir -p ~/.registry/data

podman run -d \
--name registry \
-p 5000:5000 \
-v $HOME/.registry/data:/var/lib/registry \
--restart=always \
docker.io/library/registry:latest

This type of registry setup is insecure — we’re not securing it with TLS. If you’d like something more robust, check out How to implement a simple personal/private Linux container image registry for internal use.

Step 3: Install wash

wash is the wasmCloud shell and installation is quite straightforward — just check the installation guide.

My version of wash is 0.13.0 (wash --version).

Step 4: Run wasmCloud

To start wasmCloud we would normally just run wash up but we need to set the WASMCLOUD_OCI_ALLOWED_INSECURE configuration variable first so as to allow access to the insecure local registry.

export WASMCLOUD_OCI_ALLOWED_INSECURE=localhost:5000

wash up

You’ll now be able to access the dashboard at http://localhost:4000

You can also check out your wasmCloud environment with a few handy commands.

The Host ID is important to further commands. In order to get a quick view, try wash ctl get hosts.

It can be more useful to stash this in an environment variable. The snippet below gets the host’s ID and uses it to get an inventory for the host (kind of like kubectl get all):

export CLOUDHOST=$(wash ctl get hosts -o json | jq '.hosts[0].id' -r)

wash ctl get inventory $CLOUDHOST

As we haven’t deployed any actors or providers, the inventory will be rather minimal:

Host Inventory (NCOXL2WQUI37BO3BCEFY4N3MSDQCOSDOAX6MPQVMYO5HJMT24KOJV2ET)  

hostcore.osfamily unix
hostcore.arch x86_64
hostcore.os linux

No actors found

No providers found

Step 5: Deploy the HTTP Server provider

As the demo actor will be a basic web service, we’ll need an HTTP Server provider. Deployment is straight-forward:

wash ctl start provider wasmcloud.azurecr.io/httpserver:0.16.2

For further details, see the wasmCloud HTTP Server Provider documentation.

You could also podman pull the wasmcloud.azurecr.io/httpserver:0.16.2 image and push it to the local registry and then use the provider locally but that’s not so important for this walk through.

Checking the inventory (wash ctl get inventory $CLOUDHOST) will yield a little more than last time:

# Note: this is sample output - don't run it!

Host Inventory (NCOXL2WQUI37BO3BCEFY4N3MSDQCOSDOAX6MPQVMYO5HJMT24KOJV2ET)

hostcore.os linux
hostcore.osfamily unix
hostcore.arch x86_64

No actors found

Provider ID Name Link Name Image Reference
VAG3QITQQ2ODAOWB5TTQSDJ53XK3SHBEIFNK4AYJ5RKAX2UNSCAPHA5M HTTP Server default wasmcloud.azurecr.io/httpserver:0.16.2

Step 6: Create an actor

We’ll use a Rust example so you need to install Rust using rustup and then add the wasm32-unknown-unknown compilation target:

rustup target add wasm32-unknown-unknown

The wash new command will create a new code base from a template:

wash new actor hello-rust --template-name hello

cd hello-rust

The template includes a handy Makefile so it’s just a case of running:

make

This tends to take a couple of minutes so grab a ☕️.

Once the code has built, you’ll notice that make will also sign the .wasm file to create hello_rust_s.wasm — this is what we’ll deploy.

# Note: this is sample output - don't run it!

wash claims sign target/wasm32-unknown-unknown/release/hello_rust.wasm \
-c wasmcloud:httpserver \
--name "hello-rust" --ver 0.1.0 --rev 0 \
\
--destination build/hello_rust_s.wasm

Successfully signed build/hello_rust_s.wasm with capabilities: wasmcloud:httpserver

If you take a peek at the Makefile you’ll notice that the default registry URL is already aligned to the one we deployed in Step 2 and that wash reg push is used to push the wasm file to the registry:

# registry url for our actor
REG_URL = localhost:5000/v2/$(PROJECT):$(VERSION)
# command to upload to registry (without last wasm parameter)
PUSH_REG_CMD = wash reg push --insecure $(REG_URL)

So, to push, just run:

make push

Step 7: Deploy the actor

To start the actor (our hello-rust app) call the following command:

wash ctl start actor localhost:5000/v2/hello_rust:0.1.0

A quick check of the inventory (wash ctl get inventory $CLOUDHOST) and we see that the provider and actor are ready to go:

# Note: this is sample output - don't run it!

Host Inventory (NCOXL2WQUI37BO3BCEFY4N3MSDQCOSDOAX6MPQVMYO5HJMT24KOJV2ET)

hostcore.osfamily unix
hostcore.arch x86_64
hostcore.os linux

Actor ID Name Image Reference
MBWW46M5B6G7I2Y4OUWZ2LUTUPUEJGZZES44K6OAVUBPIKY7RX2DIHOP hello-rust localhost:5000/v2/hello_rust:0.1.0

Provider ID Name Link Name Image Reference
VAG3QITQQ2ODAOWB5TTQSDJ53XK3SHBEIFNK4AYJ5RKAX2UNSCAPHA5M HTTP Server default wasmcloud.azurecr.io/httpserver:0.16.2

Step 8: Link the actor and the provider

We need to link the actor to the provider using their IDs. This is easy in the wasmCloud dashboard but needs a little work on the command line.

export HELLO_ACTOR_ID=$(wash ctl get inventory $CLOUDHOST -o json | jq '.inventory.actors[]|select(.name=="hello-rust")|.id' -r)

export HTTP_PROVIDER_ID=$(wash ctl get inventory $CLOUDHOST -o json | jq '.inventory.providers[]|select(.name=="HTTP Server")|.id' -r)

wash ctl link put ${HELLO_ACTOR_ID} ${HTTP_PROVIDER_ID} \
wasmcloud:httpserver address=0.0.0.0:8087

A quick check of http://localhost:8087/ should see our familiar Hello World greeting.

You’d think that one last check of the inventory would show us the link but we actually need to run wash ctl link queryto get the details:

# Note: this is sample output - don't run it!

Actor ID Provider ID Contract ID Link Name
MBWW46M5B6G7I2Y4OUWZ2LUTUPUEJGZZES44K6OAVUBPIKY7RX2DIHOP VAG3QITQQ2ODAOWB5TTQSDJ53XK3SHBEIFNK4AYJ5RKAX2UNSCAPHA5M wasmcloud:httpserver default

Step 9: Stop wasmCloud and then start it again

In the terminal running wash up, stop the service using CTRL+c.

Next, in the same terminal, run wash up.

To check the inventory you’ll need to get the new Host ID:

export CLOUDHOST=$(wash ctl get hosts -o json | jq '.hosts[0].id' -r)

wash ctl get inventory $CLOUDHOST

Notice something wrong? Yup, the actor and provider are gone — what a pain!

Step 10: Use a host manifest

A host manifest is a handy way to quickly fire up our environment.

Start by creating a manifest.yaml file and add the following content:

actors:
- localhost:5000/v2/hello_rust:0.1.0
capabilities:
- image_ref: wasmcloud.azurecr.io/httpserver:0.16.2

To apply the manifest we run:

wash ctl apply $CLOUDHOST manifest.yaml

That sets up the actor and provider but we still need to create the link:

export HELLO_ACTOR_ID=$(wash ctl get inventory $CLOUDHOST -o json | jq '.inventory.actors[]|select(.name=="hello-rust")|.id' -r)

export HTTP_PROVIDER_ID=$(wash ctl get inventory $CLOUDHOST -o json | jq '.inventory.providers[]|select(.name=="HTTP Server")|.id' -r)

wash ctl link put ${HELLO_ACTOR_ID} ${HTTP_PROVIDER_ID} \
wasmcloud:httpserver address=0.0.0.0:8087

http://localhost:8087/ should now be fully operational!

Oh, before you tidy up, try out http://localhost:8087/?name=Mars

Step 11: Tidy up

As described in Step 9, shutting down wasmCloud is just a case of going to the terminal running wash up, and stopping the service using CTRL+c.

To stop the image registry just run podman stop registry — you can always start it again with podman start registry.

Conclusion

Well, that’s it for this overview for launching wasmCloud-based services with the help of a local registry. Whilst we focused on an actor, the approach can also be useful when creating your own capability provider.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Duncan Dickinson

Duncan Dickinson

I guess I mainly like stuff around software development. Opinions are my own, not those of my employer. See my "About" page for more details.