Extend and Deploy
In our previous tutorials, we started a developer loop and added two interfaces (wasi:logging
and wasi:keyvalue
) to our application. The wash dev
process satisfied our application's capability requirements automatically, so we could move quickly and focus on code.
Now we'll learn how to:
- Explore capabilities available for wasmCloud applications
- Extend our application by plugging in capability requirements
- Deploy an application in a local wasmCloud environment
This tutorial assumes you're following directly from the previous steps. Make sure to complete Quickstart and Add Features first.
Choose a capability
As we learned in the previous tutorial, components can make use of capabilities for common requirements like key-value storage or logging.
If we want to learn about a capability, we can browse the Capability Catalog.
Each capability in the catalog consists of an interface and one or more capability providers.
- Interfaces are the language-agnostic APIs we use to represent a capability in our code. They are defined using the WebAssembly Interface Type (WIT) interface description language in simple
.wit
files. - Capability providers are reusable executable plugins that deliver functionality described by an interface. Where interfaces are typically very general (i.e. key-value storage), providers are tool- or vendor-specific implementations (i.e. Redis, Vault).
Here's the Capability Catalog listing for Key-Value Storage:
NAME | INTERFACE | PROVIDERS |
---|---|---|
Key-Value Storage | wasi:keyvalue | Redis, NATS, Vault |
Here we find the interface, wasi:keyvalue
, and several capability providers including Redis.
WASI stands for WebAssembly System Interface (WASI), a group of standards-track APIs governed by the WASI Subgroup in the W3C WebAssembly Community Group. wasmCloud uses WASI interfaces to define capabilities in a standards-based way that avoids vendor lock-in.For more on interfaces and WASI, see the Interfaces page in our Developer Guide.
Select a capability provider
Interfaces are backed by capability providers, which are both reusable and swappable.
When we ran wash dev
, we added capabilities—but we never specified tools or libraries for key-value storage and logging. wash dev
provisioned appropriate capability providers automatically. How? Because components encode their dependencies in the binaries themselves, wash dev
was able to detect the requirement at runtime and start an appropriate providers to satisfy the requirements for an HTTP server, key-value store, and logger.
So what was actually running? In this case, wash dev
used:
- The wasmCloud
httpserver
provider - The wasmCloud built-in logger
- The NATS
keyvalue
provider (Convenient since NATS is already part of the wasmCloud stack)
As far as the key-value capability is concerned, the application looks like this:
If wash dev
is still running from the previous tutorial, make sure to stop it with CTRL+C.
For our manual deployment, let's swap out a different key-value storage provider. We'll use the Redis provider, which will only require us to have redis-server
or Docker installed. The Redis provider will mediate a connection to the Redis server, which is running external to wasmCloud.
- Local Redis Server
- Docker
Install and launch the local redis server in the background
redis-server &
Launch a Redis container in the background.
docker run -d --name redis -p 6379:6379 redis
On the wasmCloud GitHub Packages page, we can find a keyvalue-redis
image (also linked in the Capability Catalog) that enables us to deploy the provider:
ghcr.io/wasmcloud/keyvalue-redis:0.28.1
The wasmCloud ecosystem uses the OCI image specification to package components and providers—these component and provider images are not container images, but conform to OCI standards and may be stored on any OCI-compatible registry.
Deploying the application with a key-value provider
First, let's start a local wasmCloud environment in "detached" mode so we can keep working in our terminal:
wash up -d
Instead of the default NATS keyvalue
provider used by wash dev
, we want to use the Redis provider:
To deploy a wasmCloud application manually, we use an application manifest written in YAML, much like a Kubernetes manifest.
This .yaml
file defines the relationships between the components and providers that make up our application, along with other important configuration details. It is conventionally named wadm.yaml
after the wasmCloud Application Deployment Manager that handles scheduling.
We can modify our wadm.yaml
to include the Redis provider and match the diagram above.
Open wadm.yaml
in your code editor and make the changes below.
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: hello-world
annotations:
description: 'HTTP hello world demo'
spec:
components:
- name: http-component
type: component
properties:
# Your manifest will point to the path of the built component, you can also
# start published components from OCI registries
image: file://./build/http_hello_world_s.wasm
traits:
- type: spreadscaler
properties:
instances: 1
# The new key-value link configuration
- type: link
properties:
target: kvredis
namespace: wasi
package: keyvalue
interfaces: [atomics, store]
target_config:
- name: redis-url
properties:
url: redis://127.0.0.1:6379
# The new capability provider
- name: kvredis
type: capability
properties:
image: ghcr.io/wasmcloud/keyvalue-redis:0.28.1
- name: httpserver
type: capability
properties:
image: ghcr.io/wasmcloud/http-server:0.22.0
traits:
- type: link
properties:
target: http-component
namespace: wasi
package: http
interfaces: [incoming-handler]
source_config:
- name: default-http
properties:
address: 127.0.0.1:8080
Once you save wadm.yaml
, we can deploy from the project directory:
wash app deploy wadm.yaml
Check the status of the app:
wash app list
Note: When deploying the application, it uses port 8080 as defined in wadm.yaml
.
Once the application status is Deployed
, we can curl
the application like before:
curl 'localhost:8080?name=Bob'
Hello x1, Bob!
curl 'localhost:8080?name=Bob'
Hello x2, Bob!
curl 'localhost:8080?name=Alice'
Hello x1, Alice!
Note that our increments are starting over again—after all, we swapped out the dev key-value store for a totally different one!
When you're done with the application, delete it from the wasmCloud environment:
wash app delete hello-world
Shut down the environment:
wash down
Log files
If you encounter any problems, wasmCloud log files may contain useful error messages, and it's good to know how to find them. The tabs below, organized by how you started the wasmCloud environment, show you where to find logs:
- Local
- Docker
By default, logs from wash up
are automatically output to your terminal. If you ran the command
with the --detached
flag, logs can be found in ~/.wash/downloads/wasmcloud.log
Logs from hosts running in Docker, if started with our docker compose, can be found by running
docker logs wasmcloud
.
Next steps
In this tutorial, we learned how to explore capabilities, swap out a provider, and deploy an application to a wasmCloud environment.
- For more information on defining application manifests, see our documentation on the wasmCloud application deployment manager.
- For more information on capabilities, such as how to create new interfaces and providers, see the Developer Guide pages for providers and interfaces.
You can continue to build on this application by adding more features, or you can explore additional first-party providers in the Capability Catalog to get an idea of what is possible with wasmCloud.
The next page demonstrates scaling via application manifest and gives a high-level overview of why this application that you've built already eliminates complexity and pain that developers often face when building applications for the cloud.