For the complete documentation index, see llms.txt.
Skip to main content
Version: 8.10

Configure the Helm chart with Ingress

caution

Starting with Camunda 8.8, the separated Ingress configuration is no longer supported. Instead, follow the combined Ingress setup described in this guide. If you want to replicate the behavior of the previous separated Ingress approach, check separated Ingress migration.

Camunda 8 Self-Managed has multiple web applications and gRPC services. You can expose them externally with a combined Ingress setup.

Prerequisites​

  • An Ingress controller deployed in advance. The examples below use the Ingress-nginx controller, but you can use any Ingress controller by setting global.ingress.className (and orchestration.ingress.grpc.className for the Zeebe gRPC Ingress).
  • The annotations your controller needs. Starting with Camunda 8.10 (chart 15.x), the chart's default Ingress-nginx annotation set comes from a compatibility shim that you can turn off with global.compatibility.nginx.renderAnnotations: false; see Ingress-nginx annotation defaults deprecated in the Helm chart.
note

Ingress-nginx reached end of life in March 2026. The Camunda 8 reference architectures deploy Contour instead. The examples on this page still use Ingress-nginx annotations. With another controller, translate them to its equivalents. See configure the gRPC upstream for the gRPC annotation each controller expects.

  • TLS configuration is not included in the examples because it varies between different workflows. Configure TLS in one of these ways:
    • Use ingress.tls options directly.
    • Use an external tool such as Cert-Manager with ingress.annotations.
      For more information, see the available configuration options.
note

Camunda 8 Helm chart only deploys Ingress resources. It does not manage or deploy Ingress controllers. You must have an Ingress controller running in your cluster.

Configuration​

In this configuration, two Ingress objects are created:

  • Web applications: One Ingress object for all Camunda 8 web applications using one domain. Each application has a sub-path. For example, camunda.example.com/operate, camunda.example.com/optimize.
  • Zeebe Gateway: Another Ingress object using the gRPC protocol for Zeebe Gateway. For example, zeebe.camunda.example.com.

By default, all web applications use / as a base, so we just need to set the context path, Ingress configuration, and authentication redirect URLs.

note

For Operate, Tasklist, Optimize, Modeler, Connectors, and Console, the Ingress path (global.identity.auth.<component>.redirectUrl) must match the contextPath for that component.

Example configuration​

# Chart values for the Camunda 8 Helm chart in combined Ingress setup.

# This file deliberately contains only the values that differ from the defaults.
# For changes and documentation, use your favorite diff tool to compare it with:
# https://artifacthub.io/packages/helm/camunda/camunda-platform

# IMPORTANT: Make sure to change "camunda.example.com" to your domain.

global:
host: "camunda.example.com"
ingress:
enabled: true
className: nginx
identity:
auth:
publicIssuerUrl: "https://camunda.example.com/auth/realms/camunda-platform"
optimize:
redirectUrl: "https://camunda.example.com/optimize"
webModeler:
redirectUrl: "https://camunda.example.com/modeler"
console:
redirectUrl: "https://camunda.example.com/console"

identity:
contextPath: "/identity"
fullURL: "https://camunda.example.com/identity"

optimize:
contextPath: "/optimize"

orchestration:
contextPath: "/orchestration"
ingress:
grpc:
enabled: true
className: nginx
host: "zeebe.camunda.example.com"

webModeler:
# The context path is used for the web application that will be accessed by users in the browser.
# In addition, a WebSocket endpoint will be exposed on "[contextPath]-ws", e.g. "/modeler-ws".
contextPath: "/modeler"

console:
contextPath: "/console"

connectors:
contextPath: "/connectors"

Incorporate these custom values into the values file you use to deploy Camunda (see Install Camunda with Helm):

helm install camunda camunda/camunda-platform --version $HELM_CHART_VERSION -f values-combined-ingress.yaml

After deployment, access the Camunda 8 components at:

  • Management Applications: https://camunda.example.com/[identity|modeler|console]
  • Core Orchestration Applications and REST API: https://camunda.example.com/orchestration/[identity|operate|optimize|tasklist|v2]
  • Web Modeler WebSocket: Web Modeler exposes a WebSocket endpoint on https://camunda.example.com/modeler-ws. This is only used internally by the application and not for direct user access.
  • Keycloak authentication: https://camunda.example.com/auth
  • Zeebe gRPC Gateway: grpc://zeebe.camunda.example.com
note

This configuration shows only the Ingress-related values for webModelerand Console. For full setup, see Enable additional components.

