Get Started
Cosmonic Control runs on any Kubernetes cluster. This guide walks through installing Cosmonic Control and deploying your first workload.
For production deployments, see the Operator Manual or a platform-specific deployment guide.
Cosmonic Control is free to get started. For enterprise use with unlimited HTTPTriggers per namespace, the Project grouping type, and the Artifact pre-fetch controller, contact us.
Prerequisites
1. Set up a cluster
Select your Kubernetes environment:
- Existing cluster
- k3d
- k3s
- kind
If you already have a Kubernetes cluster, skip cluster creation. Verify your kubectl context is pointing to the right cluster:
kubectl cluster-infok3d runs a lightweight k3s cluster inside Docker. It starts in seconds and uses minimal resources.
Map host ports 80 and 443 to the Cosmonic Control Traefik NodePorts (30080 and 30443), and disable k3s's built-in Traefik so it does not conflict with the chart's:
k3d cluster create cosmonic \
--port "80:30080@loadbalancer" \
--port "443:30443@loadbalancer" \
--k3s-arg "--disable=traefik@server:0"k3s is a single-binary Kubernetes distribution with no container runtime dependency. Linux only.
Install k3s with its built-in Traefik disabled (the Cosmonic Control chart deploys its own):
curl -sfL https://get.k3s.io | sh -s - --disable=traefikConfigure kubectl to use the k3s cluster:
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER ~/.kube/configkind runs Kubernetes nodes as Docker containers.
Create a cluster that maps host ports 80 and 443 to the Cosmonic Control Traefik NodePorts (30080 and 30443):
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30080
hostPort: 80
protocol: TCP
- containerPort: 30443
hostPort: 443
protocol: TCP
EOF2. Install Cosmonic Control
The chart deploys Traefik as the edge proxy by default. Install with no overrides:
helm install cosmonic-control oci://ghcr.io/cosmonic/cosmonic-control \
--version 0.4.1 \
--namespace cosmonic-system \
--create-namespaceTo auto-create a Traefik Ingress for one or more workload hosts at install time, pass ingress.hosts to the chart. This skips the manual kubectl apply of an Ingress in step 3:
helm install cosmonic-control oci://ghcr.io/cosmonic/cosmonic-control \
--version 0.4.1 \
--namespace cosmonic-system --create-namespace \
--set 'ingress.hosts[0].host=welcome-tour.localhost.cosmonic.sh'See Ingress and Workloads for the full pattern.
- Existing cluster
- k3d
- k3s
- kind
Traefik is exposed on NodePort 30080 (http) and 30443 (https) inside the cluster. To reach it externally on a cloud cluster, either:
-
Patch the Traefik Service to
LoadBalancerso the cloud provisions an LB:kubectl patch svc traefik -n cosmonic-system -p '{"spec":{"type":"LoadBalancer"}}' -
Or front the Traefik NodePorts with an existing cloud or in-cluster load balancer.
For other ingress topologies (Istio, or exposing Envoy directly without the edge proxy), see Ingress and Workloads.
The host ports configured during cluster creation already forward to Traefik's NodePorts. No extra steps are needed.
Traefik's NodePorts (30080/30443) are reachable directly on the node. To reach Traefik on host port 80 instead, patch the Service to LoadBalancer and let k3s's built-in klipper-lb claim the host port:
kubectl patch svc traefik -n cosmonic-system -p '{"spec":{"type":"LoadBalancer"}}'The extraPortMappings configured during cluster creation already forward host 80 and 443 to Traefik's NodePorts. No extra steps are needed.
Wait for all components to be ready:
kubectl rollout status deploy -l app.kubernetes.io/instance=cosmonic-control -n cosmonic-systemInstall a HostGroup:
helm install hostgroup oci://ghcr.io/cosmonic/cosmonic-control-hostgroup \
--version 0.4.1 \
--namespace cosmonic-systemkubectl rollout status deploy -l app.kubernetes.io/instance=hostgroup -n cosmonic-systemFor workloads that import wasi:webgpu/webgpu@0.0.1, pass --set gpu=true so the host advertises the WebGPU interface. Without it, the workload sticks at WORKLOAD_STATE_ERROR because hostInterfaces acts as a scheduling filter — declaring an interface the host does not advertise prevents placement, not just linking.
helm install hostgroup oci://ghcr.io/cosmonic/cosmonic-control-hostgroup \
--version 0.4.1 \
--namespace cosmonic-system \
--set gpu=trueThe host pod must run on a node with a usable GPU exposed to it (Metal, Vulkan, or DX12 via wgpu); on managed clusters this typically means a GPU node pool plus the appropriate device-plugin daemonset.
The hostgroup chart pulls ghcr.io/cosmonic/control-host:<appVersion> by default. To run a pre-release build (for example, canary published from cosmonic/control main), override image.tag:
helm upgrade --install hostgroup oci://ghcr.io/cosmonic/cosmonic-control-hostgroup \
--version 0.4.1 \
--namespace cosmonic-system \
--reuse-values \
--set image.tag=canary3. Deploy a workload
Deploy welcome-tour to verify everything is working end-to-end:
helm install welcome-tour --version 0.1.2 \
oci://ghcr.io/cosmonic-labs/charts/http-trigger \
-f https://raw.githubusercontent.com/cosmonic-labs/control-demos/refs/heads/main/welcome-tour/values.http-trigger.yamlWait for the workload's READY status to be TRUE:
kubectl get workloadsCreate a Traefik Ingress so external traffic for the workload's host reaches Envoy:
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: welcome-tour
namespace: cosmonic-system
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
spec:
ingressClassName: traefik
rules:
- host: welcome-tour.localhost.cosmonic.sh
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ingress
port:
number: 80
EOFOpen http://welcome-tour.localhost.cosmonic.sh in your browser.
localhost.cosmonic.sh is a public wildcard DNS entry that resolves to 127.0.0.1, so no /etc/hosts edits are required. For cloud or remote clusters, use the Traefik LoadBalancer service's external IP with the Host: welcome-tour.localhost.cosmonic.sh header. For k3s without a LoadBalancer patch, append :30080 to the URL.
Next steps
- Explore more examples — browse the Template Catalog for additional Wasm component demos
- Build your own component — see the wasmCloud Developer Guide to build and publish a Wasm component
- Deploy to production — see the Operator Manual for production-grade configuration, HostGroup scaling, and ingress setup
Cleaning up
- Existing cluster
- k3d
- k3s
- kind
helm uninstall welcome-tour
helm uninstall hostgroup -n cosmonic-system
helm uninstall cosmonic-control -n cosmonic-system
kubectl delete ns cosmonic-systemThe fastest way to clean up is to delete the entire cluster:
k3d cluster delete cosmonicTo remove only the Cosmonic Control workloads while keeping the cluster:
helm uninstall welcome-tour
helm uninstall hostgroup -n cosmonic-system
helm uninstall cosmonic-control -n cosmonic-system
kubectl delete ns cosmonic-systemRemove the Cosmonic Control workloads:
helm uninstall welcome-tour
helm uninstall hostgroup -n cosmonic-system
helm uninstall cosmonic-control -n cosmonic-system
kubectl delete ns cosmonic-systemTo remove k3s entirely:
sudo /usr/local/bin/k3s-uninstall.shThe fastest way to clean up is to delete the entire cluster:
kind delete clusterTo remove only the Cosmonic Control workloads while keeping the cluster:
helm uninstall welcome-tour
helm uninstall hostgroup -n cosmonic-system
helm uninstall cosmonic-control -n cosmonic-system
kubectl delete ns cosmonic-systemFrequently asked questions
Can I install the chart with a Helm 3 version prior to v3.8.0?
In versions of Helm 3 prior to v3.8.0, OCI support was experimental. You can run export HELM_EXPERIMENTAL_OCI=1 to enable it, but some OCI functionality may behave differently. See the Helm documentation for details.
How do I mirror images to my own internal registry?
Use the global.image.registry and global.image.pullSecrets Helm values to point to your registry. See the Air-Gapped Installation guide for a full example using ORAS.
