Deploy Quarkus Apps into the Cloud
As part of my position on the QE team in Quarkus, we need to play with a lot of integration tools and frameworks. Also, we need to use many cloud infrastructures like OpenShift and Kubernetes.
This post is a guide to deploy Quarkus applications into cloud infrastructures. For now, it only covers OpenShift and Kubernetes, but I will try to add all the options that Quarkus allows like AWS and Azure in the future. Moreover, I will try to keep these steps up-to-date.
Getting Started
Before going forward, I’m assuming that you already have a Quarkus application in place. If not, please proceed first with the official getting started guide in Quarkus.
As an example, using the Quarkus CLI tool, you can easily create a Quarkus application by doing:
quarkus create app
This command will create a simple Quarkus application at ./code-with-quarkus
.
OpenShift
For all the methods, we recommend first to create a new OpenShift project where to deploy our resources:
oc new-project my-project
Using s2i: From Binaries and Sources
OpenShift offers a really useful feature called Source-to-IMage (s2i). Basically, OpenShift can build our App images from binaries or from a source repository. Let’s see how to do this using a Quarkus application.
To use this method, we need to create our Build Configuration that will be used to generate our Quarkus applications. OpenShift s2i delegates the build onto a image, so the important bit is to select the right image.
For Quarkus, the right images are:
Quarkus JVM | Quarkus Native |
---|---|
registry.access.redhat.com/ubi8/openjdk-11 | quay.io/quarkus/ubi-quarkus-native-binary-s2i:1.0 |
In this tutorial, we’re using only JVM build, so I will be using only registry.access.redhat.com/ubi8/openjdk-11
.
- From Binaries
Let’s create the Build configuration:
oc new-build registry.access.redhat.com/ubi8/openjdk-11 --name quarkus-app --binary=true
Or simply apply the YAML format:
apiVersion: "build.openshift.io/v1"
kind: "BuildConfig"
metadata:
name: "quarkus-app"
spec:
source:
binary: {}
strategy:
sourceStrategy:
from:
kind: "DockerImage"
name: "registry.access.redhat.com/ubi8/openjdk-11"
Now, let’s trigger the previous Build configuration using our binaries:
mvn clean install
And trigger the s2i from the target/quarkus-app
location:
oc start-build quarkus-app --from-dir=target --follow=true --wait
Note that we’re assuming that you’re using the fast-jar package type which is the default option. If not, basically you need to pick the folder where the .jar file is. |
When finished, the App image should be installed in our project:
> oc get imagestream
NAME IMAGE REPOSITORY TAGS UPDATED
quarkus-app default-route-openshift-image-registry.apps.XXXX/my-project/quarkus-app latest 41 minutes ago
And, finally, let’s deploy it and expose the service.
oc new-app quarkus-app:latest
oc expose svc/quarkus-app
Check out the generated routes for our app:
> oc get routes
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
quarkus-app quarkus-app-my-project.apps.XXXX app 8080-tcp None
We should be able to invoke our App which is up and running in our OCP instance!
> curl quarkus-app-my-project.apps.XXXX/hello
Hello RESTEasy!
- From Sources
This method is even easiest, but we need our sources to be publicly available in a repository like github.com and then create all the application resources in one go:
oc new-app registry.access.redhat.com/ubi8/openjdk-11~https://github.com/quarkusio/quarkus-quickstarts.git --context-dir=getting-started --name=quarkus-app
Note that registry.access.redhat.com/ubi8/openjdk-11 is the image builder, see the introduction for further details. |
This command will create the deployment config, the service, the build config and will start the build in one go. In order to see how the build goes:
oc logs -f bc/quarkus-app
When finished, we can expose the service and use it:
oc expose svc/quarkus-app
Check out the generated routes for our app:
> oc get routes
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
quarkus-app quarkus-app-my-project.apps.XXXX app 8080-tcp None
And we should be able to invoke our App which is up and running in our OCP instance!
> curl quarkus-app-my-project.apps.XXXX/hello/greeting/quarkus
hello quarkus
Using Quarkus OpenShift extension
Is there an even easiest way to deploy Quarkus apps into OpenShift? Yes! Using the Quarkus OpenShift extension.
All we need is to add the Quarkus OpenShift extension into our pom.xml:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-openshift</artifactId>
</dependency>
Or using the Quarkus CLI tool:
> quarkus extension add quarkus-openshift
[SUCCESS] ✅ Extension io.quarkus:quarkus-openshift has been installed
And deploy it using the Maven command:
mvn clean package -Dquarkus.kubernetes.deploy=true -Dquarkus.openshift.route.expose=true
Note that if you are using an OpenShift with unsecure SSL, you also need to append -Dquarkus.kubernetes-client.trust-certs=true to the Maven command. |
Internally, this method will use the Binaries s2i to build the image and then start the application. However, you can configure this method by using either Docker or jib. More in here. |
When the Maven command finished, your app should be up and running!
> oc get routes
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
quarkus-app quarkus-app-my-project.apps.XXXX app 8080-tcp None
And we should be able to invoke our App which is up and running in our OCP instance!
> curl quarkus-app-my-project.apps.XXXX/hello
Hello RESTEasy!
Manual: Using Container Registry
Do you like to do everything on your own? Fair enough! Let’s explain how to deploy Quarkus applications without using s2i or the Quarkus OpenShift extension, but directly docker and a container registry where to push/pull images.
First thing you need is to have access to a container registry and be logged in:
docker login <container-registry>
Where <container-registry>
could be quay.io
.
Then, we need to build our images locally. The good news is that the auto generated project by code starters contains the necessary Dockerfile
, so all you need to do is:
> docker build -f src/main/docker/Dockerfile.jvm -t quarkus-app:latest .
(...)
Successfully tagged quarkus-app:latest
This example only shows the JVM build, but the native Dockerfile is also present by default when generating a new Quarkus project. |
Let’s push the recently created quarkus-app:latest
image into our container registry:
docker tag quarkus-app:latest <container-registry>/<namespace>/quarkus-app:latest
docker push <container-registry>/<namespace>/quarkus-app:latest
Now, we can create our application in our OpenShift project using this image:
oc new-app <container-registry>/<namespace>/quarkus-app:latest
And expose it:
oc expose svc/quarkus-app
Check out the generated routes for our app:
> oc get routes
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
quarkus-app quarkus-app-my-project.apps.XXXX app 8080-tcp None
And we should be able to invoke our App which is up and running in our OCP instance!
> curl quarkus-app-my-project.apps.XXXX/hello
Hello RESTEasy!
Kubernetes
We don’t have s2i in Kubernetes, but there are other many options to deploy applications into Kubernetes. For now, I’ve only included the container registry strategy.
Again, we recommend first to create a new Kubernetes project where to deploy our resources:
kubect create namespace my-project
Manual: Using Container Registry
First thing you need is to have access to a container registry and be logged in:
docker login <container-registry>
Where <container-registry>
could be quay.io
.
Then, we need to build our images locally. The good news is that the auto generated project by code starters contains the necessary Dockerfile
, so all you need to do is:
> docker build -f src/main/docker/Dockerfile.jvm -t quarkus-app:latest .
(...)
Successfully tagged quarkus-app:latest
This example only shows the JVM build, but the native Dockerfile is also present by default when generating a new Quarkus project. |
Let’s push the recently created quarkus-app:latest
image into our container registry:
docker tag quarkus-app:latest <container-registry>/<namespace>/quarkus-app:latest
docker push <container-registry>/<namespace>/quarkus-app:latest
Now, we can create our application in our Kubernetes project using this image:
kubectl create deployment --image=<container-registry>/<namespace>/quarkus-app:latest quarkus-app
And expose it:
kubectl expose deployment quarkus-app --port=8080 --name=quarkus-app-http
And we should be able to invoke our App which is up and running in our Kubernetes instance!
Future Cloud Infrastructure to cover
- Amazon
- Azure
- Google Cloud