Running Theia IDE in Kubernetes
Blog: IMIXS-WORKFLOW Blog
Theia IDE is a modern, AI-native IDE which can be run on Desktop as also in a Docker container as a Web app. With the Docker image you can deploy Theia IDE in a Kubernetes cluster. The deployment is straightforward — until you try to use extensions that open embedded browser windows. This post explains the problem and how to solve it using wildcard certificates with DNS-01 challenges.
The Problem: Webview Subdomains
Theia uses separate origins for webviews to provide sandbox isolation. When an extension (like the Open-BPMN modeler or other diagram editors) opens a webview, Theia generates dynamic subdomain URLs:
https://<uuid>.webview.ide.yourdomain.comLocally this works fine, but in Kubernetes you’ll see errors like:
<uuid>.webview.ide.yourdomain.com's server IP address could not be foundThe browser can’t resolve these dynamic subdomains, and even if DNS is configured with a wildcard entry, the TLS certificate doesn’t cover them.
The Solution: Let’s Encrypt Wildcard Certificates with DNS-01
Standard HTTP-01 challenges can’t issue wildcard certificates. You need DNS-01 challenges, where Let’s Encrypt verifies domain ownership by checking a TXT record. The principle of DNS-01 works as followed:
- The Cert-manager requests a certificate for
*.webview.ide.yourdomain.com - Let’s Encrypt responds: “Create a TXT record
_acme-challenge.webview.ide.yourdomain.comwith valuexyz123“ - A webhook creates the TXT record via your DNS provider’s API
- Let’s Encrypt verifies and issues the certificate
- The webhook cleans up the TXT record
This requires API access to your DNS provider. Popular options with cert-manager support include Cloudflare, AWS Route53, Google Cloud DNS, and Hetzner.
Implementation with Hetzner DNS
The following example uses Hetzner’s official cert-manager webhook, but the approach is similar for other providers.
1. Install the Webhook
Hetzner provides a helm chart to install a webhook to call the Hetzner API
git clone https://github.com/hetzner/cert-manager-webhook-hetzner.git
cd cert-manager-webhook-hetzner
helm install cert-manager-webhook-hetzner ./chart --namespace cert-manager2. Create API Token Secret
Next you need a API Token to get access to Hetzner API. With this token you can create a kubernetes secret:
kubectl create secret generic hetzner-dns-api-token \
--namespace cert-manager \
--from-literal=api-token="<YOUR-HETZNER-CLOUD-API-TOKEN>"3. Configure ClusterIssuer
Finally you install a new ClusterIssuer to support wildcard certificates. This is an example using the hetzner cert-manager webhook
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod-dns01
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-prod-dns01-key
solvers:
- dns01:
webhook:
groupName: acme.hetzner.com
solverName: hetzner
config:
tokenSecretKeyRef:
name: hetzner-dns-api-token
key: api-token4. DNS Configuration
In your DNS provider you can now register these records to your existing DNS zone:
| Type | Name | Value |
|---|---|---|
| A/CNAME | ide | Your Ingress IP/hostname |
| A/CNAME | *.webview.ide | Your Ingress IP/hostname |
5. Theia Deployment
So finally you can create the Theia IDE deployment using a ingress with wildcard TLS. See the following example:
apiVersion: apps/v1
kind: Deployment
metadata:
name: theia
spec:
template:
spec:
securityContext:
fsGroup: 101 # theia user group
containers:
- name: theia-ide
image: ghcr.io/eclipse-theia/theia-ide/theia-ide:latest
ports:
- containerPort: 3000
volumeMounts:
- mountPath: /home/theia/.theia-ide
name: theia-storage
subPath: theia-ide
- mountPath: /home/project
name: theia-storage
subPath: project
volumes:
- name: theia-storage
persistentVolumeClaim:
claimName: theia-storage
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: theia-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod-dns01"
spec:
ingressClassName: nginx
tls:
- hosts:
- ide.yourdomain.com
- "*.webview.ide.yourdomain.com"
secretName: theia-wildcard-tls
rules:
- host: ide.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: theia
port:
number: 3000
- host: "*.webview.ide.yourdomain.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: theia
port:
number: 3000Verification
After deploying, verify the certificate:
$ kubectl get certificate -n my-namespace
NAME READY SECRET AGE
tls-theia-wildcard True tls-theia-wildcard 8h
Once READY shows True, your Theia IDE is fully operational with webview support.
Note: issuing the wildcard certificate may take some minutes!
Conclusion
Running Theia IDE in Kubernetes with full extension support requires wildcard certificates for the dynamic webview subdomains. Using DNS-01 challenges with your DNS provider’s API makes this fully automated. While this example uses Hetzner, the same pattern works with any DNS provider that has a cert-manager webhook available.
