Skip to main content

From Laptop to Cluster

A workload you shape in Cosmonic Desktop doesn't need to be rewritten or repackaged to run in production. Desktop and Cosmonic Control run the same runtime and speak the same Workload specification (runtime.wasmcloud.dev/v1alpha1)—so the YAML on your laptop is the same artifact your cluster runs, governed by the same platform controls (namespaces, RBAC, GitOps, quotas) as everything else you operate on Kubernetes.

This page takes a workload from Desktop to a Cosmonic Control cluster.

Overview​

The following elements carry over unchanged:

  • The component image—the same digest-pinned OCI artifact, pulled from the same registry.
  • Configuration—the component still reads its config through wasi:config; only the source of values changes (see below).
  • allowedHosts—your outbound-network allowlist is enforced identically at the runtime level on the cluster. Deny-by-default on your laptop is deny-by-default in production.
  • hostInterfaces—the capabilities the component was granted locally are the capabilities it gets on the cluster.

1. Get your workload's spec​

Your workload lives as plain YAML in Desktop's state directory, at workloads/<namespace>/<name>.yaml (run cosmonicd paths—where the binary lives—to locate the state directory on your platform). For the quickstart's hello-world, the interesting part looks like:

spec:
  components:
    - name: hello-world
      image: ghcr.io/cosmonic-labs/control-demos/hello-world@sha256:…

2. Wrap it in a WorkloadDeployment​

On Cosmonic Control, workloads are managed through a WorkloadDeployment, and an HTTP-serving component also gets an HTTPTrigger that routes traffic to it. The WorkloadDeployment's template.spec is your Workload spec; the wrapper adds the cluster-side concerns Desktop didn't need: replicas and, through the trigger, an ingress hostname.

Side-by-side diagram. Left, &quot;On your laptop — Cosmonic Desktop&quot;: the file workloads/default/hello-world.yaml with its spec block (components, name, digest-pinned image) outlined in purple and labeled &quot;the Workload spec&quot;. An arrow labeled &quot;unchanged&quot; points right. Right, &quot;On the cluster — Cosmonic Control&quot;: a WorkloadDeployment manifest with replicas, deployPolicy, and template fields, containing the same purple-outlined spec block nested inside template. Caption: the WorkloadDeployment adds cluster concerns around the spec and never rewrites it; an HTTPTrigger routes traffic to it.

apiVersion: runtime.wasmcloud.dev/v1alpha1
kind: WorkloadDeployment
metadata:
  name: hello-world
  namespace: default
spec:
  replicas: 1
  template:
    spec:
      hostInterfaces:
        - namespace: wasi
          package: http
          interfaces:
            - incoming-handler
          config:
            host: hello.localhost.cosmonic.sh
      components:
        - name: hello-world
          image: ghcr.io/cosmonic-labs/control-demos/hello-world@sha256:…
---
apiVersion: control.cosmonic.io/v1alpha2
kind: HTTPTrigger
metadata:
  name: hello-world
  namespace: default
spec:
  hostnames:
    - hello.localhost.cosmonic.sh
  rules:
    - backendRefs:
        - name: hello-world

Keep the hostInterfaces your Desktop spec already declares. If it does not declare the inbound wasi:http interface, add it as above, and set config.host to the hostname the cluster serves. This is the shape Cosmonic Control v0.13.0 and later accept; earlier releases embedded the spec in the HTTPTrigger itself.

Apply it like any other Kubernetes resource:

kubectl apply -f hello-world.yaml

Because it's a standard manifest, the production-grade path is the one your platform already uses: commit the YAML to Git and let your GitOps tooling deliver it.

3. Translate the local-only pieces​

Three things are intentionally machine-local in Desktop and have cluster-side equivalents rather than direct copies:

On your laptopOn the cluster
Secret references into your OS keychain / 1Password / AWS Secrets ManagersecretFrom references to Kubernetes Secrets—the component still never sees plaintext in the manifest
Inline config edited in the appInline config, or configFrom ConfigMap references
hostPath volumes under your home directoryCluster-appropriate storage—laptop filesystem paths won't exist on nodes

If your image lives in a private registry, the cluster needs its own registry credentials.

4. Route traffic and verify​

The hostname in the trigger's spec.hostnames is served by Control's ingress proxy, which routes by Host header. That's the same model as Desktop's local ingress on 127.0.0.1:8200, but at cluster scale. See Ingress and Workloads for wiring external DNS and TLS.

curl http://hello.localhost.cosmonic.sh/

The reconciliation model is also the same one you watched in Desktop's Logs view: declared state versus observed state, converged by the platform. kubectl get workloaddeployments, kubectl get httptriggers and workload events tell you what the reconciler is doing.

The spec is the contract: what you reviewed and approved locally (image digest, capabilities, network reach) is what production enforces, governed with the Kubernetes machinery your platform team already trusts.

Next steps​

  • Set up a cluster with the Cosmonic Control install guide.
  • Read how Control delivers configuration and secrets to components.
  • Going the other direction? Any Workload spec from a Control cluster runs in Desktop too—paste the component's image reference into Start workload and review the draft.