Deploying to Google Cloud Platform (GCP)

This guide covers:

  • Login to Google Cloud

  • Deploying a function to Google Cloud Functions

  • Deploying a JAR to Google App Engine Standard

  • Deploying a Docker image to Google App Engine Flexible Custom Runtimes

  • Deploying a Docker image to Google Cloud Run

  • Using Cloud SQL

Prerequisites

For this guide you need:

This guide will take as input an application developed in the Getting Started guide.

Make sure you have the getting-started application at hand, or clone the Git repository: git clone https://github.com/quarkusio/quarkus-quickstarts.git, or download an archive. The solution is located in the getting-started directory.

Login to Google Cloud

Login to Google Cloud is necessary for deploying the application and it can be done as follows:

gcloud auth login

Deploying to Google Cloud Functions

Quarkus supports deploying your application to Google Cloud Functions via the following extensions:

Each extension supports a specific kind of application development, follow the specific guides for more information on how to develop, package and deploy your applications using them.

Deploying to Google App Engine Standard

We will only cover the Java 11 runtime as the Java 8 runtime uses its own Servlet engine which is not compatible with Quarkus.

First of all, make sure to have an App Engine environment initialized for your Google Cloud project, if not, initialize one via gcloud app create --project=[YOUR_PROJECT_ID].

Then, you will need to create a src/main/appengine/app.yaml file, let’s keep it minimalistic with only the selected engine:

runtime: java11

This will create a default service for your App Engine application.

App Engine Standard does not support the default Quarkus' specific packaging layout, therefore, you must set up your application to be packaged as an uber-jar via your application.properties file:

quarkus.package.type=uber-jar

Then, you can choose to build the application manually or delegating that responsibility to gcloud or the Google Cloud Maven plugin.

Building the application manually

Use Maven to build the application using mvn clean package, it will generate a single JAR that contains all the classes of your application including its dependencies.

Finally, use gcloud to deploy your application as an App Engine service.

gcloud app deploy target/getting-started-1.0.0-SNAPSHOT-runner.jar

This command will upload your application jar and launch it on App Engine.

When it’s done, the output will display the URL of your application (target url), you can use it with curl or directly open it in your browser using gcloud app browse.

Building the application via gcloud

You can choose to let gcloud build your application for you, this is the simplest way to deploy to App Engine.

Then, you can just launch gcloud app deploy in the root of your project, it will upload all your project files (the list can be reduced via the .gcloudignore file), package your JAR via Maven (or Gradle) and launch it on App Engine.

When it’s done, the output will display the URL of your application (target url), you can use it with curl or directly open it in your browser using gcloud app browse.

Building the application via the Google Cloud Maven plugin

You can also let Maven control the deployment of your application using the App Engine Maven plugin.

First, add the plugin to your pom.xml:

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>appengine-maven-plugin</artifactId>
    <version>2.4.0</version>
    <configuration>
        <projectId>GCLOUD_CONFIG</projectId> (1)
        <version>gettingstarted</version>
        <artifact>${project.build.directory}/${project.artifactId}-${project.version}-runner.jar</artifact> (2)
    </configuration>
</plugin>
  1. Use the default gcloud configuration

  2. Override the default JAR name to the one generated by the Quarkus Maven plugin

Then you would be able to use Maven to build and deploy your application to App Engine via mvn clean package appengine:deploy.

When it’s done, the output will display the URL of your application (target URL), you can use it with curl or directly open it in your browser using gcloud app browse.

Deploying to Google App Engine Flexible Custom Runtimes

Before all, make sure to have an App Engine environment initialized for your Google Cloud project, if not, initialize one via gcloud app create --project=[YOUR_PROJECT_ID].

App Engine Flexible Custom Runtimes uses a Docker image to run your application.

First, create an app.yaml file at the root of your project with the following content:

runtime: custom
env: flex

App Engine Flexible Custom Runtimes deploys your application as a Docker container, you can choose to deploy one of the Dockerfile provided inside your application.

Both JVM and native executable versions will work.

To deploy a JVM application:

  • Copy the JVM Dockerfile to the root directory of your project: cp src/main/docker/Dockerfile.jvm Dockerfile.

  • Build your application using mvn clean package.

To deploy a native application:

  • Copy the native Dockerfile to the root directory of your project: cp src/main/docker/Dockerfile.native Dockerfile.

  • Build your application as a native executable using mvn clean package -Dnative.

Finally, launch gcloud app deploy in the root of your project, it will upload all your project files (the list can be reduced via the .gcloudignore file), build your Dockerfile and launch it on App Engine Flexible custom runtime.

It uses Cloud Build to build your Docker image and deploy it to Google Container Registry (GCR).

When done, the output will display the URL of your application (target url), you can use it with curl or directly open it in your browser using gcloud app browse.

