How to deploy a (native) Quarkus Application on Heroku

Quarkus is a „container first“ framework for microservice development in Java (or alternatively Kotlin or Scala). With help of GraalVM Native Image, Quarkus applications can be compiled to native executables that run directly on the target OS, without JVM, with low memory footprint and blazing fast startup time.

Heroku is a Cloud Application Platform for building and hosting applications, while various languages can be used for development. It also allows to deploy and run self-built docker images.

Following the instructions from this blog post, we’ll create a native Quarkus application and deploy it in a docker container to the Heroku Runtime.

Prerequisites

The following needs to be installed on our development machine:

  • Java 8 or 11(+)
  • Maven
  • Docker
  • Heroku CLI

 

Creating the Quarkus app

(For more detailed instructions please consult the Quarkus website.)

We can bootstrap a quarkus project using the quarkus-maven-plugin:

We change into the newly created project directory, and run the application in Quarkus Development Mode:

Now we can test the application in another terminal. The application already contains a „hello“ REST resource. Request it with curl (or open http://localhost:8080/hello in a browser):

Stop the Quarkus Dev Mode with Ctrl+C.

Next, we’ll build the application to a native executable:

With -Pnative we activate a maven profile which creates the native executable. The parameter -Dquarkus.native.container-build=true tells Quarkus to build the application within a docker container. This way we don’t need to have GraalVM installed on our machine, since it’s present in the docker container used for the build. The resulting application will be a Linux executable (even if it’s built on Windows).

Now we go and grab a coffee, since the build will take a while (about 3 minutes on my laptop). The result is a file in the target directory named hello-quarkus-1.0-SNAPSHOT-runner. On Linux or WSL (Windows Subsystem for Linux) you can run it like this:

Now we build a docker image containing this application. The Quarkus app contains a dockerfile to do this, src/main/docker/Dockerfile.native (it’s content without comments is shown below):

However we cannot use this out of the box, because Heroku requires that the application’s port can be set with the $PORT environment variable. Therefore we need to change the last line to
CMD ./application -Dquarkus.http.host=0.0.0.0 -Dquarkus.http.port=${PORT}. We can also get rid of the line above (EXPOSE 8080), since we don’t really need it. The resulting Dockerfile.native looks like this:

Using this we build a docker image named quarkus/hello-quarkus

… and run with docker:

Note how we specify the application’s port via the --env PORT=8081 parameter. Now we can request the „hello“ resource again, this time using port 8081:

Deploying the app to Heroku

(The official documentation for this can be found on the Heroku website)

First we log in to our Heroku account:

Next, we create a Heroku application (replace <app-name> by whatever you want; however it must be unique on Heroku. Leave out the --region eu part if you’re on the American continent; in this case the default region us will be used):

Log in to the Heroku container registry:

We tag the previously built docker image and push it to the Heroku container registry (replacing <app-name> by the name of our Heroku app again):

Finally, we instruct Heroku to run the image like so (don’t forget to replace <app-name>):

Done! Now we can request the „hello“ resource from our app running on Heroku (replacing <app-name> again, you’ll guess):

Conclusion

It’s not too hard to deploy a Quarkus app to Heroku. Most of the time we could just follow the instructions from the official documentation. The only thing we needed to do was adjust the Dockerfile, to meet Heroku’s requirement that the application’s port can be set via the $PORT environment variable.

Zurück zur Übersicht

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*Pflichtfelder

*