Configure custom public ports​

Set global.ingress.publicPorts when clients reach your Ingress controller on ports other than 80 and 443. For example, a local cluster that can't bind the standard ports might map the Ingress controller to host ports 8080 and 8443.

ParameterTypeDefaultDescription
global.ingress.publicPorts.httpinteger80The public port for Ingress endpoints with TLS disabled.
global.ingress.publicPorts.httpsinteger443The public port for Ingress endpoints with TLS enabled.

Both values accept integers from 1 to 65535. The chart omits port 80 from HTTP URLs and port 443 from HTTPS URLs.

The TLS setting for each Ingress determines which public port the chart uses. For web applications, the chart uses global.ingress.tls.enabled. For the Zeebe gRPC Ingress, it uses orchestration.ingress.grpc.tls.enabled, even when global.ingress.enabled is false.

Setting a public port doesn't enable TLS.

The chart adds the public port to the URLs it derives from global.host and the Zeebe gRPC Ingress host:

  • Links in the installation notes and release information.
  • The Identity URL and its login callback, if identity.fullURL is empty.
  • The WebSocket port browsers use to connect to Web Modeler, if Web Modeler has a context path.

The chart doesn't rewrite URLs you configure explicitly. Include the port in identity.fullURL, global.identity.auth.publicIssuerUrl, and each global.identity.auth.<component>.redirectUrl.

Public ports change only the generated URLs. They don't configure Ingress controller listeners, Kubernetes Services, or host port mappings. Configure your Ingress controller and cluster to expose the required ports.

The Gateway API integration doesn't use these values. To change the Gateway listener ports, see custom listener ports.

The following example configures the generated web application URLs to use HTTPS on public port 8443:

global:
host: "camunda.example.com"
ingress:
enabled: true
className: nginx
tls:
enabled: true
secretName: camunda-platform
publicPorts:
https: 8443
identity:
auth:
publicIssuerUrl: "https://camunda.example.com:8443/auth/realms/camunda-platform"
optimize:
redirectUrl: "https://camunda.example.com:8443/optimize"
webModeler:
redirectUrl: "https://camunda.example.com:8443/modeler"
console:
redirectUrl: "https://camunda.example.com:8443/console"

identity:
contextPath: "/identity"
fullURL: "https://camunda.example.com:8443/identity"

Route traffic with your own resources​

Set global.ingress.external: true when a service mesh or routing resources you manage send traffic to Camunda instead of the chart's Ingress objects.

global:
host: "camunda.example.com"
ingress:
enabled: true
external: true

orchestration:
ingress:
grpc:
enabled: true
external: true
host: "zeebe.camunda.example.com"

With global.ingress.external: true, the chart doesn't render any web application Ingress object. The setting has no effect if global.ingress.enabled is false.

The chart still derives external URLs from global.host, the component context paths, global.ingress.protocol, and global.ingress.publicPorts. The chart uses these URLs for:

  • Links in the installation notes and release information.
  • The Identity URL and its login callback, if identity.fullURL is empty.
  • The WebSocket host, port, and path browsers use to connect to Web Modeler, if Web Modeler has a context path.

Configure your routing resources to serve each component on these URLs. If clients reach Camunda over HTTPS, set global.ingress.protocol: https.

global.ingress.external doesn't affect the Zeebe gRPC Ingress. To skip the gRPC Ingress, set orchestration.ingress.grpc.external: true. The chart still derives the gRPC URL from orchestration.ingress.grpc.host.

If a service mesh or your own routing resources send traffic to Camunda, use global.ingress.external: true instead of global.ingress.enabled: false:

ValuesChart renders Ingress objectsURL sourceUse when
global.ingress.enabled: trueYesglobal.hostThe chart's Ingress objects route traffic.
global.ingress.enabled: true and global.ingress.external: trueNoglobal.hostA service mesh or your own routing resources route traffic.
global.ingress.enabled: falseNolocalhost defaultsYou access components with port forwarding.

If you manage Gateway API resources yourself, use global.gateway.external instead. See manage all resources yourself.

Separated Ingress migration​

As the separated Ingress was removed in Camunda 8.8, there are two options for migration:

  1. Recommended: Use the combined Ingress configuration.
  2. Alternative: You can use global.extraManifests to define and deploy your own Ingress objects, providing functionality similar to the former separated Ingress setup.

The example below demonstrates how to add an Ingress object for Optimize, replicating the separated Ingress behavior. You can apply the same approach to create additional Ingress objects for other components, as needed.

