Google Cloud Platform pipeline/container builder i

2019-06-04 09:58发布

问题:

Created basic HelloWorld microservice using Spring Boot (2.1.3), Java 8, Maven.

pom.xml has maven plugin entry like below

<plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                    <mainClass>com.example.HelloWorldApplication</mainClass>
            </configuration>
        </plugin>

Dockerfile looks like below

FROM openjdk:8
VOLUME /tmp
ADD target/helloworld.jar helloworld.jar
EXPOSE 8081
ENTRYPOINT ["java","-jar","helloworld.jar"]

Created image on local machine using command

docker build . -t helloworld:v1

Verified by creating container out of it. Checked in code to docker-hub account and github account.

Logged into Google cloud platform (GCP), created kubernetes cluster, created pipeline(using container builder) by configuring github url where helloworld microservice code resides. There are two options to run build (use Dockerfile or cloudbuild.yaml). I am using Dockerfile to run build.

When build is picked up to run, it fails for this line in Dockerfile

ADD target/helloworld.jar helloworld.jar

Error seen in GCP logs:

ADD failed: stat /var/lib/docker/tmp/docker-builderxxxxxx/target/helloworld.jar: no such file or directory

I tried to replace it with COPY command and still the issue is same.

Note: I tried to go with cloudbuild.yaml Here is how my cloudbuild.yaml looks:

  steps:
  # Build the helloworld container image.
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - 'build'
      - '-t'
      - 'gcr.io/${PROJECT_ID}/helloworld:${TAG_NAME}'
      - '.'

This didn't make any difference. Issue remains the same.

Any idea if Springboot Java application has some specific configuration for Dockerfile to be built fine in Google Cloud Platform?


UPDATE - 1

Based on comments tried below steps on local machine:

  1. ran command mvn clean . That cleaned target folder

  2. updated Dockerfile

FROM maven:3.5-jdk-8 AS build
COPY src .
COPY pom.xml .
RUN mvn -f pom.xml clean package

FROM openjdk:8
VOLUME /tmp
COPY --from=build target/helloworld.jar helloworld.jar
EXPOSE 8081
ENTRYPOINT ["java","-jar","helloworld.jar"]

  1. Ran docker build . -t helloworld:v1 command and that created image.

  2. Then run command to start container: docker run -p 8081:8081 -n helloworld-app -d helloworld:v1

container starts and exits with error in log:

Exception in thread "main" java.lang.ClassNotFoundException: com.example.HelloWorldApplication at java.net.URLClassLoader.findClass(URLClassLoader.java:382)

回答1:

Looks like a problem with file paths.

Try the following updated Dockerfile, which explicitly sets the working directory. It also uses explicit file paths when copying the jar between images.

FROM maven:3.5-jdk-8-slim AS build
WORKDIR /home/app
COPY src     /home/app/src
COPY pom.xml /home/app
RUN mvn clean package

FROM openjdk:8-jre-slim
COPY --from=build /home/app/target/helloworld-0.0.1-SNAPSHOT.jar /usr/local/lib/helloworld.jar
EXPOSE 8081
ENTRYPOINT ["java","-jar","/usr/local/lib/helloworld.jar"]

Additional Notes:

  • See the related answer for a full example building a spring boot app
  • I've based the second stage on a JRE image. Reduces the size of the output image.