App Engine Flexible custom runtimes support health checks, it is strongly advised to provide them thanks to Quarkus Microprofile Health support.

Deploying to Google Cloud Run

Google Cloud Run allows you to run your Docker containers inside Google Cloud Platform in a managed way.

By default, Quarkus listens on port 8080, and it’s also the Cloud Run default port. No need to use the PORT environment variable defined in Cloud Run to customize the Quarkus HTTP port.

Cloud Run will use Cloud Build to build your Docker image and deploy it to Google Container Registry (GCR).

Both JVM and native executable versions will work.

To deploy a JVM application:

  • Copy the JVM Dockerfile to the root directory of your project: cp src/main/docker/Dockerfile.jvm Dockerfile.

  • Build your application using mvn clean package.

To deploy a native application:

  • Copy the native Dockerfile to the root directory of your project: cp src/main/docker/Dockerfile.native Dockerfile.

  • Build your application as a native executable using mvn clean package -Dnative.

Then, create a .gcloudignore file to tell gcloud which files should be not be uploaded for Cloud Build, without it, it defaults to .gitignore that usually exclude the target directory where you packaged application has been created.

In this example, I only exclude the src directory:

src/

Then, use Cloud Build to build your image, it will upload to a Google Cloud Storage bucket all the files of your application (except the ones ignored by the `.gcloudignore`file), build your Docker image and push it to Google Container Registry (GCR).

gcloud builds submit --tag gcr.io/PROJECT-ID/helloworld
You can also build your image locally and push it to a publicly accessible Docker registry, then use this image in the next step.

Finally, use Cloud Run to launch your application.

gcloud run deploy --image gcr.io/PROJECT-ID/helloworld --platform managed

Cloud run will ask you questions on the service name, the region and whether or not unauthenticated calls are allowed. After you answer to these questions, it will deploy your application.

When the deployment is done, the output will display the URL to access your application.

Using Cloud SQL

Google Cloud SQL provides managed instances for MySQL, PostgreSQL and Microsoft SQL Server. Quarkus has support for all three databases.

Using Cloud SQL with a JDBC driver

To make your applications work with Cloud SQL, you first need to use the corresponding JDBC extension, for example, for PostgreSQL, add the quarkus-jdbc-postgresql extension.

Then you need to add to your pom.xml the Cloud SQL JDBC library that provides the additional connectivity to Cloud SQL. For PostgreSQL you will need to include the following dependency:

<dependency>
    <groupId>com.google.cloud.sql</groupId>
    <artifactId>postgres-socket-factory</artifactId>
    <version>${postgres-socket-factory.version}</version>
</dependency>

Finally, you need to configure your datasource specifically to use the socket factory:

quarkus.datasource.db-kind=other (1)
quarkus.datasource.jdbc.url=jdbc:postgresql:///mydatabase (2)
quarkus.datasource.jdbc.driver=org.postgresql.Driver
quarkus.datasource.username=quarkus
quarkus.datasource.password=quarkus
quarkus.datasource.jdbc.additional-jdbc-properties.cloudSqlInstance=project-id:gcp-region:instance (3)
quarkus.datasource.jdbc.additional-jdbc-properties.socketFactory=com.google.cloud.sql.postgres.SocketFactory (4)
1 Database kind must be 'other' as we need to skip Quarkus auto-configuration.
2 The JDBC URL should not include the hostname / IP of the database.
3 We add the cloudSqlInstance additional JDBC property to configure the instance id.
4 We add the socketFactory additional JDBC property to configure the socket factory used to connect to Cloud SQL, this one is coming from the postgres-socket-factory dependency.
If you use Hibernate ORM, you also need to configure quarkus.hibernate-orm.dialect=org.hibernate.dialect.PostgreSQL10Dialect as Hibernate ORM would not be able to automatically detect the dialect of your database.
Using a PostgreSQL socket factory is not possible in dev mode at the moment due to issue #15782.

Using Cloud SQL with a reactive SQL client

You can also use one of our reactive SQL client instead of the JDBC client. To do so with Cloud SQL, add the following dependency (adjust the classifier depending on your platform):

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-transport-native-epoll</artifactId>
    <classifier>linux-x86_64</classifier>
</dependency>

Then configure your reactive datasource with no hostname and with the Netty native transport:

quarkus.datasource.reactive.url=postgresql://:5432/db-name?host=/cloudsql/project-id:zone:db-name
quarkus.vertx.prefer-native-transport=true
This only works when your application is running inside a Google Cloud managed runtime like App Engine.

Going further

You can find a set of extensions to access various Google Cloud Services in the Quarkiverse (a GitHub organization for Quarkus extensions maintained by the community), including PubSub, BigQuery, Storage, Spanner, Firestore, Secret Manager (visit the repository for an accurate list of supported services).

You can find some documentation about them in the Quarkiverse Google Cloud Services repository.