# values-separated-ingress.yaml
global:
extraManifests:
- |
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: camunda-platform-optimize
namespace: camunda-dev
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTP
nginx.ingress.kubernetes.io/proxy-body-size: 10m
nginx.ingress.kubernetes.io/proxy-buffer-size: 128k
nginx.ingress.kubernetes.io/proxy-buffering: "on"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
ingressClassName: nginx
rules:
- host: optimize.example.com
http:
paths:
- backend:
service:
name: camunda-platform-optimize
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- optimize.example.com
secretName: camunda-platform-optimize-tls
- |
[Add more Ingresses as needed]

Please note that, you need to create all resources referenced by the objects in global.extraManifests, such as the TLS secret camunda-platform-optimize-tls.

Ingress controllers​

Ingress resources require the cluster to have a running Ingress Controller. There are many options for configuring your Ingress Controller. If you use a cloud provider such as AWS or GCP, follow their Ingress setup guides if an Ingress Controller is not already pre-installed. For AWS EKS Ingress configuration, see Install Camunda 8 on an EKS cluster.

Local setup example​

An Ingress controller is also required for local Camunda 8 installation. The following example shows an Ingress controller configuration using the Ingress-nginx controller:

# ingress_nginx_values.yml
controller:
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
service:
type: NodePort

publishService:
enabled: false

Install the Ingress-nginx controller to your local cluster:

helm install -f ingress_nginx_values.yml \
ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--version "4.9.0" \
--namespace ingress-nginx \
--create-namespace

If your local cluster exposes the Ingress controller on ports other than 80 and 443, set the ports as described in configure custom public ports.

Configure the gRPC upstream​

Configure your Ingress controller to send HTTP/2 to the Orchestration Cluster, because the Zeebe Gateway serves gRPC. Each controller declares the gRPC upstream differently, and not on the same object:

Ingress controllerAnnotationObject
Contourprojectcontour.io/upstream-protocol.h2c: "26500"Orchestration Cluster Service
Ingress-nginxnginx.ingress.kubernetes.io/backend-protocol: GRPCZeebe Ingress (added by the Helm chart)

When the upstream itself uses TLS, use projectcontour.io/upstream-protocol.h2 with Contour, and nginx.ingress.kubernetes.io/backend-protocol: GRPCS with Ingress-nginx. For other controllers, check their documentation for the equivalent.

With Contour, set the annotation on the Orchestration Cluster service:

orchestration:
service:
annotations:
projectcontour.io/upstream-protocol.h2c: "26500"

Use an AWS Application Load Balancer​

An AWS Application Load Balancer (ALB) terminates TLS at the load balancer with a certificate from AWS Certificate Manager (ACM). For the limits, see the ALB known limitations.

  1. Deploy the AWS Load Balancer Controller.

  2. Set up a certificate in AWS Certificate Manager.

  3. Set the alb class on every Ingress object the chart renders. The web application Ingress objects read global.ingress, and the Zeebe gRPC Ingress reads orchestration.ingress.grpc.

  4. Set alb.ingress.kubernetes.io/backend-protocol-version: GRPC only on the Zeebe gRPC Ingress, as in the AWS gRPC example. On a web application Ingress, this annotation makes the ALB target groups use gRPC and breaks the HTTP applications.

  5. Add the values to your values.yaml file:

    global:
    compatibility:
    nginx:
    # Stop the chart from adding its default Ingress-nginx annotations.
    renderAnnotations: false
    ingress:
    className: alb
    # TLS terminates at the ALB. An empty secretName lists the hosts without a Secret.
    tls:
    enabled: true
    secretName: ""
    annotations:
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip

    orchestration:
    ingress:
    grpc:
    className: alb
    tls:
    enabled: true
    secretName: ""
    annotations:
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    alb.ingress.kubernetes.io/backend-protocol-version: GRPC
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip

The ALB terminates TLS with the ACM certificate, so you don't need a TLS Secret. With tls.enabled: true and an empty secretName, the chart lists each host under the Ingress tls field without a Secret. The AWS Load Balancer Controller uses these hosts to find the matching ACM certificate. The chart also uses https in the URLs it generates, for example in the release information.

Use the GKE Ingress​

With the GKE Ingress (Ingress-gce), you may need cloud.google.com/app-protocols annotations on the Zeebe Gateway service. For details, see the GKE guide using HTTP/2 for load balancing with Ingress.

Troubleshooting​

If Ingress is not working as expected, see Camunda components troubleshooting.