πŸš€ Camunda 8: A Complete Guide to Local Deployment with Docker + Spring Boot Application with Zeebe

πŸš€ Camunda 8: A Complete Guide to Local Deployment with Docker + Spring Boot Application with Zeebe

Β·

6 min read


Camunda 8 is an industry-leading platform for workflow and decision automation. Deploying it locally allows developers to test, iterate, and develop workflow applications before pushing them into production. This tutorial will guide you step-by-step on how to install and deploy Camunda 8 using Docker Compose on your local machine.


πŸ› οΈ Prerequisites

Before getting started, make sure you have the following installed on your system:

  1. Docker Desktop : Install Docker Compose

Make sure that Docker and Docker Compose are up and running on your system. We will use Docker Compose to orchestrate the different Camunda components in a single environment.


πŸ§‘β€πŸ’» Step 1: Set Up Environment Variables

Start by defining the environment variables for the different versions of Camunda and supporting components. These versions will ensure compatibility among all containers.

 # Camunda 8 versions
CAMUNDA_CONNECTORS_VERSION=8.5.7
CAMUNDA_PLATFORM_VERSION=8.5.7
CAMUNDA_IDENTITY_VERSION=8.5.5
CAMUNDA_OPERATE_VERSION=8.5.6
CAMUNDA_TASKLIST_VERSION=8.5.7
CAMUNDA_OPTIMIZE_VERSION=8.5.5
CAMUNDA_WEB_MODELER_VERSION=8.5.8

# Supporting tools
ELASTIC_VERSION=8.15.1
OPENSEARCH_VERSION=2.16.0
MAILPIT_VERSION=v1.20.4
POSTGRES_VERSION=14.5-alpine
KEYCLOAK_SERVER_VERSION=24.0.5

These version numbers ensure that the correct versions of Camunda components, Elasticsearch, and OpenSearch are pulled into your Docker environment.

πŸ—οΈ Step 2: Create Docker Compose File

Next, you’ll need a docker-compose.yml file that defines all the services Camunda 8 relies on, including Zeebe, Operate, Tasklist, OpenSearch/Elasticsearch, and Connectors.

Create a file named docker-compose.yml in your working directory, and paste the following configuration into it:

yamlCopy codeversion: '3.7'

services:
  zeebe:
    image: camunda/zeebe:${CAMUNDA_PLATFORM_VERSION}
    container_name: zeebe
    ports:
      - "26500:26500"
      - "9600:9600"
    environment:
      - ZEEBE_BROKER_DATA_DISKUSAGECOMMANDWATERMARK=0.998
      - ZEEBE_BROKER_DATA_DISKUSAGEREPLICATIONWATERMARK=0.999
      - JAVA_TOOL_OPTIONS=-Xms512m -Xmx512m
    volumes:
      - zeebe:/usr/local/zeebe/data
    networks:
      - camunda-platform
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "timeout 10s bash -c ':> /dev/tcp/127.0.0.1/9600' || exit 1"]

  operate:
    image: camunda/operate:${CAMUNDA_OPERATE_VERSION}
    container_name: operate
    ports:
      - "8081:8080"
    environment:
      - CAMUNDA_OPERATE_ZEEBE_GATEWAYADDRESS=zeebe:26500
      - CAMUNDA_OPERATE_CSRFPREVENTIONENABLED=false
    networks:
      - camunda-platform
    depends_on:
      - zeebe

  tasklist:
    image: camunda/tasklist:${CAMUNDA_TASKLIST_VERSION}
    container_name: tasklist
    ports:
      - "8082:8080"
    environment:
      - CAMUNDA_TASKLIST_ZEEBE_GATEWAYADDRESS=zeebe:26500
      - CAMUNDA_TASKLIST_CSRFPREVENTIONENABLED=false
    networks:
      - camunda-platform
    depends_on:
      - zeebe

  connectors:
    image: camunda/connectors-bundle:${CAMUNDA_CONNECTORS_VERSION}
    container_name: connectors
    ports:
      - "8085:8080"
    environment:
      - ZEEBE_CLIENT_BROKER_GATEWAY_ADDRESS=zeebe:26500
      - CAMUNDA_OPERATE_CLIENT_URL=http://operate:8080
    networks:
      - camunda-platform
    depends_on:
      - zeebe
      - operate

  opensearch:
    image: opensearchproject/opensearch:${OPENSEARCH_VERSION}
    container_name: opensearch
    environment:
      - cluster.name=opensearch-cluster
      - network.bind_host=0.0.0.0
      - discovery.type=single-node
    ulimits:
      memlock:
        soft: -1
        hard: -1
    ports:
      - "9200:9200"
      - "9601:9600"
    volumes:
      - opensearch-data:/usr/share/opensearch/data
    networks:
      - camunda-platform

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION}
    container_name: elasticsearch
    ports:
      - "9200:9200"
      - "9300:9300"
    environment:
      - discovery.type=single-node
      - cluster.routing.allocation.disk.threshold_enabled=false
    networks:
      - camunda-platform

