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
To complete this guide, you need:
-
Roughly 1 hour for all modalities
-
An IDE
-
JDK 17+ installed with
JAVA_HOME
configured appropriately -
Apache Maven 3.9.9
-
Optionally the Quarkus CLI if you want to use it
-
A Google Cloud Account. Free accounts work.
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. 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:
-
Google Cloud Functions: Build functions using the Google Cloud Functions API.
-
Google Cloud Functions HTTP binding: Build functions using Quarkus HTTP APIs: Quarkus REST (formerly RESTEasy Reactive, our Jakarta REST implementation), Undertow (Servlet), Vert.x Web, or Funqy HTTP.
-
Funky Google Cloud Functions: Build functions using Funqy.
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
First, 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: java21
This will create a default service for your App Engine application.
You can also use another Java runtime supported by App Engine, for example, for Java 17, use |
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.jar.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.7.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 SmallRye 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
Cloud run will ask you questions on the service name, the region and whether 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.
Cloud Run supports health checks, it is strongly advised to provide them thanks to Quarkus SmallRye Health support. |
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=postgresql
quarkus.datasource.jdbc.url=jdbc:postgresql:///mydatabase (1)
quarkus.datasource.username=quarkus
quarkus.datasource.password=quarkus
quarkus.datasource.jdbc.additional-jdbc-properties.cloudSqlInstance=project-id:gcp-region:instance (2)
quarkus.datasource.jdbc.additional-jdbc-properties.socketFactory=com.google.cloud.sql.postgres.SocketFactory (3)
1 | The JDBC URL should not include the hostname / IP of the database. |
2 | We add the cloudSqlInstance additional JDBC property to configure the instance id. |
3 | 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. |
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. |
Using Cloud SQL with native executables
When generating native executables, you must mark jnr.ffi.provider.jffi.NativeFinalizer$SingletonHolder
as runtime initialized.
quarkus.native.additional-build-args=--initialize-at-run-time=jnr.ffi.provider.jffi.NativeFinalizer$SingletonHolder
Additionally, starting with com.google.cloud.sql:postgres-socket-factory:1.17.0
, you must also mark com.kenai.jffi.internal.Cleaner
as runtime initialized.
quarkus.native.additional-build-args=--initialize-at-run-time=jnr.ffi.provider.jffi.NativeFinalizer$SingletonHolder\\,com.kenai.jffi.internal.Cleaner
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 documentation.