////
This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
////
= Quarkus - Deploying to Google Cloud Platform (GCP)

include::./attributes.adoc[]

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

== Prerequisites

For this guide you need:

* Roughly 1 hour for all modalities
* JDK 11
* Apache Maven {maven-version}
* https://cloud.google.com/[A Google Cloud Account].  Free accounts work.
* https://cloud.google.com/sdk[Cloud SDK CLI Installed]

This guide will take as input an application developed in the link:getting-started[Getting Started guide].

Make sure you have the getting-started application at hand, or clone the Git repository: `git clone {quickstarts-clone-url}`,
or download an {quickstarts-archive-url}[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:

[source, subs=attributes+]
----
gcloud auth login
----

== Deploying to Google Cloud Functions

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

- link:gcp-functions[Google Cloud Functions]: Build functions using the Google Cloud Functions API.
- link:gcp-functions-http[Google Cloud Functions HTTP binding]: Build functions using Quarkus HTTP APIs: RESTEasy (JAX-RS),
Undertow (Servlet), Vert.x Web, or link:funqy-http[Funqy HTTP].
- link:funqy-gcp-functions[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

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:

[source, yaml]
----
runtime: java11
----

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

Then, you can choose to build the application by yourself or letting `gcloud` or the Google Cloud Maven plugin build it for you.

=== Building the application manually

Set up your application to be packaged as an uber-jar via your `application.properties` file:

[source, properties]
----
quarkus.package.type=uber-jar
----

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.

[source, shell script]
----
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 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.

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 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`:

[source,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}/getting-started-${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:

[source, yaml]
----
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`.

NOTE: App Engine Flexible custom runtimes support link:https://cloud.google.com/appengine/docs/flexible/custom-runtimes/configuring-your-app-with-app-yaml#updated_health_checks[health checks],
it is strongly advised to provide them thanks to Quarkus link:microprofile-health[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.

NOTE: 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:

[source]
----
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).

[source, shell script]
----
gcloud builds submit --tag gcr.io/PROJECT-ID/helloworld
----

NOTE: 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.

[source, shell script]
----
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.

== 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 (visit the repository for an accurate list of supported services).

You can find some documentation about them in the link:https://github.com/quarkiverse/quarkiverse-google-cloud-services[Quarkiverse Google Cloud Services repository].
