WebAssembly
    CNCF

    Deploy wasmCloud on a VPS

    CNCF distributed application platform for WebAssembly components, with NATS lattice coordination and declarative wadm orchestration.

    At a Glance

    ProjectwasmCloud (CNCF)
    LicenseApache 2.0
    Recommended PlanRamNode Cloud VPS 2 vCPU / 4-8 GB
    ComponentsNATS + wasmCloud host + wadm + wash
    OSUbuntu 22.04 / 24.04 / 26.04
    1

    Prereqs

    Base packages
    sudo apt update && sudo apt upgrade -y
    sudo apt install -y curl ca-certificates gnupg lsb-release ufw unzip
    2

    NATS with JetStream

    Install nats-server + CLI
    cd /tmp
    curl -L https://github.com/nats-io/nats-server/releases/latest/download/nats-server-v2.10.21-linux-amd64.tar.gz -o nats-server.tar.gz
    tar -xzf nats-server.tar.gz
    sudo install -m 0755 nats-server-*/nats-server /usr/local/bin/nats-server
    
    curl -L https://github.com/nats-io/natscli/releases/latest/download/nats-0.1.5-linux-amd64.zip -o nats-cli.zip
    unzip -j nats-cli.zip 'nats-*/nats' -d /tmp/
    sudo install -m 0755 /tmp/nats /usr/local/bin/nats
    
    sudo useradd --system --create-home --home-dir /var/lib/nats --shell /usr/sbin/nologin nats
    sudo mkdir -p /etc/nats /var/lib/nats/jetstream /var/log/nats
    sudo chown -R nats:nats /var/lib/nats /var/log/nats
    /etc/nats/nats-server.conf
    server_name: wasmcloud-node-1
    host: 127.0.0.1
    port: 4222
    
    jetstream {
        store_dir: /var/lib/nats/jetstream
        domain: core
        max_memory_store: 256MB
        max_file_store: 4GB
    }
    
    logfile: "/var/log/nats/nats-server.log"
    logtime: true
    log_size_limit: 50MB
    http: 127.0.0.1:8222
    max_connections: 4096
    max_payload: 8MB
    systemd unit + start
    sudo tee /etc/systemd/system/nats-server.service > /dev/null <<'EOF'
    [Unit]
    Description=NATS Server
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=simple
    User=nats
    Group=nats
    ExecStart=/usr/local/bin/nats-server -c /etc/nats/nats-server.conf
    ExecReload=/bin/kill -HUP $MAINPID
    Restart=on-failure
    RestartSec=5
    LimitNOFILE=65536
    
    NoNewPrivileges=true
    ProtectSystem=strict
    ProtectHome=true
    PrivateTmp=true
    ReadWritePaths=/var/lib/nats /var/log/nats
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    sudo systemctl daemon-reload
    sudo systemctl enable --now nats-server.service
    nats --server 127.0.0.1:4222 server info | head -20
    3

    Install wash CLI

    From wasmCloud apt repo
    curl -s https://packagecloud.io/install/repositories/wasmcloud/core/script.deb.sh | sudo bash
    sudo apt install -y wash
    wash --version
    4

    wasmCloud Host

    Install + keys
    cd /tmp
    WASMCLOUD_VERSION=$(curl -s https://api.github.com/repos/wasmCloud/wasmCloud/releases/latest | grep tag_name | cut -d '"' -f 4)
    curl -L "https://github.com/wasmCloud/wasmCloud/releases/download/${WASMCLOUD_VERSION}/wasmcloud-x86_64-unknown-linux-gnu.tar.gz" -o wasmcloud.tar.gz
    tar -xzf wasmcloud.tar.gz
    sudo install -m 0755 wasmcloud /usr/local/bin/wasmcloud
    
    sudo useradd --system --create-home --home-dir /var/lib/wasmcloud --shell /usr/sbin/nologin wasmcloud
    sudo mkdir -p /etc/wasmcloud /var/log/wasmcloud
    sudo chown -R wasmcloud:wasmcloud /var/lib/wasmcloud /var/log/wasmcloud
    
    sudo -u wasmcloud bash -c 'cd /var/lib/wasmcloud && wash keys gen cluster > cluster-key.txt && wash keys gen server > host-key.txt'
    sudo -u wasmcloud bash -c "grep 'Seed:' /var/lib/wasmcloud/cluster-key.txt | awk '{print \$2}' > /var/lib/wasmcloud/cluster.seed"
    sudo -u wasmcloud bash -c "grep 'Seed:' /var/lib/wasmcloud/host-key.txt | awk '{print \$2}' > /var/lib/wasmcloud/host.seed"
    sudo chmod 600 /var/lib/wasmcloud/*.seed
    /etc/wasmcloud/host.env
    WASMCLOUD_LATTICE=default
    WASMCLOUD_NATS_HOST=127.0.0.1
    WASMCLOUD_NATS_PORT=4222
    WASMCLOUD_JS_DOMAIN=core
    WASMCLOUD_RPC_TIMEOUT_MS=2000
    WASMCLOUD_LOG_LEVEL=info
    WASMCLOUD_ALLOW_FILE_LOAD=true
    WASMCLOUD_LABEL_environment=production
    WASMCLOUD_LABEL_region=us-central
    systemd unit
    [Unit]
    Description=wasmCloud Host
    After=network-online.target nats-server.service
    Requires=nats-server.service
    
    [Service]
    Type=simple
    User=wasmcloud
    Group=wasmcloud
    WorkingDirectory=/var/lib/wasmcloud
    EnvironmentFile=/etc/wasmcloud/host.env
    ExecStart=/bin/bash -c '/usr/local/bin/wasmcloud --cluster-seed "$(cat /var/lib/wasmcloud/cluster.seed)" --host-seed "$(cat /var/lib/wasmcloud/host.seed)"'
    Restart=on-failure
    RestartSec=10
    LimitNOFILE=65536
    
    NoNewPrivileges=true
    ProtectSystem=strict
    ProtectHome=true
    PrivateTmp=true
    ReadWritePaths=/var/lib/wasmcloud /var/log/wasmcloud
    
    [Install]
    WantedBy=multi-user.target
    5

    wadm Orchestrator

    Install + run
    cd /tmp
    WADM_VERSION=$(curl -s https://api.github.com/repos/wasmCloud/wadm/releases/latest | grep tag_name | cut -d '"' -f 4)
    curl -L "https://github.com/wasmCloud/wadm/releases/download/${WADM_VERSION}/wadm-${WADM_VERSION}-linux-amd64.tar.gz" -o wadm.tar.gz
    tar -xzf wadm.tar.gz
    sudo install -m 0755 wadm-*/wadm /usr/local/bin/wadm
    /etc/systemd/system/wadm.service
    [Unit]
    Description=wasmCloud Application Deployment Manager
    After=network-online.target nats-server.service
    Requires=nats-server.service
    
    [Service]
    Type=simple
    User=wasmcloud
    Group=wasmcloud
    WorkingDirectory=/var/lib/wasmcloud
    Environment=WADM_NATS_SERVER=127.0.0.1:4222
    Environment=WADM_JETSTREAM_DOMAIN=core
    Environment=WADM_STRUCTURED_LOGGING=true
    ExecStart=/usr/local/bin/wadm
    Restart=on-failure
    RestartSec=10
    
    [Install]
    WantedBy=multi-user.target
    Start everything + verify
    sudo systemctl daemon-reload
    sudo systemctl enable --now wasmcloud-host.service wadm.service
    wash get hosts
    6

    Deploy a Sample App

    hello.yaml
    apiVersion: core.oam.dev/v1beta1
    kind: Application
    metadata:
      name: hello-world
    spec:
      components:
        - name: hello
          type: component
          properties:
            image: ghcr.io/wasmcloud/components/http-hello-world-rust:0.1.0
          traits:
            - type: spreadscaler
              properties:
                instances: 1
            - type: link
              properties:
                target: httpserver
                namespace: wasi
                package: http
                interfaces: [incoming-handler]
                source_config:
                  - name: default-http
                    properties:
                      address: 127.0.0.1:8000
    
        - name: httpserver
          type: capability
          properties:
            image: ghcr.io/wasmcloud/http-server:0.23.0
    Deploy
    wash app deploy hello.yaml
    wash app status hello-world
    curl http://127.0.0.1:8000
    7

    Caddy + TLS

    /etc/caddy/Caddyfile
    wasm.example.com {
        encode zstd gzip
        reverse_proxy 127.0.0.1:8000 {
            header_up X-Real-IP {remote_host}
            header_up X-Forwarded-For {remote_host}
        }
        header {
            Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
            X-Content-Type-Options "nosniff"
            -Server
        }
    }
    UFW
    sudo ufw allow 22/tcp && sudo ufw allow 80/tcp && sudo ufw allow 443/tcp
    sudo ufw enable
    8

    Backup + Update Order

    /etc/cron.daily/wasmcloud-backup
    #!/usr/bin/env bash
    set -euo pipefail
    DATE=$(date +%Y%m%d)
    systemctl stop wasmcloud-host wadm
    systemctl stop nats-server
    tar -czf /var/backups/wasmcloud-${DATE}.tar.gz /var/lib/nats /var/lib/wasmcloud
    systemctl start nats-server
    sleep 5
    systemctl start wadm wasmcloud-host

    Update order: NATS first, then wadm, then the wasmCloud host. This avoids hosts/wadm expecting NATS features the running server lacks.