Skip to main content

Blobstore Fileserver (NATS)

A blob storage ("blobby") fileserver backed by NATS, implemented as a Wasm component and packaged for Cosmonic Control.

Deploy with Helm

helm install blobby --version 0.1.2 oci://ghcr.io/cosmonic-labs/charts/http-trigger -f https://raw.githubusercontent.com/cosmonic-labs/control-demos/refs/heads/main/blobby/values.http-trigger.yaml

Repository: cosmonic-labs/control-demos/blobstore-nats
Languages: Rust
Interfaces: wasi/http, wasi/blobstore

Running on Kubernetes

You will need a local Kubernetes environment with Cosmonic Control installed according to the Get Started guide.

Now you can connect to the component at http://blobby.localhost.cosmonic.sh.

Create a file with some content:

$ echo 'Hello there!' > myfile.txt

Upload the file to the fileserver:

curl -H 'Content-Type: text/plain' -v 'http://blobby.localhost.cosmonic.sh/myfile.txt' --data-binary @myfile.txt
* Host blobby.localhost.cosmonic.sh:80 was resolved.
* IPv6: (none)
* IPv4: 127.0.0.1
*   Trying 127.0.0.1:80...
* Connected to blobby.localhost.cosmonic.sh (127.0.0.1) port 80
> POST /myfile.txt HTTP/1.1
> Host: blobby.localhost.cosmonic.sh
> User-Agent: curl/8.7.1
> Accept: */*
> Content-Type: text/plain
> Content-Length: 13
>
* upload completely sent off: 13 bytes
< HTTP/1.1 201 Created
< date: Thu, 09 Oct 2025 19:55:00 GMT
< x-envoy-upstream-service-time: 1
< server: envoy
< transfer-encoding: chunked
<
* Connection #0 to host blobby.localhost.cosmonic.sh left intact
Wrote myfile.txt to blobstore successfully

Get the file back from the server:

curl -v 'http://blobby.localhost.cosmonic.sh/myfile.txt'
* Host blobby.localhost.cosmonic.sh:80 was resolved.
* IPv6: (none)
* IPv4: 127.0.0.1
*   Trying 127.0.0.1:80...
* Connected to blobby.localhost.cosmonic.sh (127.0.0.1) port 80
> GET /myfile.txt HTTP/1.1
> Host: blobby.localhost.cosmonic.sh
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< date: Thu, 09 Oct 2025 19:57:01 GMT
< x-envoy-upstream-service-time: 2
< server: envoy
< transfer-encoding: chunked
<
Hello there!
* Connection #0 to host blobby.localhost.cosmonic.sh left intact

Update the file:

echo 'General Kenobi!' >> myfile.txt

Update the file on the fileserver:

curl -H 'Content-Type: text/plain' -v 'http://blobby.localhost.cosmonic.sh/myfile.txt' --data-binary @myfile.txt
* Host blobby.localhost.cosmonic.sh:80 was resolved.
* IPv6: (none)
* IPv4: 127.0.0.1
*   Trying 127.0.0.1:80...
* Connected to blobby.localhost.cosmonic.sh (127.0.0.1) port 80
> POST /myfile.txt HTTP/1.1
> Host: blobby.localhost.cosmonic.sh
> User-Agent: curl/8.7.1
> Accept: */*
> Content-Type: text/plain
> Content-Length: 29
>
* upload completely sent off: 29 bytes
< HTTP/1.1 201 Created
< date: Thu, 09 Oct 2025 20:14:30 GMT
< x-envoy-upstream-service-time: 2
< server: envoy
< transfer-encoding: chunked
<
* Connection #0 to host blobby.localhost.cosmonic.sh left intact
Wrote myfile.txt to blobstore successfully

Get the file again to see your updates:

curl -v 'http://blobby.localhost.cosmonic.sh/myfile.txt'
* Host blobby.localhost.cosmonic.sh:80 was resolved.
* IPv6: (none)
* IPv4: 127.0.0.1
*   Trying 127.0.0.1:80...
* Connected to blobby.localhost.cosmonic.sh (127.0.0.1) port 80
> GET /myfile.txt HTTP/1.1
> Host: blobby.localhost.cosmonic.sh
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< date: Thu, 09 Oct 2025 20:15:45 GMT
< x-envoy-upstream-service-time: 0
< server: envoy
< transfer-encoding: chunked
<
Hello there!
General Kenobi!
* Connection #0 to host blobby.localhost.cosmonic.sh left intact

Delete the file:

curl -X DELETE -v 'http://blobby.localhost.cosmonic.sh/myfile.txt'
* Host blobby.localhost.cosmonic.sh:80 was resolved.
* IPv6: (none)
* IPv4: 127.0.0.1
*   Trying 127.0.0.1:80...
* Connected to blobby.localhost.cosmonic.sh (127.0.0.1) port 80
> DELETE /myfile.txt HTTP/1.1
> Host: blobby.localhost.cosmonic.sh
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< date: Thu, 09 Oct 2025 20:16:15 GMT
< x-envoy-upstream-service-time: 2
< server: envoy
< transfer-encoding: chunked
<
* Connection #0 to host blobby.localhost.cosmonic.sh left intact
Deleted myfile.txt from blobstore successfully

Confirm that the file doesn't exist anymore:

curl -v 'http://blobby.localhost.cosmonic.sh/myfile.txt'
* Host blobby.localhost.cosmonic.sh:80 was resolved.
* IPv6: (none)
* IPv4: 127.0.0.1
*   Trying 127.0.0.1:80...
* Connected to blobby.localhost.cosmonic.sh (127.0.0.1) port 80
> GET /myfile.txt HTTP/1.1
> Host: blobby.localhost.cosmonic.sh
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 404 Not Found
< date: Thu, 09 Oct 2025 20:17:09 GMT
< x-envoy-upstream-service-time: 0
< server: envoy
< transfer-encoding: chunked
<
* Connection #0 to host blobby.localhost.cosmonic.sh left intact
Object not found

Development

Development requirements:

  • cargo 1.82+ for the Rust toolchain
  • wasm32-wasip2 target for Rust: Install with rustup target add wasm32-wasip2
  • Wasm Shell (wash) for component development

Clone the wasmcloud/wasmcloud repository:

git clone https://github.com/wasmcloud/wasmcloud.git
cd wasmcloud/examples/rust/components/blobby

Install the blobstore-filesystem plugin, which enables you to back blobstore operations with your local filesystem during the development loop:

wash plugin install ghcr.io/wasmcloud/wash-plugins/blobstore-filesystem:0.1.0

Start the development loop:

wash dev

The component is accessible at localhost:8000. View the code and make changes in src/lib.rs.

You can cancel the wash dev process with Ctrl-C.

Build the Wasm Binary

Compile the component:

wash build

The .wasm binary will output to /target/wasm32-wasip2/debug.

Learn More