Building workflow images using Quarkus CLI

This document describes how to build a Serverless Application Container image using the Quarkus CLI.

Prerequisites
  • A workflow project is created.

    For more information about creating a workflow project, see Creating your first Serverless Workflow service.

  • Latest version of Docker is installed. Alternatively, you can use Jib to build container images. However, Docker is required to build GraalVM native image using the Quarkus native builder image.

  • Optionally, GraalVM 22.3.0 is installed.

Quarkus provides a few extensions to build container images, such as Jib, docker, s2i, and buildpacks. For more information about the Quarkus extensions, see the Quarkus documentation.

The examples in this document assume that you have the Quarkus tooling installed. For more information about the tooling, see Getting familiar with SonataFlow tooling.

Using an example application

To get started with building workflow images, you can use the serverless-workflow-greeting-quarkus example application.

You can skip the following procedure if you already have a workflow application.
Procedure
  1. Clone the kogito-examples repository and navigate to the serverless-workflow-greeting-quarkus example application.

    Clone an example application
    git clone --branch main https://github.com/apache/incubator-kie-kogito-examples.git
    cd kogito-examples/serverless-workflow-examples/serverless-workflow-greeting-quarkus
  2. To run the example application, follow the instructions in Creating your first workflow service.

  3. Install the Quarkus command line interface (CLI). For more information, see Installing the Quarkus CLI.

  4. Add the required Quarkus extension using Quarkus CLI:

    Add the Jib extension

    The kogito-examples already have this extension added by default, and can be activated with the container Maven profile.

    The steps to add the extension in your Serverless Workflow application are:

    quarkus extension add 'container-image-jib'

    After adding the Jib extension, you can verify the newly added dependency in the pom.xml file:

    Verify the Jib extension
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-container-image-jib</artifactId>
    </dependency>

Building the workflow application

After installing the required tooling, you can start building your workflow application.

Prerequisites
  • You have created a Quarkus project.

  • Quarkus CLI is installed. For more information about installing the Quarkus CLI, see Installing the Quarkus CLI.

Procedure
  1. In a command terminal, navigate to your Quarkus project.

  2. To build your workflow application on Quarkus, set the quarkus.container-image.build property value to true and run the following command:

    Build your workflow application
    quarkus build -Dquarkus.container-image.build=true

    The previous command builds your image with name: {system_username}/{project_artifactId}:{project_version}.

    Optionally, you can set the following properties to specify the image:

    • quarkus.container-image.registry: To define the registry address of the image, such as quay.io. When using OpenShift use the provided registry.

    • quarkus.container-image.group: To define the registry namespace of the image. For example, context/namespace or in case of Kubernetes or OpenShift namespace/project.

    • quarkus.container-image.name: To override the image name. By default, this property uses artifact ID.

    Build your workflow application with specific image information
    quarkus build -Dquarkus.container-image.build=true \
        -Dquarkus.container-image.group=kogito \
        -Dquarkus.container-image.name=serverless-workflow-greeting-quarkus \
        -Dquarkus.container-image.tag=1.0 \
        -Dquarkus.container-image.registry=quay.io

    The added Jib extension caches the target/lib directory. Based on the size of your project, Jib speeds up the rebuilds.

  3. You can also push your workflow application to the defined registry. You need to set the quarkus.container-image.push property value to true (default value is false).

    Example of pushing the built workflow application to a registry
    quarkus build -Dquarkus.container-image.build=true \
        -Dquarkus.container-image.group=kogito \
        -Dquarkus.container-image.name=serverless-workflow-greeting-quarkus \
        -Dquarkus.container-image.tag=1.0 \
        -Dquarkus.container-image.registry=quay.io \
        -Dquarkus.container-image.push=true

    The previous command results in the following container image pushed to quay.io:

    quay.io/kogito/serverless-workflow-greeting-quarkus:1.0

  4. Alternatively, you can create an Apache Maven profile to build the container image, which can be triggered by setting the target profile.

    Example Apache Maven profile
    <profile>
      <id>build-container</id>
      <properties>
        <quarkus.container-image.build>true</quarkus.container-image.build>
        <quarkus.container-image.group>kogito</quarkus.container-image.group>
        <quarkus.container-image.name>serverless-workflow-greeting-quarkus</quarkus.container-image.name>
        <quarkus.container-image.tag>1.0</quarkus.container-image.tag>
        <quarkus.container-image.registry>quay.io</quarkus.container-image.registry>
        <quarkus.container-image.push>true</quarkus.container-image.push>
      </properties>
    </profile>

    You can activate the created Apache Maven profile using Quarkus CLI:

    Activate the Apache Maven profile
     quarkus build -- -Pbuild-container

Building the workflow application using a native image

When it comes to workflows, a small startup footprint is expected, which can be better when using the native builds to build a workflow application.

Prerequisites
  • You have created a Quarkus project.

  • Quarkus CLI is installed. For more information about installing the Quarkus CLI, see Installing the Quarkus CLI.

Procedure
  1. In a command terminal, navigate to your Quarkus project.

  2. To build a native image, pass the --native flag using Quarkus CLI:

    Example of building a native image
    quarkus build --native -Dquarkus.container-image.build=true \
        -Dquarkus.container-image.group=kogito \
        -Dquarkus.container-image.name=serverless-workflow-greeting-quarkus \
        -Dquarkus.container-image.tag=1.0-native \
        -Dquarkus.container-image.registry=quay.io

    The previous command results in the following container image:

    quay.io/kogito/serverless-workflow-greeting-quarkus:1.0-native

    In case GraalVM is not installed, you can set the -Dquarkus.native.container-build=true system property, which creates a Linux executable.

    Configure Docker to use the in-cluster (Remote) Docker daemon

    When build Container Images using a remote Docker Daemon, i.e. Minikube, you need to use the following system property instead of -Dquarkus.native.container-build=true

    System property to use a remote Docker Daemon
    -Dquarkus.native.remote-container-build=true

    For more information about native builds, see Building a native executable.

Testing your workflow image

After building your workflow image using Quarkus CLI, you can test the built image.

Prerequisites
  • Latest version of Docker is installed.

Procedure
  1. Start JVM and native Container Images.

    • Example JVM image

    • Example native image

    docker run -it -p 8080:8080 quay.io/kogito/serverless-workflow-greeting-quarkus:1.0
    ...
    INFO  [io.quarkus] (main) serverless-workflow-greeting-quarkus 1.22.1.Final on JVM (powered by Quarkus 2.9.2.Final) started in 1.302s
    docker run -it -p 8080:8080 quay.io/kogito/serverless-workflow-greeting-quarkus:1.0-native
    ...
    INFO  [io.quarkus] (main) serverless-workflow-greeting-quarkus 1.22.1.Final native (powered by Quarkus 2.9.2.Final) started in 0.039s

    Note that the startup of native image is faster than the JVM image.

  2. To invoke the workflow application, execute the following command once the container is started:

    • Example request

    • Example response

    curl -X POST -H 'Content-Type:application/json' -H 'Accept:application/json' -d '{"name": "John", "language": "English"}' http://localhost:8080/jsongreet
    {
        "id": "2acf710d-7e4a-481d-925c-dfd85a369987",
        "workflowdata": {
            "name": "John",
            "language": "English",
            "greeting": "Hello from JSON Workflow, "
        }
    }

Found an issue?

If you find an issue or any misleading information, please feel free to report it here. We really appreciate it!