Prerequisites
- A DNS zone you control, for example
acme.com. - An ingress controller, or the AWS Load Balancer Controller for the NLB option below.
- cert-manager with a
ClusterIssuer, or a certificate you provide yourself.
1
Set the ingress values
The gateway is published from the app Ingress settings. Set Replace both hosts. The chart renders a second Ingress,
ingress.gateway.host next to the app hosts:<release>-gateway-ingress, with the same className and annotations. It routes /v1 and /health on the gateway host to the gateway Service. The control plane derives the public URL CLI users get from ingress.gateway.host.With className: nginx the chart adds annotations to the gateway Ingress only. They keep streamed responses unbuffered, let a stream run for an hour, and raise the body limit to 32 MB. Keys in ingress.gateway.annotations override them.2
Issue the certificate
With the To bring your own certificate, create the TLS Secret yourself and drop the
cert-manager.io/cluster-issuer annotation, cert-manager requests a certificate for ingress.host and stores it in ingress.tls.secretName. A DNS-01 issuer works before the DNS record exists:cert-manager.io/cluster-issuer annotation:3
Create the DNS record
Point a CNAME at the ingress controller’s load balancer hostname:Use a CNAME, never an A record: cloud load balancer addresses change.
4
Verify
/health call returns {"status":"ok","checks":{"gateway":"ok","control_plane":"ok"}}. The /v1/models call returns 200 with the models your key can route to. Continue with the post-install checklist.What the ingress publishes
/healthz, /readyz, /startupz, /debug/control-plane and /internal/* stay in-cluster. Metrics are on their own port (9464). The Gemini-native routes under /v1beta are outside the /v1 prefix and are not published by the chart Ingress. To publish them, route /v1beta to the gateway Service with your own route, as described in Routing and ingress controllers.
Cloud load balancer in front of the Service
To terminate TLS on a cloud load balancer instead of the ingress, leaveingress.gateway.host empty and turn the Service into a LoadBalancer. On AWS with the Load Balancer Controller and an ACM certificate:
LoadBalancer publishes every route, including the probes and /debug/control-plane, which returns the resolved LW_GATEWAY_BASE_URL and takes no key. Put a load balancer listener rule or a security group in front of it when the address is public. Set service.internal.enabled: true to also render a ClusterIP Service named langwatch-gateway-internal for in-cluster callers, so they do not go out through the load balancer.
Other ingress controllers
Setingress.className for your controller. The ingress-nginx annotations are added only when className is nginx. Put the controller’s equivalents in ingress.gateway.annotations so they apply to the gateway host only.
Three settings matter for every controller: response buffering off, an idle or read timeout above the longest stream you allow, and a body limit of at least 32 MB. The gateway lets a provider call run up to 14 minutes. Routing and ingress controllers has the full list and an Envoy Gateway HTTPRoute.
AWS ALB example. The certificate comes from ACM rather than ingress.gateway.tls.secretName, so gateway.publicUrl states the https URL the CLI should use:
Outbound endpoint policy
TLS in front of the gateway is one boundary. The other is the provider endpoints that customers configure on their own credentials. Three variables, set throughgateway.security.* in the chart, control them:
Both switches default to
false, so a self-hosted install can route to a model server on the cluster network. Cloud metadata addresses, 0.0.0.0, :: and link-local ranges are refused with every setting. Setting ENVIRONMENT to anything other than local requires both switches to be true.
Common failures
More symptoms are on Troubleshooting.