Run a Spin app
In this guide we create and deploy a simple Spin HTTP app. This guide is derived from
Spinβs spin-wagi-http
example
and shows how to run a Spin application serving routes from two programs written in
different languages (Rust and C++) using both the Spin executor and the Wagi executor
on Unikraft Cloud. To run it, follow these steps:
-
Install the
kraft
CLI tool and a container runtime engine, e.g. Docker. -
Clone the
examples
repository andcd
into theexamples/spin-wagi-http/
directory:
git clone https://github.com/kraftcloud/examplescd examples/spin-wagi-http/
Make sure to log into Unikraft Cloud by setting your token and a metro close to you.
We use fra0
(Frankfurt, π©πͺ) in this guide:
# Set Unikraft Cloud access tokenexport UKC_TOKEN=token# Set metro to Frankfurt, DEexport UKC_METRO=fra0
When done, invoke the following command to deploy this application on Unikraft Cloud:
kraft cloud deploy -p 443:3000 -M 2048 .
The output shows the instance URL and other details:
[β] Deployed successfully! β βββββββββββ name: spin-wagi-http-is72r βββββββββββ uuid: 045c1bda-0f2e-4f8b-98c7-a208bfa7d143 ββββββββββ state: running ββββββββββββ url: https://damp-bobo-wg43p36e.fra0.kraft.host ββββββββββ image: spin-wagi-http@sha256:57a5151996d83332af6da521e1cd92271a8c3ac7ae26bc44a7c0dbbc0a30e577 ββββββ boot time: 300.06 ms βββββββββ memory: 2048 MiB ββββββββ service: damp-bobo-wg43p36e βββ private fqdn: spin-wagi-http-is72r.internal βββββ private ip: 172.16.28.16 βββββββββββ args: /usr/bin/spin up --from /app/spin.toml --listen 0.0.0.0:3000
In this case, the instance name is spin-wagi-http-is72r
and the URL is https://damp-bobo-wg43p36e.fra0.kraft.host
.
They are different for each run.
Then curl
the hello route:
curl -i https://damp-bobo-wg43p36e.fra0.kraft.host/hello
Hello, Fermyon!
And curl
the goodbye route:
curl -i https://damp-bobo-wg43p36e.fra0.kraft.host/goodbye
Goodbye, Fermyon!
At any point in time, you can list information about the instance:
kraft cloud instance list
NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIMEspin-wagi-http-is72r damp-bobo-wg43p36e.fra0.kraft.host running 1 minute ago spin-wagi-http@sha2... 2.0 GiB /usr/bin/spin up --from /app/spin.tom... 300064us
When done, you can remove the instance:
kraft cloud instance remove spin-wagi-http-is72r
Customize your Application
To customize the application, update the files in the repository, listed below:
wagi-http-cpp
: C++ server handling the hello routehttp-rust
: Rust server handling the goodbye routeKraftfile
: the Unikraft Cloud specificationDockerfile
: the Docker-specified application filesystemspin.toml
: The Spin TOML configuration file
spec: v0.6
runtime: spin:latest
rootfs: ./Dockerfile
cmd: ["/usr/bin/spin", "up", "--from", "/app/spin.toml", "--listen", "0.0.0.0:3000"]
FROM rust:1.75.0-bookworm AS spin
ARG SPIN_VERSION=2.1.0
WORKDIR /spin
RUN set -xe; \apt-get update; \apt-get install -y --no-install-recommends \ ca-certificates \ make \ wget;
RUN set -xe; \wget -q -O spin.tar.gz "https://github.com/fermyon/spin/releases/download/v${SPIN_VERSION}/spin-v${SPIN_VERSION}-linux-amd64.tar.gz"; \tar xzvf ./spin.tar.gz; \mv ./spin /usr/bin/spin; \rm -rf spin.tar.gz; \rustup target add wasm32-wasi
ARG WASI_SDK_VERSION=21
WORKDIR /wasi
RUN set -xe; \wget -q -O wasi-sdk.tar.gz "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-linux.tar.gz"; \mkdir -p /opt/wasi-sdk; \tar xzvf ./wasi-sdk.tar.gz --strip-components 1 -C /opt/wasi-sdk/; \rm -rf ./wasi-sdk.tar.gz;
FROM spin AS build
COPY ./http-rust /app/http-rustWORKDIR /app/http-rustRUN cargo build --release
COPY ./wagi-http-cpp /app/wagi-http-cppWORKDIR /app/wagi-http-cppRUN make build
FROM scratch
COPY --from=build /app /appCOPY ./spin.toml /app/spin.toml
spin_manifest_version = 2
[application]description = "A hello world application that serves content from a C++ program and a Rust program"name = "spin-wagi-hello"version = "1.0.0"
[[trigger.http]]route = "/hello"component = "hello"executor = { type = "wagi" } # _start (the default entrypoint) is automatically mapped to main()
[[trigger.http]]route = "/goodbye"component = "goodbye"executor = { type = "http" }
[component.hello]source = "wagi-http-cpp/main.wasm"[component.hello.build]command = "make build -C wagi-http-cpp"
[component.goodbye]source = "http-rust/target/wasm32-wasi/release/goodbyerust.wasm"[component.goodbye.build]command = "cargo build --target wasm32-wasi --release --manifest-path http-rust/Cargo.toml"
Lines in the Kraftfile
have the following roles:
-
spec: v0.6
: The currentKraftfile
specification version is0.6
. -
runtime: spin:latest
: The Unikraft runtime kernel to use is Spin. -
rootfs: ./Dockerfile
: Build the application root filesystem using theDockerfile
. -
cmd: ["/usr/bin/spin", "up", "--from", "/app/spin.toml", "--listen", "0.0.0.0:3000"]
: Usespin
as the command to start the app, with the given parameters.
The following options are available for customizing the application:
-
If only updating the existing files under the
wagi-http-cpp
andhttp-rust
directories, no other change is required. -
If new files are added, these have to be copied in the application filesystem, using the
COPY
command in theDockerfile
. -
More extensive changes may require expanding the
Dockerfile
with additionalDockerfile
commands.
Learn More
Use the --help
option for detailed information on using Unikraft Cloud:
kraft cloud --help
Or visit the CLI Reference.