I want to run a gradle build inside a container, then execute the jar with its config file and server parameters. This is what I have
WORKDIR /app
COPY . /app
RUN chmod +x gradlew \
&& gradle build
COPY config/*.yml build/libs
RUN cd build/libs \
&& ls -la
EXPOSE 8081
ENTRYPOINT ["java", "-jar", "/app/build/libs/app.jar", "-Dconfig.location=app/build/libs/config.yml", "-Dgrails.env=prod"]
I can see that both the yml file and the jar file are in the build libs folder, but when I build the dockerfile, I get error indicating missing yml file. When I reorder them and place config location before the jar file, it finds the config, but doesn't execute the jar file. When I purposely put an incorrect path to jar file, I get an error that jar is not found.
What I get after docker run is
Configuring Spring Security Core ...
... finished configuring Spring Security Core Configuring Spring Security REST 2.0.0.RC1...
... finished configuring Spring Security REST
And that's it. Although running locally I get "application running.." aswell.
Any help appreciated!
I cannot post a comment as I am a newbie.
I see that you are in build/libs when you run-
RUN cd build/libs
Then your ENTRYPOINT command is using relative path for config location-
"-Dconfig.location=app/build/libs/config.yml"
You can try starting the location with "/app" instead of "app".
Also, if that doesn't help, can you paste the exact errors you are getting in the 2 scenarios you mentioned?
Related
In my Spring Boot app, I read some csv file located in resources\data folder and I have the following Dockerfile:
FROM maven:3.8.2-openjdk-17-slim AS builder
# add pom.xml and source code
ADD ./pom.xml pom.xml
ADD ./src src/
# package jar
RUN mvn clean install
# Second stage: minimal runtime environment
FROM openjdk:17-alpine
# copy jar from the first stage
ARG JAR_FILE=target/*.jar
COPY --from=builder ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
When I run the app after building the container, I get the following error:
"class path resource [data/employees.csv] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app.jar!/BOOT-INF/classes!/data/employees.csv"
I think I need to add the resources\data folder to my container. So, how can I do this? What is the most proper way?
Note: I also tried to fix the problem using new ClassPathResource(filename).getInputStream(), but it did not make any sense and still the same problem.
I am trying to run my DockerFile and Gradle build inside . I have tried all the ways to do it , but can't understand.
Here is my dockerFile it is working properly, but DO NOT making the gradle BUILD , can someone help me With it:
FROM gradle:4.7.0-jdk8-alpine AS build
COPY . /temp
RUN gradle build --no-daemon
FROM java:8-jdk AS TEMP_BUILD_IMAGE
COPY . /tmp
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
The output is
'<unknown> Dockerfile: DockerFile' has been deployed successfully.
But it is not building me the Gradle. P.S i am new to DOCKER , and maybe i am doing the wrong stuff in my docker FIle
You have a multistage build here that you need to understand.
FROM gradle:4.7.0-jdk8-alpine AS build
COPY . /temp
RUN gradle build --no-daemon
This will create a docker container, copy the complete docker build context into the container and run gradle. You did not show the complete console output so I can only guess that this ran successfully. Also you did not show your build.gradle file so noone can tell you where to search for the compile result.
FROM java:8-jdk AS TEMP_BUILD_IMAGE
COPY . /tmp
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
With these lines you create the next stage's docker container, and again you copy your project into the container. But nowhere I see that you would transport the build output from the first stage into the second stage. As this is missing, the resulting container of course does not contain the build result, and you believe it did not happen.
You need to add a line such as
COPY --from=build /whateverPointsToYourBuildOutput /whereverYouWantItInTheContainer
See https://docs.docker.com/engine/reference/builder/#copy
I reference an HTML file in my code, and access it with:
Path filePath1 = Path.of("./email.html");
When I run the project locally, the project works fine, and the file loads normally. However, when running the project in a Docker container, I get the following error:
java.nio.file.NoSuchFileException: ./email.html
Here is my Docker file for reference
FROM openjdk:11.0-jdk-slim as builder
VOLUME /tmp
COPY . .
RUN apt-get update && apt-get install -y dos2unix
RUN dos2unix gradlew
RUN ./gradlew build
# Phase 2 - Build container with runtime only to use .jar file within
FROM openjdk:11.0-jre-slim
WORKDIR /app
# Copy .jar file (aka, builder)
COPY --from=builder build/libs/*.jar app.jar
ENTRYPOINT ["java", "-Xmx300m", "-Xss512k", "-jar", "app.jar"]
EXPOSE 8080
Thank you for the answers. So this is a Java project, so there is no index.html to add. I tried changing the work directory to /src, but it is still not picking it up
Docker has no access to the filesystem fromm the host OS.
You need to put it in there as well:
COPY ./index.html index.html
There's a couple of options:
Copy the index.html in the docker image (solution by ~dominik-lovetinsky)
Mount the directory with your index.html file as a volume in your docker instance.
Include the index.html as a resource in your app.jar, and access it as a classpath resource.
The last option: including resources as classpath resource, is the normal way webapps work, but I'm not sure if it works for you.
So I am trying to run a spring boot app with maven wrapper inside the docker container. Here is my Docker file:
### Stage 1: Build the application
FROM openjdk:8-jdk-alpine as build
RUN mkdir -p /app
#Set the current working directory inside the image
WORKDIR /app
#copy maven executable to the image
COPY mvnw .
COPY .mvn .mvn
#Copy the pom.xml file
COPY pom.xml .
#Build all the dependencies in preparation to go offline
#This is a separate step so the dependencies will be cached unless
#the pom.xml file has changed
RUN ./mvnw dependency:go-offline -B
#Copy the project source
COPY src src
#Package the application
RUN ./mvnw package -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
I have this error:
Step 7/16 : RUN ./mvnw dependency:go-offline -B
---> Running in 642a32f86392
/bin/sh: ./mvnw: not found
ERROR: Service 'app-server' failed to build: The command '/bin/sh -c ./mvnw dependency:go-offline -B' returned a non-zero code: 127
I am working with windows 10 pro. Please I need your help
Maybe a duplicate of Unable to run './mvnw clean install' when building docker image based on "openjdk:8-jdk-alpine" for Spring Boot app
Can you check the line endings of the mvnw shell script?
You could fix it by adding this before executing the mvnw command:
RUN dos2unix mvnw
Alternatively, if the file is in git, you can also fix it by adding the following to a .gitattributes file and checking the file out again:
*.bat text eol=crlf
mvnw text eol=lf
You have to copy the project files into the /app dir first. And you don't have the maven wrapper in the context folder where you run the docker build.
Try change the end of line mvnw file from Windows style CRLF to Unix style LF. Then rebuild the image.
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:
ran command mvn clean . That cleaned target folder
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"]
Ran docker build . -t helloworld:v1 command and that created image.
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)
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.