Helm: Configuring TLS
In a Kubernetes deployment, TLS is typically terminated at the Ingress controller rather than inside the Zulip container itself. By default, the Helm chart serves unencrypted HTTP on port 80 and expects a TLS-terminating Ingress or load balancer in front of it.
Using an Ingress with cert-manager
The recommended production setup uses an Ingress controller (such as Traefik) combined with cert-manager for automatic TLS certificate provisioning from Let’s Encrypt.
Install an Ingress controller and cert-manager in your cluster. Refer to their respective documentation for installation instructions.
Create a
ClusterIssuerfor Let’s Encrypt (if you don’t already have one):apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: admin@example.com privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: ingressClassName: traefik
Enable the Ingress in your values file:
ingress: enabled: true className: traefik annotations: cert-manager.io/cluster-issuer: letsencrypt-prod hosts: - host: zulip.example.com paths: - path: / tls: - secretName: zulip-tls hosts: - zulip.example.com
Ensure
SETTING_EXTERNAL_HOSTmatches the Ingress host:zulip: environment: SETTING_EXTERNAL_HOST: zulip.example.com
Install or upgrade the chart:
helm upgrade --install zulip oci://ghcr.io/zulip/helm-charts/zulip \ -f values-local.yaml
cert-manager will automatically provision a TLS certificate and store it in the
zulip-tlsSecret.
Using a pre-existing TLS secret
If you manage TLS certificates outside of cert-manager, you can reference an existing Kubernetes TLS Secret:
Create the Secret with your certificate and key:
kubectl create secret tls zulip-tls \ --cert=path/to/tls.crt \ --key=path/to/tls.key
Reference the secret in your Ingress configuration:
ingress: enabled: true className: traefik hosts: - host: zulip.example.com paths: - path: / tls: - secretName: zulip-tls hosts: - zulip.example.com
Using a cloud load balancer
If you prefer to terminate TLS at a cloud load balancer (e.g. AWS NLB, GCP
Load Balancer) instead of using an Ingress, you can configure the Service as
type LoadBalancer:
service:
type: LoadBalancer
port: 443
annotations:
# AWS NLB example:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:...
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
Consult your cloud provider’s documentation for the appropriate annotations.
Container-level TLS
While not recommended for Kubernetes deployments (since TLS is normally handled by the Ingress or load balancer), the chart also supports TLS termination inside the Zulip container itself by setting CERTIFICATES:
zulip:
environment:
CERTIFICATES: self-signed
When CERTIFICATES is set to a non-empty value, the Service’s targetPort
switches from http (port 80) to https (port 443) automatically.