Helm: Getting started

Prerequisites

  • A running Kubernetes cluster (1.24+)

  • Helm 3.x

  • kubectl configured to access your cluster

Installation

  1. Create a values-local.yaml file with your deployment settings. At minimum, you must configure:

    zulip:
      environment:
        SETTING_EXTERNAL_HOST: zulip.example.com
        SETTING_ZULIP_ADMINISTRATOR: "admin@example.com"
        SECRETS_secret_key: "replace-with-a-secure-secret-key"
    

    You should also set passwords for the dependency services:

    memcached:
      auth:
        password: "replace-with-secure-password"
    rabbitmq:
      auth:
        password: "replace-with-secure-password"
        erlangCookie: "replace-with-secure-cookie"
    redis:
      auth:
        password: "replace-with-secure-password"
    postgresql:
      auth:
        postgresPassword: "replace-with-secure-password"
        password: "replace-with-secure-password"
    

    See Helm: Configuring settings for more configuration options, and values-local.yaml.example for a starting template.

  2. Install the chart from GHCR:

    helm install zulip oci://ghcr.io/zulip/helm-charts/zulip -f values-local.yaml
    

    Zulip takes several minutes to start up on first boot. You can watch the pod status with:

    kubectl get pods -w
    

    Note

    The bundled RabbitMQ runs as a Kubernetes-native clustered deployment: each node queries the Kubernetes API (through its ServiceAccount RBAC) for its peers and resolves its own *.svc.cluster.local headless DNS name. On hardened clusters this can stop it from starting — for example a default-deny NetworkPolicy blocking the API server, restricted RBAC, a non-default cluster domain, or a memory limit too low for the Erlang VM. If the RabbitMQ pod never becomes ready, point Zulip at an external RabbitMQ server instead.

  3. Once the pod is ready, generate a link to create your first organization:

    kubectl exec zulip-0 -c zulip -- \
        runuser -u zulip -- \
        /home/zulip/deployments/current/manage.py \
        generate_realm_creation_link
    
  4. If you have configured an Ingress, open the link in a browser. Otherwise, you can use kubectl port-forward to access the server locally:

    kubectl port-forward svc/zulip 8080:80
    

    Then visit http://localhost:8080 in your browser.

Next steps

Local development with Minikube

Minikube provides a local single-node Kubernetes cluster for development. Zulip requires TLS (or at least an Ingress) to function correctly, so a few extra setup steps are needed.

  1. Enable the Ingress addon:

    minikube addons enable ingress
    
  2. Install cert-manager to handle TLS certificates:

    kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.2/cert-manager.yaml
    

    Wait for the cert-manager pods to be ready:

    kubectl -n cert-manager wait --for=condition=Ready pods --all --timeout=120s
    
  3. Create a ClusterIssuer that issues self-signed certificates:

    kubectl apply -f - <<'EOF'
    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: selfsigned
    spec:
      selfSigned: {}
    EOF
    
  4. Point a hostname at your Minikube IP. Add a line to /etc/hosts:

    <minikube-ip>  zulip.local
    

    You can get the IP with minikube ip.

  5. Follow the installation steps above, setting SETTING_EXTERNAL_HOST to zulip.local and enabling the Ingress with the self-signed issuer:

    zulip:
      environment:
        SETTING_EXTERNAL_HOST: zulip.local
    ingress:
      enabled: true
      className: nginx
      annotations:
        cert-manager.io/cluster-issuer: selfsigned
      hosts:
        - host: zulip.local
          paths:
            - path: /
      tls:
        - secretName: zulip-tls
          hosts:
            - zulip.local
    

    Then open https://zulip.local in your browser (accepting the self-signed certificate warning).

See also