Skip to main content
Version: 8.8

Deploy Camunda 8 to a local kind cluster

With this guide, you'll deploy Camunda 8 Self-Managed to a local Kubernetes cluster using kind (Kubernetes in Docker). The setup is optimized for learning, development, and testing, with reduced resource requirements suitable for a personal machine.

While this guide uses kind, the same concepts apply to other local Kubernetes tools, like K3s, minikube, or MicroK8s.

Local development only

This setup is intended for local development only and shouldn't be used in production environments. For production deployments, follow our cloud provider guides.

If you encounter issues during deployment, refer to the Troubleshooting section.

Deployment modes

You can choose from two deployment modes:

ModeAccessRequirementsUse case
Domainhttps://camunda.example.commkcert, hosts file modificationFull TLS setup, realistic environment
No-domainlocalhost via port-forwardhosts file modificationQuick setup, minimal configuration

How domain mode works

In domain mode, you'll simulate a production-like environment locally with:

  • Local DNS resolution
    • You'll configure your machine's /etc/hosts file to resolve camunda.example.com to 127.0.0.1.
    • Inside the cluster, you'll configure CoreDNS to rewrite DNS queries for this domain to the Ingress controller, allowing pods to communicate with each other using the same domain name.
  • TLS certificates with mkcert
    • You'll use mkcert to generate locally-trusted certificates by installing a local Certificate Authority (CA) in your system's trust store. This allows your browser to trust the self-signed certificates without security warnings.
    • You'll also mount the CA certificate in the pods that need to make HTTPS calls to other Camunda components.
Firefox compatibility

mkcert requires NSS to work properly with Firefox. Without it, Firefox will display certificate errors. We recommend using Chrome or Chromium-based browsers for the best experience with domain mode.

Prerequisites

Before you begin, you'll need:

tip

You can also use asdf to install the tools, with the versions defined in .tool-versions.

Outcome

By the end of this tutorial, you'll have:

  • A local Kubernetes cluster running with kind. This includes one control plane and two worker nodes.
  • An Ingress NGINX controller deployed for routing traffic (domain mode only).
  • TLS certificates configured with mkcert (domain mode only).
  • Camunda 8 Self-Managed fully deployed and accessible.
Other installation profiles

With this guide, you deploy the full Camunda 8 platform with all components. For lighter setups or specific use cases, see the Helm installation guide, which covers different installation profiles, such as core only, with Connectors, and with Web Modeler.

Download the reference architecture

Download the reference architecture files you'll use throughout this guide:

8.8/local/kubernetes/kind-single-region/procedure/get-your-copy.sh
loading...

You'll run all subsequent commands from camunda-deployment-references/local/kubernetes/kind-single-region/.

Before proceeding, take some time to explore the repository structure and understand the configuration files, scripts, and Helm values. This will help you understand what each step does and how to customize the deployment for your needs.

Quick setup with Makefile

The reference architecture includes a Makefile with useful commands to automate the entire deployment process. For a quick setup, you can use:

  • make domain.init — Full setup with TLS (requires mkcert)
  • make no-domain.init — Full setup without TLS (uses port-forward)

To clean up, use make domain.clean or make no-domain.clean respectively.

Run make help to see all available targets, or consult the Makefile directly.

The following sections detail each step if you prefer to run them manually or want to understand the process. If you've used the quick setup commands above, you can skip ahead to Accessing Camunda 8.

Create the Kubernetes cluster

First, run the cluster creation script:

8.8/local/kubernetes/kind-single-region/procedure/cluster-create.sh
loading...

This script:

  1. Creates a kind cluster named camunda-platform-local.
  2. Waits until all nodes are ready.
  3. Creates the camunda namespace.

In the output, you should see three nodes in Ready state.

Review the cluster configuration

The cluster includes one control plane node and two worker nodes with HTTP (80) and HTTPS (443) port mappings for Ingress:

8.8/local/kubernetes/kind-single-region/configs/kind-cluster-config.yaml
loading...

Now that you've created the cluster, you'll need to choose a deployment mode for the next steps:

Domain mode deployment

This section covers the full domain mode setup with TLS certificates and Ingress.

If you'd prefer a simpler setup without domain configuration, skip to No-domain mode deployment.

Deploy the Ingress controller

Deploy the Ingress NGINX controller to handle incoming traffic:

8.8/local/kubernetes/kind-single-region/procedure/ingress-nginx-deploy.sh
loading...

This script:

  1. Installs Ingress NGINX via Helm.
  2. Configures it to run on the control plane node with hostNetwork: true.
  3. Waits until the controller is ready.

Verify the Ingress controller is running:

kubectl get pods -n ingress-nginx

Configure DNS resolution

For pods inside the cluster to resolve camunda.example.com, configure CoreDNS to rewrite DNS queries:

8.8/local/kubernetes/kind-single-region/procedure/coredns-config.sh
loading...

This configuration rewrites DNS queries for camunda.example.com and zeebe-camunda.example.com to the Ingress NGINX controller service (ingress-nginx-controller.ingress-nginx.svc.cluster.local), allowing pods to reach Camunda services using the same domain names as external clients.

Review the CoreDNS configuration
8.8/local/kubernetes/kind-single-region/configs/coredns-configmap.yaml
loading...

Configure your hosts file

Run the hosts file configuration script to resolve camunda.example.com locally. The script requires sudo privileges, so you'll need to provide your password:

