Deploying a Quarkus native app to Cloud Run

Alexis MP
3 min readApr 9, 2019

--

(updated to Quarkus 1.0 RC)

If you haven’t heard of Google Cloud Run, which was announced at Cloud Next ’19, you should check out cloud.google.com/run for more details.

Essentially this is a way to deploy and scale your stateless containers on a serverless infrastructure — no infra or cluster to setup/manage, auto-scaling (including to zero), and billing as you go based on actual user requests, not on instances running.

Cloud Run

Quarkus on the other hand is also a recent project by RedHat introduced here and meant to support cloud native Java apps with an option to compile them down to native code.

This article explores the deployment of Quarkus native app to Cloud Run (all using Cloud Shell to minimize setup steps). This should be a nice combo with fast startup time, thus minimizing any cold start issue.

I followed the Quarkus getting started and Building a Native Executable instructions, up until the “Packaging and run the application” section. I then built and packaged the sample app using these commands :
$ mvn package -Pnative -Dquarkus.native.container-build=true
$ docker build -f src/main/docker/Dockerfile.native .

The Java application is compiled into a native Linux 64-bit binary optimized for startup time and memory consumption using GraalVM and is containerized. Building the application into a native artifact does take a bit of time (about 5 minutes for me, but YMMV). You can think of this a trading compile time for runtime performance.

To use Cloud Build instead of building locally, you can use a multi-stage Docker build (no need to make GraalVM available to the build environment).

I then tagged and pushed the resulting docker image to Cloud Registry using a reference to the Google Cloud $PROJECT_ID that I use :
$ docker tag 0b03762bad42 gcr.io/$PROJECT_ID/quarkus-quickstart
$ docker push gcr.io/$PROJECT_ID/quarkus-quickstart

At this point I am are ready to deploy the container to Cloud Run :
$ gcloud beta run deploy \
--platform managed \
--allow-unauthenticated \
--image gcr.io/$PROJECT_ID/quarkus-quickstart \
--set-env-vars DISABLE_SIGNAL_HANDLERS=foobar

That’s really it! Nothing else to configure!
Note: the environment variable listed in the command above is required as discussed in this Quarkus issue (tl;dr: shutdown hooks are not called).

Note that you can also map your own custom domain

Your app is now exposed as a service on a run.app domain and it will auto-scale from 0 to multiple container instances to adapt to the incoming load.

First revision deployed, getting all the traffic from the “run.app” domain

The logs show a nice startup time indeed :

getting-started 1.0-SNAPSHOT (running on Quarkus 1.0.0.CR1) started in 0.264s. Listening on: http://0.0.0.0:8080

If you enjoy Quarkus, Google Cloud Run is a great option to deploy your containers. If you’d rather deploy to an existing Kubernetes cluster which you manage then try Cloud Run on Anthos and deploy that same container! The underlying Knative technology is what makes Cloud Run workloads portable.

Next steps would be to hook up the application to Cloud SQL, Cloud Datastore or other GCP databases.

Here are a few additional Cloud Run resources:

--

--