Dynamic and Runtime Application Configuration

Spin applications may define custom configuration which can be looked up by component code via the spin-config interface.

Custom Config Variables

Application-global custom config variables are defined in the top-level [variables] section. These entries aren’t accessed directly by components but are referenced by component config value templates. Each entry must either have a default value or be marked as required = true. “Required” entries must be provided with a value.

Configuration keys may only contain lowercase letters and underscores between letters:

api_host = { default = "api.example.com" }
api_key = { required = true }

Component Custom Config

The configuration entries available to a component are listed in its [component.config] section. Configuration values may reference config variables with simple mustache-inspired string templates:

# ...
api_base_url = "https://{{ api_host }}/v1"
api_key = "{{ api_key }}"

Custom Config Providers

Custom config variables values may be set at runtime by config “providers”. Currently, there are two providers: the environment variable provider and vault config provider.

Environment Variable Provider

The environment variable provider which gets config values from the spin process’s environment (not the component environment). Config keys are translated to environment variables by upper-casing and prepending with SPIN_CONFIG_:

$ export SPIN_CONFIG_API_KEY = "1234"  # Sets the `api_key` value.
$ spin up

Vault Config Provider

The Vault config provider gets secret values from HashiCorp Vault. Currently, only KV Secrets Engine - Version 2 is supported. You can set up v2 kv secret engine at any mount point and give Vault information in the runtime configuration file:

type = "vault"
url = ""
token = "root"
mount = "secret"

Vault Config Provider Example

  1. Install Vault.
  2. Start Vault:
$ vault server -dev -dev-root-token-id root
  1. Set a password:
$ export VAULT_TOKEN=root
$ export VAULT_ADDR=
$ vault kv put secret/password value="test_password"
$ vault kv get secret/password
  1. Go to the spin/tests/http/vault-config-test folder.
  2. Build and run the vault-config-test app:
$ spin build
$ spin up --runtime-config-file runtime_config.toml
  1. Test the app:
$ curl -i
HTTP/1.1 200 OK
content-length: 26
date: Tue, 18 Oct 2022 12:34:40 GMT

Got password test_password

Runtime Configuration

Runtime configuration contains information for the selected config provider, such as the Vault config provider. You can supply runtime configuration by providing a value for the --runtime-config-file flag when invoking the spin up command.

Key Value Store Runtime Configuration

Spin provides built-in key-value storage. This storage is backed by an SQLite database embedded in Spin by default. However, the Spin runtime configuration file (runtime-config.toml) can be updated to not only modify the SQLite configuration but also choose to use a different backing store. The available store options are the embedded SQLite database, an external Redis database or Azure CosmosDB.

The following is an example of how an application’s runtime-config.toml file can be configured to use Redis instead. Note the type and url values, which are set to redis and the URL of the Redis host, respectively:

type = "redis"
url = "redis://localhost"

Similarly, to implement Azure CosmosDB as a backend for Spin’s key/value store, change the type to azure_cosmos and specify your database account details:

type = "azure_cosmos"
key = "<key>"
account = "<cosmos-account>"
database = "<cosmos-database>"
container = "<cosmos-container>"

Note: The CosmosDB container must be created with the default partition key, /id.

Whilst a single default store may be sufficient for certain application use cases, each Spin application can be configured to support multiple stores of any type, as shown in the runtime-config.toml file below:

Note: At present, when deploying an application to Fermyon Cloud only the single “default” key-value store is supported. To see more about Spin support on Fermyon Cloud, visit the limitations documentation:

# This defines a new store named user_data
type = "spin" 
path = ".spin/user_data.db"

# This defines a new store named other_data backed by a Redis database
type = "redis"
url = "redis://localhost"

You must individually grant each component access to the stores that it needs to use. To do this, use the component.key_value_stores entry in the component manifest within spin.toml. See Spin Key Value Store for more details.

SQLite Storage Runtime Configuration

Spin provides built-in SQLite storage. By default, this is backed by a database that Spin creates for you underneath your application directory (in the .spin subdirectory). However, you can use the Spin runtime configuration file (runtime-config.toml) to add and customize SQLite databases.

The following example runtime-config.toml tells Spin to map the default database to an SQLite database elsewhere in the file system:

path = "/planning/todo.db"

If you need more than one database, you can configure multiple databases, each with its own name:

# This defines a new store named todo
path = "/planning/todo.db"

# This defines a new store named finance
path = "/super/secret/monies.db"

Spin creates any database files that don’t exist. However, it is up to you to delete them when you no longer need them.

Spin can also use libSQL databases accessed over HTTPS. libSQL is fully compatible with SQLite but provides additional features including remote, distributed databases.

Spin does not provide libSQL access to file-based databases, only databases served over HTTPS. Specifically, Spin supports the sqld libSQL server.

To use libSQL, set type = "libsql" in your runtime-config.toml entry. You must then provide a url and authentication token instead of a file path. For example, this entry tells Spin to map the default database to a libSQL service running on libsql.example.com:

# This tells Spin to use the remote host as its default database
type = "libsql"
url = "https://sensational-penguin-ahacker.libsql.example.com"
token = "a secret"

Spin does not create libSQL databases. Use your hosting service’s tools to create them (or sqld if you are self-hosting) . You can still set up tables and data in a libSQL database via spin up --sqlite.

You must include the scheme in the url field. The scheme must be http or https. Non-HTTP libSQL protocols are not supported.

The default database will still be defined, even if you add other databases.

By default, components will not have access to any of these databases (even the default one). You must grant each component access to the databases that it needs to use. To do this, use the component.sqlite_databases entry in the component manifest within spin.toml. See SQLite Database for more details.

LLM Runtime Configuration

Spin provides a Large Language Model interface for interacting with LLMs for inferencing and embedding. The default host implementation is to use local CPU/GPU compute. However, the Spin runtime configuration file (runtime-config.toml) can be updated to enable Spin to use remote compute using HTTP requests.

The following is an example of how an application’s runtime-config.toml file can be configured to use the remote compute option. Note the type, url and auth_token are set to remote_http, URL of the server and the auth token for the server.

type = "remote_http"
url = "http://example.com"
auth_token = "<auth_token>"

Currently, the remote compute option requires an user to deploy their own LLM proxy service. Fermyon Cloud users can do this using the cloud-gpu plugin. If you prefer to create and deploy your own proxy service, you can find a reference implementation of the proxy protocol in the spin-cloud-gpu plugin repository.

By default, componenets will not have access to the LLM models unless granted explicit access through the component.ai_models entry in the component manifest within spin.toml. See Serverless AI for more details.