Join our largest event of the year | CamundaCon 2022 October 5-6

Icon Close

Camunda Platform 7: Deploy a Process to Kubernetes with Quarkus

Our latest Camunda Platform Runtime 7.16.0 release introduces a new Quarkus Extension allowing you to add an embedded Process Engine to your Quarkus Application.

Some months ago, I joined forces with my teammate Nikola Koevski to create the Camunda Quarkus Engine Extension. Today, we present it in more detail.

Similarly to Spring Boot, the Quarkus framework:

  • is independent of a Java Application Server; you can build an uber-jar that runs directly on the JVM
  • supports dependency injection
  • has a strong focus on simplifying your local development workflow
  • has a growing list of best-of-breed Java library extensions you can choose from

Quarkus supports generating resources to deploy your application to a cluster technology like Kubernetes, OpenShift, or Knative.

In this article, you will learn in nine simple steps how to deploy a Quarkus Process Application and its Postgres database to a Kubernetes cluster.

Table of Contents


  • Access to a Kubernetes cluster (e.g., via Minikube)
  • Java 11+
  • A Java IDE of your choice
  • Optionally Maven 3.8.1+

Step 1: Initial Project Setup

Let's first create the initial project setup. In this guide, we will use the build tool Gradle, but with Maven, it should work similarly. No worries if you haven't installed Gradle yet since you don't need to. The Gradle Wrapper is part of the basic project structure.

There are two options to create the initial project structure.

Using Maven

To make things as easy as possible, you can use the Maven Plugin to scaffold your project:

$ mvn io.quarkus.platform:quarkus-maven-plugin:2.3.0.Final:create \
    -DprojectGroupId=org.camunda.platform.example \
    -DprojectArtifactId=camunda-k8s-example \
    -Dextensions="camunda,kubernetes,jdbc-postgresql,jib,resteasy" \
    -DplatformVersion="2.1.2.Final" \
    -DnoCode=true \

This command creates a project with the following Quarkus Extensions:

  • camunda-bpm-quarkus-engine
  • quarkus-kubernetes
  • quarkus-container-image-jib
  • quarkus-jdbc-postgresql
  • quarkus-resteasy


If you don't want to install Maven, you can download a basic Gradle project on Make sure to add the Camunda Quarkus Engine Extension yourself:

$ cd ./camunda-k8s-example
$ ./gradlew addExtension --extensions="camunda"

Step 2: Configure the Datasource

The file located under ./camunda-k8s-example/src/main/resources/ configures the Quarkus application.

To configure the default datasource, add the following lines to the file:


In Step 6 of this guide, we will create a Postgres database with matching credentials, host, port, and database name with the help of a dedicated Kubernetes deployment.

Step 3: Deploy a Process Model

Download the process model process.bpmn (right-click & save) and move it into your project under ./camunda-k8s-example/src/main/resources. The process consists of a Service Task that calls the bean serviceDelegateBean. We define this bean in Step 5 of this guide.

Create a Java class org.camunda.platform.example.ProcessDeployer with the following content:

import org.camunda.bpm.engine.RepositoryService;
import org.camunda.bpm.quarkus.engine.extension.event.CamundaEngineStartupEvent;

import javax.enterprise.event.Observes;
import javax.inject.Inject;

public class ProcessDeployer {

  public RepositoryService repositoryService;

