simon
simon

Reputation: 559

How to deploy a spring boot project to Google App Engine using Google Cloud Build?

I am building my spring boot application using maven and google cloud build but somehow I get different deployment results whether I run locally using mvn appengine:run or that I deploy using Cloud Build.

If I run locally using mvn appengine:run, I can access my controller as expected. Using Cloud Build, I get a 404 error.

My cloudbuild.yaml is the following:

steps:
- name: 'gcr.io/cloud-builders/mvn'
  args: ['package']
- name: 'gcr.io/cloud-builders/gcloud'
  args: ['app', 'deploy', 'target/myapp/WEB-INF/appengine-web.xml']

How would you recommend configuring a cloud build in order to build and deploy a spring boot application on google app engine?


After additionnal digging, the issue seems to be related to some kind of error returned:

javax.servlet.ServletContext log: 2 Spring WebApplicationInitializers detected on classpath

I do not get this message in the stack trace when deploying from local machine using mvn appengine:deploy

My question still remains, how do I go about creating a cloudbuild.yaml that can invoke mvn appengine:deploy ?

Upvotes: 3

Views: 1621

Answers (1)

simon
simon

Reputation: 559

In order to build a spring boot project and deploy it to google appengine using Google Cloud Build. I ended up having to first build a "builder" image using the image below and reference this image when performing my actual application builds.

Dockerfile

FROM debian:stretch
#
# Google Cloud SDK installation
# https://cloud.google.com/sdk/docs/quickstart-debian-ubuntu
RUN apt-get update -y && \
  apt-get install \
    apt-utils \
    dialog \
    gnupg \
    lsb-release \
    curl -y && \ 
  export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)" && \
  echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && \
  curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \
  apt-get update -y && \
  apt-get install google-cloud-sdk -y
# Install all available components
RUN apt-get install google-cloud-sdk \
  google-cloud-sdk \
  google-cloud-sdk-app-engine-go \
  google-cloud-sdk-app-engine-java \
  google-cloud-sdk-app-engine-python \
  google-cloud-sdk-app-engine-python-extras \
  google-cloud-sdk-bigtable-emulator \
  google-cloud-sdk-cbt \
  google-cloud-sdk-datastore-emulator \
  google-cloud-sdk-cloud-build-local \
  google-cloud-sdk-datalab \
  kubectl \
  google-cloud-sdk-pubsub-emulator -y
#
# OpenJDK installation
# https://linuxhint.com/install-openjdk-8-on-debian-9-stretch/
RUN apt-get install openjdk-8-jdk -y

#
# MAVEN installation
# https://github.com/carlossg/docker-maven/blob/f581ea002e5d067deb6213c00a4d217297cad469/jdk-8/Dockerfile
ARG MAVEN_VERSION=3.5.4
ARG USER_HOME_DIR="/root"
ARG SHA=ce50b1c91364cb77efe3776f756a6d92b76d9038b0a0782f7d53acf1e997a14d
ARG BASE_URL=https://apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binaries

RUN mkdir -p /usr/share/maven /usr/share/maven/ref \
  && curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
  && echo "${SHA}  /tmp/apache-maven.tar.gz" | sha256sum -c - \
  && tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 \
  && rm -f /tmp/apache-maven.tar.gz \
  && ln -s /usr/share/maven/bin/mvn /usr/bin/mvn

ENV MAVEN_HOME /usr/share/maven
ENV MAVEN_CONFIG "$USER_HOME_DIR/.m2"

WORKDIR /workspace

cloudbuild.yaml

# In this directory, run the following command to build this builder.
# $ gcloud builds submit . --config=cloudbuild.yaml

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '--tag=gcr.io/$PROJECT_ID/gcloud-maven', '.']
# Simple sanity check: invoke java to confirm that it was installed correctly.
- name: 'gcr.io/$PROJECT_ID/gcloud-maven'
  args: ['java', '-version']
# Simple sanity check: invoke gcloud to confirm that it was installed correctly.
- name: 'gcr.io/$PROJECT_ID/gcloud-maven'
  args: ['gcloud', 'projects', 'list']
# Simple sanity check: invoke maven to confirm that it was installed correctly.
- name: 'gcr.io/$PROJECT_ID/gcloud-maven'
  args: ['mvn', '--version']

images: ['gcr.io/$PROJECT_ID/gcloud-maven']

timeout: 1200s

My spring boot project's cloudbuild.yaml now references this image:

steps:
- name: 'gcr.io/$PROJECT_ID/gcloud-maven'
  args: ['mvn', 'appengine:deploy']

I will try to put this docker image on dockerhub and github for others to find. I will also appreciate people more familiar with docker and linux to help improve this image to reduce its size. (For example, use Alpine instead of Debian or Debian Stretch Slim). In the meantime, I hope this helps others like me.

Upvotes: 4

Related Questions