Deploy Spring Boot App to GCP App Engine
Explore the full use of the benefits of cloud computing with this simple tutorial.
Join the DZone community and get the full member experience.
Join For FreeIn this post, we are going to deploy a Spring Boot application to the Google Cloud Platform (GCP) App Engine. First, we will take a look at the differences between the standard and flexible environment of App Engine. After that, we will describe step by step how the deployment to GCP App Engine can be accomplished.
1. What Is App Engine?
GCP App Engine is a cloud platform where you can quickly deploy your application without worrying too much about the infrastructure. Besides that, your application can automatically scale up and down, you can debug and monitor your application, split traffic, etc.
Two types of App Engine environments exist: the standard environment and the flexible environment. Which environment to choose depends on your application’s needs. A complete comparison of features between the two environments can be found here.
You choose for the standard environment when:
- You don’t mind that your application is running in a sandbox that is limited to a specific set of languages and runtime versions;
- Your application needs rapid scaling;
- You only want to pay when your application is being used;
- Pricing is based on instance hours.
You choose for a flexible environment when:
- You want your application to run inside Docker containers on Compute Engine virtual machines;
- Your application receives a constant flow of traffic and gradually needs scaling up and down;
- You need to use a programming language or runtime version which is not supported by the standard environment;
- You need to access resources or services of your GCP project;
- You pay based on the usage of vCPU, memory, and persistent disks.
Besides the functional differences between the standard and flexible environment, the differences in costs between the two environments can also be decisive in which one to choose. A helpful tool in order to find out what the costs will be is available on the GCP Pricing Calculator.
2. Deploy to Flexible Environment
We will start with deployment to a flexible environment. The reason for this will become clear when we try to deploy to the standard environment. Sources being used can be found at GitHub.
Create the Application
First, we need to create a Spring Boot application. We create this at start.spring.io and choose Java 1.8 and Web MVC. We choose Java 1.8 because this is the supported Java version for the standard environment and our aim is to use this same application for deployment to the standard environment without any changes.
We add a HelloController
that prints a Hello Google App Engine welcome message and the host where our application is running:
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
StringBuilder message = new StringBuilder("Hello Google App Engine!");
try {
InetAddress ip = InetAddress.getLocalHost();
message.append(" From host: " + ip);
} catch (UnknownHostException e) {
e.printStackTrace();
}
return message.toString();
}
}
In order to make the deployment to App Engine easier, we add the App Engine Maven Plugin to our pom
:
<build>
<plugins>
...
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<version>1</version>
</configuration>
</plugin>
</plugins>
</build>
We also need an app.yaml
file, which is needed to configure your App Engine application’s settings. A complete reference for the app.yaml
file can be found here. We add the following app.yaml
file to directory src/main/appengine/
:
runtime: java
env: flex
handlers:
- url: /.*
script: this field is required, but ignored
Create the GCP Project
Now that we have created our application, it is time to turn to the Google Cloud Platform.
Create a MyGoogleAppEnginePlanet project in GCP. This also shows us the project ID, which we must remember somewhere.
Start the Google Cloud Shell in the browser and clone the git repository:
$ git clone https://github.com/mydeveloperplanet/mygoogleappengineplanet.git
Enter the mygoogleappengineplanet directory and run the application:
$ mvn clean spring-boot:run
Our application now runs in the console and we can use web preview in order to access our hello URL:
In the browser, a new tab is opened to the following URL:
https://8080-dot-6340638-dot-devshell.appspot.com/?authuser=0
This will show a 404 error page because it maps to the root URL. Let’s change it to our hello URL:
https://8080-dot-6340638-dot-devshell.appspot.com/hello/?authuser=0
This will show us our welcome message, as expected:
Hello Google App Engine! From host: cs-6000-devshell-vm-859e05a5-a8a3-4cd2-813f-af385740076b/172.17.0.3
Deploy to App Engine
When creating an application in AppEngine, we need to choose a region where the application will be running. The list of regions can be shown by issuing the command:
$ gcloud app regions list
We will choose region europe-west
and create our AppEngine app:
$ gcloud app create --region europe-west
You are creating an app for project [gentle-respect-234016].
WARNING: Creating an App Engine application for a project is irreversible and the region
cannot be changed. More information about regions is at
<https://cloud.google.com/appengine/docs/locations>.
Creating App Engine application in project [gentle-respect-234016] and region [europe-west]....done.
Success! The app is now created. Please use `gcloud app deploy` to deploy your first app.
From within our git repository directory, we can deploy our application:
$ mvn -DskipTests appengine:deploy
After deployment, open the browser and enter the welcome URL:
https://gentle-respect-234016.appspot.com/hello
This will show us the hello message again.
In order to prevent extra charges against your GCP credit, you should shut down your GCP project.
3. Deploy to Standard Environment
Deployment to the standard environment deploys your application into a Jetty Web Server. The standard environment is mostly used for stateless web applications, which need to respond quickly to requests. Your application also runs in a sandbox. Because our application is running in a Jetty Web Server, the default configuration for a Spring Boot application will not work. This causes several conflicts because Spring Boot uses an embedded Tomcat Web Server. More information about the configuration of a Spring Boot application for the standard environment can be found here. The sources for the standard environment are available in the feature/standardenv branch of our git repository.
Convert for Standard AppEngine
In this section, we will convert our previously created application with configuration for the flexible environment to a configuration that will be deployable to the standard environment.
We need to remove the app.yaml
file and we add an appengine-web.xml
in directory src/main/webapp/WEB-INF
with the following contents:
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<threadsafe>true</threadsafe>
<runtime>java8</runtime>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties"/>
</system-properties>
</appengine-web-app>
We add a SpringBootServletInitializer
implementation:
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyGoogleAppEnginePlanetApplication.class);
}
}
The following changes are made to our pom
:
...
<packaging>war</packaging>
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- Exclude any jul-to-slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<scope>provided</scope>
</dependency>
..
And finally, we add a logging.properties
file into src/main/resources
:
.level = INFO
Run and Deploy
In order to run the application, we need to issue the following command:
$ mvn appengine:run
In the logs, we can clearly see that the standard environment is used:
[INFO] Detected App Engine standard environment application.
The URL is again accessible via the web preview, just as we did before at the flexible environment.
Deployment to AppEngine is identical as for the flexible environment:
$ mvn -DskipTests appengine:deploy
Check the correct deployment by accessing the URL via web preview and the following response is issued:
Hello Google App Engine! From host: localhost/127.0.0.1
4. Conclusion
In this post, we looked at the GCP App Engine and how we can deploy a Spring Boot application to the standard and flexible environment. We would not advise deploying a Spring Boot application to the standard environment because you need to convert it in order to make it run into a Jetty Web Server. You will lose some benefits of Spring Boot. This does not mean that you should never use the standard environment. Spring Boot is probably not the best technical choice for the standard environment. The flexible environment in combination with Spring Boot is easy to use. Besides that, you have the choice of choosing another runtime than Java 8, and you can keep the benefits of using a Spring Boot application.
Published at DZone with permission of Gunter Rotsaert, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments