Published: March 26, 2017
GCP's (Google App Engine) App Engine Flex is an amazing product. It's comparable to AWS's (Amazon Web Service) Elastic Beanstalk, but instead of using proprietary ebextension files, App Engine Flex uses vanilla Docker.
My only complaint is that Google isn't doing the greatest job updating their documentation to get Spring Boot working with the latest version of App Engine Flex. It took me awhile, but I finally got it working and thought I'd throw it up here for all to benefit.
Step one, sign up for GCP https://cloud.google.com. Second, install the gcloud sdk. On Mac with Homebrew this is as simple as:
brew cask install google-cloud-sdk
For other setups you can find the details at the following link https://cloud.google.com/sdk/gcloud/. After this is installed, we can move onto building the Spring Boot app.
We're starting from scratch, so why not start from the newest stable version of Spring Boot with web.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Next throw in the plugins for Spring Boot and App Engine.
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.3.RELEASE</version>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.2.1</version>
</plugin>
</plugins>
You can find the rest of the POM file in the GitHub repo I made for this tutorial along with a generic SpringBootApplication file.
Below is the Docker file for my application. The important part to note is the name of the jar file generated by the App Engine plugin. Instead of the jar name generated by Spring Boot, the App Engine plugin renames the jar to target.jar.
FROM gcr.io/google_appengine/openjdk
VOLUME /tmp
ADD target.jar app.jar
CMD [ "java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
We need to tell App Engine we're using the flex environment, and in this tutorial I want to build a custom environment for my application. By specifying the runtime as custom App Engine will look for the Docker file. Also, by default, App Engine Flex launches with 2 instances, so I specified to only start with 1.
runtime: custom
env: flex
handlers:
- url: /.*
script: this field is required, but ignored
manual_scaling:
instances: 1
With just four files, our app is ready to go
Now that these files are in place, we should be able to startup the app. Let's make sure it runs locally first by running the following command.
mvn spring-boot:run
If that started up, then the app should be ready to deploy.
mvn appengine:deploy
If this is the first time you're running the command, then gcloud will probably prompt you a few times to setup various components, but after that the app should deploy successfully into GCP.
Turns out the App Engine Flex environment doesn't have a free tier, it's discounted, but not free. $20 isn't bad for a month of application infrastructure though. Hopefully Google updates their documentation to clarify they mean 28 hours of App Engine Standard is free instead of just saying "App Engine".