Camunda 8 Self-Managed Local Environment

(Updated as per Camunda 8.7) In this post I will go briefly about all the options available for having a Camunda 8 environment fully functional for development purposes locally in your machine.

Camunda Logo


Why local?

Most developers strongly prefer to develop locally whenever possible, rather than relying on remote resources.

In larger projects, you'll typically find multiple Camunda 8 environments (self-managed or SaaS) for different purposes — such as DEV, QA, STAGE, and PROD.

As a fellow technology enthusiast, I love having everything running locally whenever I can :)
It also lets me work offline until I need to pull in another dependency or library.

Camunda 8 Run (Preferred)

Since Camunda 8.6. This has become my preferred option.

Official documentation: Camunda 8 Run 

This option allows to run extremely quickly a Camunda 8 Self-Managed Local Cluster with all the required components (Zeebe, Tasklist, Operate, Connectors, Elasticsearch)

The best of this option is:
  • You can run Camunda 8 entirely as Java Application.
  • You can run Camunda 8 entirely as Docker containers by just adding to the start scripts the option --docker (or -docker for windows)
My take:
  • It is the quickest way to scaffold a local development environment
  • It is the best addition Camunda has done
Camunda 8 Run (8.6)

Manual

Yes, if you're from the older generation like me — someone who preferred using virtual machines to isolate local installations instead of relying on Docker or Kubernetes — then this might be the approach for you.

You can find the manual installation steps here: Manual Installation on local machine

To be honest, this method is best suited for traditional architectures based on virtual machines.

My take:

If you go this route, avoid installing everything directly on your local machine — don’t pollute your system. Instead, I’d recommend using a dedicated local virtual machine.

Personally, I’ll be skipping this approach and sticking with Camunda 8 Run or Docker Compose for local development.

Docker Compose (Preferred)

Using Docker Compose is a common and convenient way for developers to spin up a local development environment with all the necessary services.

You can find the official documentation here: Camunda 8 - Docker Compose

Note: As clearly stated in the documentation — this setup is for development only! Don’t be silly and try to use it in production.

Important to Know:

  • The default docker-compose.yaml includes all services except the Web Modeler (which requires an Enterprise license).

  • If you’re not interested in using Optimize, Keycloak, or Identity for your development setup, you can simply use docker-compose-core.yaml.

  • If you do have an Enterprise license and want to use the Web Modeler, you’ll need to use docker-compose-web-modeler.yaml — and log in to registry.camunda.cloud

My take:

In the past, Camunda used to recommend running a local Kubernetes cluster using Kind to simulate a more realistic Camunda 8 cluster setup for development.

Personally, I always thought that was overkill.

A local development environment doesn’t need to mirror your full-blown Camunda 8 DEV cluster — the one where all developers integrate their work.

Keep it simple and fast. Docker Compose does the job perfectly for local development.

Camunda 8 - Docker Compose

Docker Desktop running Camunda 8 - Docker

Local Kubernetes Cluster (Updated)

This was the recommended approach by Camunda previously. It consists of installing a local Kubernetes cluster with kind, minikube or your preferred for running local kubernetes clusters.

They provide very clear all the steps to configure it here: Camunda 8 - Local Kubernetes Cluster

I recommend to you to configure the NGINX ingress controller, so you do not have to do port-forwarding mappings every time / day you up your local environment.

Some important things to know when following the documentation:
  • If using NGINX approach, create the cluster following the instructions below where you need to create the kind.config file to make sure you enable ingress-controller

  • If using NGINX, you have to update the camunda-platform-kind-values.yaml. There is a small bug (maybe the fixed it when you read this) where the first ingress needs an indentation inside global 

  • Make sure that all the containers are Running when you finish the steps

    Camunda 8 pods running in local kubernetes (KIND)

  • You need to have the NGINX ingress controller also up


    Ingress Controllers configured

Time to test that the tasklist is accessible: http://camunda.local/tasklist

Camunda 8 Self-Managed Tasklist running locally


Test also that operate is accessible: http://camunda.local/operate

Camunda 8 Self-Managed Operate running locally


Is this all?

No, it is not all if you decided to use NGINX Ingress instead of Port-Forwarding. Camunda can work without TLS/SSL configured, however NGINX controllers not.

So, let's continue updating our above setup as following:
  • Create the certificates using OpenSSL command, I used the same as used in the blog below from Camunda (lazy)

    Shell / OpenSSL
    openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 --nodes -addext 'subjectAltName=DNS:camunda.local'

    Shell / OpenSSL
    openssl req -x509 -newkey rsa:4096 -keyout key-zeebe.pem -out cert-zeebe.pem -sha256 -days 365 --nodes -addext 'subjectAltName=DNS:zeebe.camunda.local'

  • Add the secrets just created to the Local Kubernetes cluster as follow

    Shell / OpenSSL
    kubectl create secret tls tls-secret --cert=cert.pem --key=key.pem

    Shell / OpenSSL
    kubectl create secret tls tls-secret-zeebe --cert=cert-zeebe.pem --key=key-zeebe.pem

  • Update the yaml we used for the kind configuration before (camunda-platform-kind-values.yaml) for enabling TLS in zeebeGateway and global ingress

    camunda-platform-core-kind-values.yaml
    global:
      ingress:
        enabled: true
        className: nginx
        host: "camunda.local"
        tls:
          enabled: true
          secretName: 'tls-secret'
      identity:
        auth:
          # Disable the Identity authentication for local development
          # it will fall back to basic-auth: demo/demo as default user
          enabled: false
          
    # Disable identity as part of the Camunda core
    identity:
      enabled: false
    
    optimize:
      enabled: false
    
    # Reduce for Zeebe and Gateway the configured replicas and with that the required resources
    # to get it running locally
    zeebe:
      clusterSize: 1
      partitionCount: 1
      replicationFactor: 1
      pvcSize: 10Gi
    
    zeebeGateway:
      ingress:
        enabled: true
        className: nginx
        host: "zeebe.camunda.local"
        tls:
          enabled: true
          secretName: 'tls-secret-zeebe'
      replicas: 1
    
    connectors:
      enabled: true
      inbound:
        mode: disabled
    
    operate:
      contextPath: "/operate"
    
    tasklist:
      contextPath: "/tasklist"
    
    elasticsearch:
      master:
        replicaCount: 1
        # Request smaller persistent volumes.
        persistence:
          size: 15Gi

  • Now, upgrade the Helm deployment we did before as following

    Shell / OpenSSL
    helm upgrade --install camunda-platform camunda/camunda-platform -f camunda-platform-core-kind-values.yaml


  • Test that all is good with Zeebe CLI as following

    Shell / OpenSSL
    zbctl status --certPath cert-zeebe.pem --address zeebe.camunda.local:443

  • Also, is needed that you also import in your keystore (e.g. cacerts) of your Java JDK those certificates as following

    Shell / OpenSSL
    keytool -import -alias camunda-local-zeebe -keystore cacerts -file cert-zeebe.pem


    Shell / OpenSSL
    keytool -import -alias camunda-local -keystore cacerts -file cert.pem
 
Future posts will start including code and best practices around Camunda

References


Comments

Popular posts from this blog

Sega Saturn Development: Where do I start

Just another example of CQRS and ES