Salta ai contenuti

Camunda Cheat Sheet

Overview

Camunda is a workflow and decision automation platform that enables organizations to orchestrate processes across people, systems, and devices. Camunda 8 is the cloud-native version built on Zeebe, a horizontally scalable workflow engine, while Camunda 7 is the traditional Java-based BPMN engine.

Camunda supports BPMN 2.0 for process modeling, DMN for decision tables, and provides task lists for human workflow. It offers language-agnostic job workers through gRPC, a visual process modeler (Camunda Modeler), and Operate/Tasklist/Optimize web applications for monitoring and management.

Installation

Camunda 8 (Self-Managed with Docker)

# Clone Camunda Platform
git clone https://github.com/camunda/camunda-platform.git
cd camunda-platform

# Start all components
docker compose up -d

# Components:
# Zeebe Gateway: localhost:26500
# Operate: localhost:8081
# Tasklist: localhost:8082
# Optimize: localhost:8083
# Identity: localhost:8084
# Elasticsearch: localhost:9200

Camunda Modeler

# Download from https://camunda.com/download/modeler/
# macOS
brew install --cask camunda-modeler

Zeebe CLI (zbctl)

# macOS
brew install camunda/tap/zbctl

# Linux
wget https://github.com/camunda/zeebe/releases/latest/download/zbctl
chmod +x zbctl
sudo mv zbctl /usr/local/bin/

# Verify connection
zbctl --address localhost:26500 --insecure status

Client SDKs

# Java
# Maven: io.camunda:zeebe-client-java:8.5.0

# Node.js
npm install camunda-8-sdk

# Python
pip install pyzeebe

# Go
go get github.com/camunda/zeebe/clients/go/v8

Core CLI Commands (zbctl)

CommandDescription
zbctl statusCheck cluster status
zbctl deploy resource process.bpmnDeploy a process
zbctl create instance order-processCreate process instance
zbctl create instance order-process --variables '{"x":1}'Create with variables
zbctl activate jobs my-serviceActivate jobs for a worker
zbctl publish message "order-placed" --correlationKey "123"Publish message
zbctl resolve incident <key>Resolve an incident

BPMN Process Definition

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
                  xmlns:zeebe="http://camunda.org/schema/zeebe/1.0">
  <bpmn:process id="order-process" name="Order Process" isExecutable="true">

    <bpmn:startEvent id="start" name="Order Received"/>

    <bpmn:serviceTask id="validate" name="Validate Order">
      <bpmn:extensionElements>
        <zeebe:taskDefinition type="validate-order"/>
      </bpmn:extensionElements>
    </bpmn:serviceTask>

    <bpmn:exclusiveGateway id="gateway" name="Valid?"/>

    <bpmn:serviceTask id="process" name="Process Payment">
      <bpmn:extensionElements>
        <zeebe:taskDefinition type="process-payment"
                             retries="3"/>
      </bpmn:extensionElements>
    </bpmn:serviceTask>

    <bpmn:endEvent id="end" name="Order Completed"/>

    <bpmn:sequenceFlow sourceRef="start" targetRef="validate"/>
    <bpmn:sequenceFlow sourceRef="validate" targetRef="gateway"/>
    <bpmn:sequenceFlow sourceRef="gateway" targetRef="process">
      <bpmn:conditionExpression>=valid = true</bpmn:conditionExpression>
    </bpmn:sequenceFlow>
    <bpmn:sequenceFlow sourceRef="process" targetRef="end"/>
  </bpmn:process>
</bpmn:definitions>

Job Workers

Node.js Worker

import { Camunda8 } from 'camunda-8-sdk';

const c8 = new Camunda8();
const zbc = c8.getZeebeGrpcApiClient();

// Deploy process
await zbc.deployResource({ processFilename: './order-process.bpmn' });

// Create process instance
const result = await zbc.createProcessInstance({
  bpmnProcessId: 'order-process',
  variables: { orderId: '12345', amount: 99.99 },
});

// Create a job worker
const worker = zbc.createWorker({
  taskType: 'validate-order',
  taskHandler: async (job) => {
    const { orderId, amount } = job.variables;

    const valid = amount > 0 && orderId != null;

    return job.complete({ valid, validatedAt: new Date().toISOString() });
  },
  timeout: 30000,
  maxJobsToActivate: 32,
});

Python Worker

import asyncio
from pyzeebe import ZeebeWorker, create_insecure_channel

channel = create_insecure_channel(hostname="localhost", port=26500)
worker = ZeebeWorker(channel)

@worker.task(task_type="validate-order")
async def validate_order(orderId: str, amount: float):
    valid = amount > 0 and orderId is not None
    return {"valid": valid}

@worker.task(task_type="process-payment")
async def process_payment(orderId: str, amount: float):
    # Process payment logic
    return {"transactionId": "txn_abc123"}

asyncio.run(worker.work())

Configuration

Zeebe Broker (zeebe.cfg.yaml)

zeebe:
  broker:
    cluster:
      partitionsCount: 3
      replicationFactor: 3
      clusterSize: 3
    threads:
      cpuThreadCount: 4
      ioThreadCount: 4
    network:
      host: 0.0.0.0
      port: 26501
    gateway:
      enable: true
      network:
        host: 0.0.0.0
        port: 26500
    data:
      directory: data
      logSegmentSize: 512MB
      snapshotPeriod: 15m
    exporters:
      elasticsearch:
        className: io.camunda.zeebe.exporter.ElasticsearchExporter
        args:
          url: http://elasticsearch:9200
          index:
            prefix: zeebe-record

Advanced Usage

Message Correlation

// Publish a message
await zbc.publishMessage({
  name: 'payment-received',
  correlationKey: orderId,
  variables: { paymentId: 'pay_123', amount: 99.99 },
  timeToLive: 300000, // 5 minutes
});

DMN Decision Tables

# Deploy a decision
zbctl deploy resource pricing-decision.dmn

# Evaluate a decision
zbctl evaluate decision pricing-decision \
  --variables '{"customerType": "premium", "orderTotal": 500}'

Timer Events

<!-- Timer start event (cron) -->
<bpmn:timerEventDefinition>
  <bpmn:timeCycle>R/PT1H</bpmn:timeCycle>
</bpmn:timerEventDefinition>

<!-- Timer intermediate catch (duration) -->
<bpmn:timerEventDefinition>
  <bpmn:timeDuration>PT24H</bpmn:timeDuration>
</bpmn:timerEventDefinition>

<!-- Timer boundary (date) -->
<bpmn:timerEventDefinition>
  <bpmn:timeDate>=deadline</bpmn:timeDate>
</bpmn:timerEventDefinition>

REST API (Operate)

# Get process instances
curl -X POST http://localhost:8081/v1/process-instances/search \
  -H "Content-Type: application/json" \
  -d '{"filter": {"state": "ACTIVE"}}'

# Get incidents
curl -X POST http://localhost:8081/v1/incidents/search \
  -H "Content-Type: application/json" \
  -d '{"filter": {"state": "ACTIVE"}}'

Troubleshooting

IssueSolution
Zeebe gateway unreachableCheck gateway port 26500; verify network connectivity
Process deployment failsValidate BPMN in Modeler; check for missing task types
Jobs not activatingEnsure worker task type matches BPMN definition; check worker connection
Incidents accumulatingReview incident details in Operate; fix worker errors and resolve incidents
Process instance stuckCheck for missing message correlations or timer events
Elasticsearch connection errorVerify ES is running; check exporter configuration
Cluster unhealthyCheck all broker nodes are running; verify partition replication
Variables not passingUse correct FEEL expressions; check variable scoping in process