volumes:
  zeebe:
  opensearch-data:

networks:
  camunda-platform:

This configuration sets up Zeebe, Operate, Tasklist, Connectors, and the search engines (OpenSearch and Elasticsearch).


Step 3: Run the Docker Containers

Now that you’ve created the docker-compose.yml file, you can start your Camunda 8 environment. Run the following command in the terminal:

docker-compose up -d

Docker will pull the required images, create the containers, and start them. You can verify everything is running using:

code docker ps

You should see the containers for Zeebe, Operate, Tasklist, Connectors, and OpenSearch or Elasticsearch.

Step 4: Access the Camunda Services

Once all containers are running, you can access the various Camunda services via your web browser:

Each component has its own dashboard that allows you to manage workflows, monitor tasks, and configure connectors.

🎯 Why Use Tasklist, Zeebe, and Operate?

Before diving into the example application, let's break down the purpose of key components in Camunda 8: Tasklist, Zeebe, and Operate.

βœ…1. Tasklist

The Tasklist is a user interface designed for managing human tasks within business processes. Whenever a process model includes user tasks, they are listed in Tasklist, allowing assigned users to claim, complete, or reassign tasks.

  • Why is Tasklist important?
    Tasklist bridges the gap between automated workflow execution and human interaction, ensuring that tasks requiring user input are not missed and are handled in a structured manner.

  • Use Case:
    When you have business processes where human approval or interaction is necessary, Tasklist will manage these interactions efficiently.

πŸš€ Zeebe

Zeebe is the core workflow engine in Camunda 8, responsible for executing BPMN workflows. It handles process orchestration, managing workflow execution through tasks, services, and message events.

  • Why is Zeebe important?
    Zeebe is lightweight and highly scalable, allowing you to automate and execute complex workflows with minimal overhead. It can orchestrate services, microservices, and human tasks.

  • Use Case:
    Zeebe is ideal for automating end-to-end workflows that span different services or require integration with multiple systems.

🧩 Operate

Operate is a monitoring tool used to visualize, monitor, and troubleshoot running process instances in real time.

  • Why is Operate important?
    Operate provides visibility into the execution of workflows. It allows you to track the progress of individual process instances, find bottlenecks, and debug errors efficiently.

  • Use Case:
    When you need to monitor and analyze running instances of your workflows, Operate gives you real-time insights, which is critical for keeping workflows optimized and ensuring they run as expected.


πŸ’» Example: Camunda Spring Boot Application with Zeebe

Now that we understand the role of Tasklist, Zeebe, and Operate, let’s look at a practical emxample of how Zeebe is used in a Spring Boot application to automate message-based workflows.

package com.camunda.demo;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import io.camunda.zeebe.client.ZeebeClient;
import io.camunda.zeebe.spring.client.annotation.Deployment;

@SpringBootApplication
@Deployment(resources = "classpath:message-start.bpmn")
public class MessageStartAppApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(MessageStartAppApplication.class, args);
    }

    @Autowired
    private ZeebeClient client;

    @Override
    public void run(String... args) throws Exception {

        final Map<String, Object> variables = new HashMap<String, Object>();

        variables.put("name", "HAMZA BRAIMI");
        variables.put("age", 23);

        String messageId = "message-1";

        client.newPublishMessageCommand()
              .messageName("Message-Received")
              .correlationKey(messageId)
              .variables(variables)
              .send()
              .exceptionally(throwable -> {
                  throw new RuntimeException("Could not publish message", throwable);
              });
    }
}

Explanation of the Code

  1. Spring Boot Application: This is a simple Spring Boot application that integrates with the Zeebe workflow engine.

  2. Zeebe Client: The ZeebeClient is used to connect to the running Zeebe engine (which, in this case, would be running in Docker at localhost:26500).

  3. Publish Message Command: A message with the name "Message-Received" is published. This message correlates with a BPMN process that listens for a message event with a matching correlation key (messageId). The message includes process variables like "name" and "age" that are sent along with it.

application.properties Configuration

To ensure the application can communicate with the Zeebe broker (which is running locally in Docker), you need the following configuration in application.properties:

propertiesCopy codeserver.port=8099
zeebe.client.broker.gatewayAddress=localhost:26500
zeebe.client.security.plaintext=true
zeebe.client.requestTimeout=15000

πŸ”Ž Monitoring Your Process

  1. Deploy the BPMN Model: The process definition (e.g., message-start.bpmn) should be deployed in Zeebe, and this can be done automatically using the @Deployment annotation, as shown in the example.

  2. Monitor in Operate: Once the application starts sending messages to Zeebe, you can monitor the workflow instances and their progress using Operate.

πŸŽ‰ And that's the final result!

With this setup, you can deploy Camunda 8 locally, integrate Zeebe with Spring Boot, and monitor your processes in real time.

Happy coding! πŸ’»

HAMZA BRAIMI

Β