8.8/local/kubernetes/kind-single-region/procedure/hosts-add.sh
loading...

This adds the following entries to your /etc/hosts file:

127.0.0.1 camunda.example.com
127.0.0.1 zeebe-camunda.example.com

Generate TLS certificates

Generate locally-trusted TLS certificates, using mkcert:

8.8/local/kubernetes/kind-single-region/procedure/certs-generate.sh
loading...

Using certificates from real certificate authorities (CAs) for local development can be dangerous or impossible, for hosts like localhost or 127.0.0.1, and self-signed certificates cause trust errors. mkcert solves this by automatically creating and installing a local CA in the system root store and generating locally-trusted certificates.

The certificate generation script:

  1. Installs the mkcert CA in your system trust store (first run only).
  2. Generates certificates for camunda.example.com, zeebe-camunda.example.com and *.camunda.example.com.
  3. Stores certificates in .certs/.

Create Kubernetes secrets for TLS

  1. Create the TLS secret in Kubernetes. The Ingress controller will use this to serve HTTPS traffic for camunda.example.com:

    8.8/local/kubernetes/kind-single-region/procedure/certs-create-secret.sh
    loading...
  2. Then, create a ConfigMap with the CA certificate for pods that need to trust it:

    8.8/local/kubernetes/kind-single-region/procedure/certs-create-ca-configmap.sh
    loading...

Deploy Camunda 8

Deploy Camunda 8 with the domain mode Helm values:

8.8/local/kubernetes/kind-single-region/procedure/camunda-deploy-domain.sh
loading...

This uses the following Helm values:

Domain mode Helm values
8.8/local/kubernetes/kind-single-region/helm-values/values-domain.yml
loading...
mkcert CA trust configuration
8.8/local/kubernetes/kind-single-region/helm-values/values-mkcert.yml
loading...

No-domain mode deployment

This section covers the simplified setup using port-forwarding without TLS.

Configure your hosts file for Keycloak

When running without a domain, Console validates the JWT issuer claim against the configured Keycloak base URL. To keep token issuance consistent and avoid mismatches, the chart configuration sets Keycloak's hostname to its Kubernetes Service name when operating locally. This means you need to map the service hostname to 127.0.0.1 so that browser redirects and token issuer values align.

Add (or update) the following entry in your /etc/hosts file:

127.0.0.1  camunda-keycloak

The hostname camunda-keycloak is derived from the Helm release name (camunda) followed by -keycloak. If you use a different release name, adjust accordingly (for example, my-release-keycloak).

After adding this entry and deploying Camunda 8 in the next step, you'll be able to reach Keycloak at http://camunda-keycloak:18080/auth.

Why port 18080? We forward container port 18080 to a non-privileged local port (18080) to avoid requiring elevated privileges and to reduce conflicts with other processes using port 18080.

Deploy Camunda 8

Deploy Camunda 8 with the no-domain mode Helm values:

8.8/local/kubernetes/kind-single-region/procedure/camunda-deploy-no-domain.sh
loading...

This uses the following Helm values:

No-domain mode Helm values
8.8/local/kubernetes/kind-single-region/helm-values/values-no-domain.yml
loading...

Verify deployment

Monitor the deployment progress:

kubectl get pods -n camunda -w

Wait until all pods show Running status. This may take 5–10 minutes depending on your internet connection and system resources.

You can also use the deployment readiness check script from the root directory of the camunda-deployment-references repository. This script requires jq to be installed:

export CAMUNDA_NAMESPACE=camunda
8.8/generic/kubernetes/single-region/procedure/check-deployment-ready.sh
loading...

Finally, verify the Helm release:

helm list -n camunda

Accessing Camunda 8

Default credentials

  • Username: admin
  • Password: Run the following script
8.8/local/kubernetes/kind-single-region/procedure/get-password.sh
loading...

Cleanup

Destructive action

This will permanently delete all Camunda 8 data in the local development cluster.

If you used the Makefile for setup, you can use the corresponding clean command:

# Domain mode
make domain.clean

# No-domain mode
make no-domain.clean

Alternatively, you can clean up manually:

# Delete cluster
kind delete cluster --name camunda-platform-local

# (domain mode) Remove hosts entries (requires sudo)
sudo sed -i '/camunda.example.com/d' /etc/hosts

# (no-domain mode) Remove Keycloak hosts entry (requires sudo)
sudo sed -i '/camunda-keycloak/d' /etc/hosts

# (domain mode) Clean certificates
rm -rf .certs

Troubleshooting

Pods don't start

Check the pod status and events:

kubectl get pods -n camunda
kubectl describe pod <pod-name> -n camunda
kubectl logs <pod-name> -n camunda

Browser shows certificate errors (Domain mode)

Ensure the mkcert CA is installed:

mkcert -install

Regenerate certificates:

./procedure/certs-generate.sh
./procedure/certs-create-secret.sh
kubectl rollout restart deployment -n camunda

Ingress doesn't work (Domain mode)

Check the Ingress controller status:

kubectl get pods -n ingress-nginx
kubectl get ingress -n camunda

Insufficient resources

Ensure your container runtime has enough resources allocated (4+ CPU cores, 8GB+ RAM).

  • Docker Desktop: Check the Resources settings
  • Docker Engine: Configure the Docker daemon (configuration varies by OS)
  • Podman: Resources are managed by your system; ensure sufficient resources are available

Next steps