Ingress & TLS (Kubernetes)
Expose KubeWatch on Kubernetes through ingress-nginx or an AWS ALB, with automatic HTTPS, or on the load balancer's own endpoint.
The Helm chart ships an Ingress that fronts the whole platform. Enable it with
ingress.enabled=true. This page covers the two common setups, ingress-nginx
(with cert-manager) and AWS ALB (with ACM), plus running on the load balancer's
own endpoint without a custom domain.
How routing works
The Ingress splits traffic the same way the Docker/Caddy deployment does:
/api/*,/auth/*,/ws*go to the gateway- everything else (dashboard pages and assets) goes to the frontend
ingress.host is optional. Leave it empty (host: "") and the rule matches any
Host header, so you can reach the app on the load balancer's own DNS name
without owning a domain.
ingress-nginx (with cert-manager)
Requires an ingress-nginx controller and (for automatic HTTPS) cert-manager with a ClusterIssuer.
# values.yaml
ingress:
enabled: true
className: nginx
host: kubewatch.your-company.com
tls: true
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
# Keep live-log SSE streams and WebSockets alive (default nginx timeout is 60s):
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
With tls: true, the chart adds a TLS block backed by the {release}-tls
Secret, which cert-manager fills once it issues the certificate for host.
Point your domain's DNS at the ingress-nginx load balancer, then apply:
helm upgrade --install kubewatch \
https://raw.githubusercontent.com/lloyd-theophilus/kubewatch-releases/main/kubewatch.tgz \
-f values.yaml
AWS ALB (with ACM)
Requires the AWS Load Balancer Controller.
TLS is terminated at the ALB using an ACM certificate, so you do NOT set
ingress.tls, and there is no Kubernetes TLS Secret. The certificate is
referenced by annotation instead.
# values.yaml
ingress:
enabled: true
className: alb
host: kubewatch.your-company.com # or "" to use the ALB's own DNS name
tls: false # ALB terminates TLS via ACM, not a K8s Secret
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80},{"HTTPS":443}]'
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:REGION:ACCOUNT:certificate/ID
alb.ingress.kubernetes.io/ssl-redirect: "443"
# Raise the ALB idle timeout so live-log SSE streams / WebSockets aren't cut at 60s:
alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=3600
After helm upgrade, get the ALB's DNS name and point your domain at it with a
CNAME (or a Route 53 alias):
kubectl get ingress kubewatch-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
No domain: the load balancer endpoint
To reach the app without a custom domain, leave the host empty:
ingress:
enabled: true
className: nginx # or alb
host: "" # match any Host, serve on the LB's own DNS name
tls: false
Then open the load balancer's address:
- ingress-nginx: the external IP/hostname of the
ingress-nginx-controllerService (kubectl get svc -n ingress-nginx). - AWS ALB: the ALB DNS name from the
kubectl get ingresscommand above.
Live logs and WebSockets
The dashboard streams container/pod logs over long-lived HTTP (SSE) and uses a
WebSocket for live updates. Load balancers cut idle connections by default
(often 60s), which shows up as logs that stop after a minute. The timeout
annotations above (proxy-read-timeout for nginx, idle_timeout.timeout_seconds
for ALB) keep those streams open, so set them whenever you enable ingress.
Verify
kubectl get ingress
# Then, from a machine that can resolve the host:
curl -ksS https://kubewatch.your-company.com/api/v1/health # gateway → 200
curl -ksS https://kubewatch.your-company.com/ # dashboard HTML
If /api/v1/health returns 200 but / does not serve the dashboard, the
Ingress isn't routing non-API paths to the frontend, double-check you're on a
chart version that splits the routes (this page's behavior).