Categories
GCP Java Quarkus

How to deploy Quarkus on Google App Engine

The App Engine is not a tool for “lazy” developers. It’s more than just an easy way to deploy your app. App Engine covers scaling, availability, logging and more.

For more then 4 years, I was super skeptical about such solutions, in my eyes they were “limiting” your architecture freedom. Few months ago, I realized how wrong I was. Let me show you small example that I had to scale once.

Small history

I was involved in a small startup that operates globally. Let’s say they earn $10k per month, minus developers salary, minus costs of operation, minus small expenses we left with “can we please spend as little as possible on server expenses?”. The next picture shows the initial architecture.

Super-simple non-scalable architecture

There was initially no external storage and SQL, all those services were in a virtual machine, but I decided to show visually what was present in app. All for all pricing was around $6. How it was scaling? Stop instance, rescale CPU and memory, start again. The first idea, of course, was to use Kubernetes. Here’s already more scalable version:

Scalable Kubernetes Architecture

This is already something more beautiful, but, let’s compute how much we’ll spend on this beauty:

  1. You run GKE all the time, which means you pay for 3 nodes, which is $157 per months with 1-year commitment
  2. The load balancer would go for 22 bucks per 100GiB of traffic
  3. 100 GB of storage will cost $2.60
  4. Cloud SQL would cost $88 per months with 3 instances and a 30% discount

And the total is $271.65 per 1 month. Which is around $3259 per year. Wow, probably not the best solution for a small startup. The problem arises when we look at service usage by hours. Most of the traffic comes from Europe and US at noon. These peaks are when we need our full capacity, while other times(especially from 24:00 to 6:00) we need as little as possible.

Example of service usage on average.

Quarkus on App Engine

You’ll see at the end of the article how much we saved on choosing App Engine decision, but I can say already that it was right. They have a free quota that will cover the initial stage where you have zero or a small amount of people using your service. And if you go over this limit, you’ll pay a reasonable price for it. Let’s start with a simple example.

Setup App Engine

Open Google Cloud Console, locate App Engine by search or side menu.

Select App Engine

Click “Create Application”

Click Create Application

You then select region that’s closest to your customers, region scaling can be done with different additional services, but they’re out of the scope for this article. Select then Java Language and Standard environment, and click Next.

Specify Java Language and Standart Environment

That’s it for now. You need to have gcloud util on your local environment, if not, install it here. Then you’ll need to call gcloud init, specify your project and region. That’s it for setup, let’s configure our project.

Setup Quarkus project

Get project that you want to put on App Engine or create a new one

We’ll be using maven plugin to deploy our app. We have <build><plugins> scope, put next bold lines to your pom.xml

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>${surefire-plugin.version}</version>
  <configuration>
    <systemProperties>
      <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
    </systemProperties>
  </configuration>
</plugin>
<plugin>
  <groupId>com.google.cloud.tools</groupId>
  <artifactId>appengine-maven-plugin</artifactId>
  <version>2.2.0</version>
  <configuration>
    <projectId>GCP_PROJECT_ID</projectId>
    <version>${appengine.build.number}</version>
    <artifact>${project.build.directory}/${project.build.finalName}-runner.jar</artifact>
  </configuration>
</plugin>
</plugins>

Replace GCP_PROJECT_ID with your project id. We’ll also need to add appengine.build.number variable to properties scope

<properties>
  ...
  <surefire-plugin.version>2.22.1</surefire-plugin.version>
  <appengine.build.number>0-0-1</appengine.build.number>
</properties>

That’s it. We only have two more actions to do. Firstly, you need to redirect HTTP port to any that App Engine will provide in application.properties

quarkus.http.port=${PORT:8080}

App Engine can use any port for the app, that’s done for sharing purposes. You’ll have a personalized URL with the name of the project, so you don’t need to think about which port your app is running.

And secondly, we need to have a YAML file that describes how to build your app. I put them into src/main/appengine/app.yaml

runtime: java11
instance_class: F1

We specify that we use java11, as well as F1 instance type, F1 has 256 MB of memory, and 600 MHz of CPU, which should be more than enough for many purposes. Keep in mind that this is settings for single deployment, App Engine will scale it depending on load.

That’s it, let’s enjoy our deployment with :

./mvnw clean package appengine:deploy

In the output, you’ll see some link that ends with *.appspot.com. This is the link that you can use to access your service. Click on it, and you’ll see our favorite Quarkus welcome screen.

Example of Quarkus running on App Engine

View logs

That’s cool and all, but how, you ask me, do I view any issues occurring with my service? And logs in general. And I’ll say to you that you can view logs both form command line and from nice logger on the console.

View logs via command line

To view logs from command line, just use next command.

 gcloud app logs tail -s default

You’ll need to execute some endpoints to see new data, this will output default data that you’ll get from running app in command line.

View logs online

Sometimes it’s better to look at specific log online. It’s easy, open up again App Engine page, go to versions, click on Tools dropdown near your app version, and you’ll get Logs.

From there it’s straightforward.

Debugging Quarkus from GCP Console

What? You can do that? Yes, absolutely. You can debug your app without restarting, redeploying or any other magic that you usually do.

In the previous screen near the Logs you have a Debug button, click on this, it’ll open Debugger window. Debugger is another service that Google provides to help you manage your app better and faster navigate any problems. You’ll be prompted to give access to your source code, it’s required by any remote debugger because your jar only contains compiled code that doesn’t correspond line-by-line with source code. Also, grant any access to Github or your git provider.

Now You’ll see list of all the source files that you have, open ExampleResource.java (or any other), and put a breakpoint at the return statement

Then execute this endpoint(e.g from browser)

curl https://your-app-id/hello

Once you’ll see blue line, that means you caught your own call(or someone else’s if you already have users)

On the right, you’ll see familiar stack, variables and conditions view:

List of debugging info once Debugger captured call

You can specify any conditions on which you want the debugger to capture, and once it’s there, you can see all available variables and stack trace from where your code executed. It won’t compare with IDE debugger, but still impressive enough, and can be helpful if you want to capture something that occurs really really rarely and by specific users. You can store snapshots of captured executions, which is really helpful.

In conclusion

Thanks to App Engine I managed to cut costs from possible 200-400 dollars to just 50, sometimes there were no costs for some days because there’s a free tier below a specific amount. There was one more thing that I changed, and it’s replacing MySQL with Firestore, which is a topic for next article 😉

App Engine is not for any use case, you can’t run sockets there(however there’s special Stream API that can do that), you’re limited to 30 seconds by default. But many different apps can benefit from it, especially by saving many idle hours, where App Engine can drop instances to zero. Taking this into account, your app should be really fast on startup, this is where Quarkus shines really bright.

Think also outside the box, you’re not forced to use only App Engine or only Kubernetes. Why not mix them up?

Weekly Quarkus Newsletter

Our newsletter saves your precious time with curated list of top news, guides and articles of the week

Marketing by

Leave a Reply

Connect with




Your email address will not be published. Required fields are marked *