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 toolchainwasm32-wasip2
target for Rust: Install withrustup 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
-
See the Cosmonic Control documentation for instructions on pushing your Wasm component to an OCI registry.
-
To learn how to extend this example with additional capabilities, see the Adding Capabilities section of the wasmCloud documentation.
-
For more on building components in Go, see the Component Developer Guide in the wasmCloud documentation.