  // Method is called as soon as the Process Engine is running
  public void deployProcess(@Observes CamundaEngineStartupEvent startupEvent) {
    // Create a new deployment
        .addClasspathResource("process.bpmn") // Filename of the process model
        .enableDuplicateFiltering(true) // No redeployment when process model remains unchanged


As soon as the process engine is running, the Quarkus Extension emits a CamundaEngineStartupEvent. The ProcessDeployer#deployProcess method catches the event and calls the API of the process engine to deploy the process model stored in the process.bpmn file.

Step 4: Create a REST Endpoint to start a process

Create a Java class org.camunda.platform.example.StartProcessService with the following content:

import org.camunda.bpm.engine.RuntimeService;

import javax.inject.Inject;

public class StartProcessService {

  public RuntimeService runtimeService;

  public String startProcessInstance() {
    String processInstanceId = runtimeService.startProcessInstanceByKey("process").getId();
    return "Process instance with id " + processInstanceId + " started!";


The JAX-RS resource implements the GET /start-process REST API endpoint, which calls the process engine API to start a new process.

Step 5: Define a Java Delegate Bean

Create a Java class org.camunda.platform.example.ServiceDelegateBean with the following content:

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.jboss.logging.Logger;

import javax.enterprise.context.Dependent;
import javax.inject.Named;

public class ServiceDelegateBean implements JavaDelegate {

  public void execute(DelegateExecution execution) {
        .infov("\n\nService Task called. Hurray!!");


Whenever the engine executes the Service Task defined in the process, it calls the ServiceDelegateBean#execute method, which logs Service Task called. Hurray!! to the console.

Step 6: Create Kubernetes Objects

Next, let's create Kubernetes deployments and services for the Quarkus Application itself as well as for the Postgres database.

Quarkus Application Objects

The Quarkus extension quarkus-kubernetes allows us to create the object configurations for the Quarkus Application by running the following command:

$ ./gradlew build

You can find the generated configuration file under ./camunda-k8s-example/build/kubernetes/kubernetes.yml, which contains the definitions of the Service and Deployment objects.

In case the Kubernetes cluster runs locally on your machine, you need to set the imagePullPolicy of the deployment object to IfNotPresent. Otherwise, the cluster tries to pull the image from a remote registry.

Postgres Database Objects

To create the Kubernetes deployment and service objects for the Postgres database, add the following object definitions to the previously generated kubernetes.yml file:

apiVersion: v1
kind: Service
    app: postgres
  name: postgres
    - port: 5432
    app: postgres
  type: ClusterIP
apiVersion: apps/v1
kind: Deployment
  name: postgres
  replicas: 1
      app: postgres
        app: postgres
        - name: postgres
          image: postgres:latest
          imagePullPolicy: "IfNotPresent"
            - containerPort: 5432
            - name: POSTGRES_DB
              value: process-engine
            - name: POSTGRES_USER
              value: camunda
            - name: POSTGRES_PASSWORD
              value: camunda

Now, we are all set to apply the object definition configuration file to the Kubernetes cluster by running the following command:

$ kubectl apply -f build/kubernetes/kubernetes.yml

The command output should look as follows:

service/camunda-k8s-example created
deployment.apps/camunda-k8s-example created
service/postgres created
deployment.apps/postgres created

Step 7: Build the Container Image and Deploy it to Kubernetes

To create a container image and deploy it to Kubernetes, run the following command:

$ ./gradlew build -Dquarkus.kubernetes.deploy=true

The flag is provided by the extension quarkus-container-image-jib which helps to build a container image based on your application. The quarkus.kubernetes.deploy flag is provided by the extension quarkus-kubernetes and deploys the image containing your application to the Kubernetes cluster.

Step 8: Start a process via REST API

To call the REST API endpoint GET /start-process from your local machine, you need to forward the port of the Kubernetes service to your host machine by running the following command:

$ kubectl port-forward svc/camunda-k8s-example 8080:80

Now, you can start a new process instance by opening the following URL in your browser: http://localhost:8080/start-process. It triggers the execution of the Java Delegate Bean defined via Service Task.

Step 9: Check Kubernetes Pod Logs

Let's have a look at the pod logs of our application deployment by running the following command:

$ kubectl logs -l

When the process was executed successfully, you should see the following output:

Service Task called. Hurray!!

Now, it's your turn!

Now you know the first steps to get started with the Camunda Platform Process Engine and Quarkus. You can find the complete code of the example on GitHub. If you need help, you can ask your question in the forum.

We would be interested in your feedback as it helps us to iterate on the Camunda Quarkus Engine Extension. We have already collected some ideas on how we can improve the Camunda Quarkus integration. You can find a list of Feature Requests in our issue tracker. If your particular feature request is missing, you are welcome to create a new feature request.

We would also be happy to receive code contributions that you can submit as a pull request directly to our codebase on GitHub.

  • Zbchaos — A new fault injection tool...

    During Summer Hackdays 2022, I worked on a project called “Zeebe chaos” (zbchaos), a fault injection command-line interface (CLI) tool. This allows us engineers to more easily run chaos experiments against Zeebe, build up confidence in the system’s capabilities, and discover potential weaknesses. Requirements To understand this blog post, it is useful to have a certain understanding of Kubernetes and Zeebe itself. Summer Hackdays: Hackdays are a regular event at Camunda, where people from different departments (engineering, consulting, DevRel, etc.) work together on new ideas, pet projects, and more. Often, the results are quite impressive and are also presented in the following CamundaCon. For example, check out the agenda of this year’s CamundaCon 2022. Check out previous Summer Hackdays here:...

    Read more
  • Increase your resilience with new regions in...

    We’re excited to announce new regions for Camunda Platform 8 SaaS that further strengthen the resilience, performance, and data requirements for our SaaS customers. Enterprise customers can now choose to create their clusters in a number of regions including Europe West, US Central, US East, and the most recent addition, Australia South East. This provides multiple benefits, such as increasing availability, allowing to set up fail-safes, adhering to regulatory requirements for regional data storage, and reduced latency due to closer physical proximity. Resilience and redundancy in technology are important for all modern organizations and are top of mind for many. Across industries, organizations need a solution that scales effectively and is resilient to provide a good base for process orchestration....

    Read more
  • Black title slide that reads, "The CAM project in JIRA is moving to GitHub"

    The CAM project in JIRA is moving...

    For almost 10 years, JIRA has been our development issue tracker for the core components of Camunda Platform 7. About 15,000 tickets later, Camunda’s engineering has grown from one team to a team of teams. Many new projects have used GitHub exclusively as a code repository and an issue tracker from the start. In October, we will move the CAM project to GitHub issues. With this change we are reducing the gap: our community can participate in our development processes with a single account. We achieve a unified approach for managing development issues, making it easier for everyone to participate. We thank everyone who has contributed to our CAM issue tracker and hope that the collaboration continues in our new...

    Read more

Ready to get started?

Still have questions?