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)
| Command | Description |
|---|---|
zbctl status | Check cluster status |
zbctl deploy resource process.bpmn | Deploy a process |
zbctl create instance order-process | Create process instance |
zbctl create instance order-process --variables '{"x":1}' | Create with variables |
zbctl activate jobs my-service | Activate 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
| Issue | Solution |
|---|---|
| Zeebe gateway unreachable | Check gateway port 26500; verify network connectivity |
| Process deployment fails | Validate BPMN in Modeler; check for missing task types |
| Jobs not activating | Ensure worker task type matches BPMN definition; check worker connection |
| Incidents accumulating | Review incident details in Operate; fix worker errors and resolve incidents |
| Process instance stuck | Check for missing message correlations or timer events |
| Elasticsearch connection error | Verify ES is running; check exporter configuration |
| Cluster unhealthy | Check all broker nodes are running; verify partition replication |
| Variables not passing | Use correct FEEL expressions; check variable scoping in process |