Camunda Platform 7: Deploy a Process to Kubernetes with Quarkus

Discover how our latest Camunda Platform Runtime 7.16.0 release introduces a new Quarkus Extension allowing you to add an embedded process engine.
  • Blog
  • >
  • 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.

Try All Features of Camunda

Related Content

There are good reasons BPMN been so popular for so long. Let's talk about what BPMN can really do and why it's brilliant.
We're excited to announce the June 2024 alpha release of Camunda. Check out what's new, from AI Docs integrations to Connector improvements to Helm Chart updates.
Achieve our first certification as a Camunda Certified Professional—Developer.