Running a build of Maven based project but it fails.
The reason is no such file or directory when it tries to find the jar.
Dockerfile:
FROM frolvlad/alpine-oraclejdk8:slim
FROM maven:3.5.2-jdk-8-slim
VOLUME /tmp
CMD ['mvn package']
ADD target/app-0.1.0-SNAPSHOT.jar app.jar <-- fails there
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
The log output:
...
Removing intermediate container 60da937dde8a
Step 4/8 : CMD ['mvn package']
---> Running in 8ba364ba9d98
---> 4a722569d1a7
Removing intermediate container 8ba364ba9d98
Step 5/8 : ADD target/app-0.1.0-SNAPSHOT.jar app.jar
ADD failed: stat /var/lib/docker/tmp/docker-builder1534563/target/app-0.1.0-SNAPSHOT.jar: no such file or directory
ERROR: Build failed: ADD failed: stat /var/lib/docker/tmp/docker-builder1534563/target/app-0.1.0-SNAPSHOT.jar: no such file or directory
ERROR: Build failed with exit code 2
Have played with the different settings but it still doesn't work despite the app name is matches to the built jar one.
How to fix the issue?
This question IMO has nothing to do with Spring Boot, and it's Docker related.
In general please share more information about how exactly you run docker build command, from which directory and where does your Dockerfile reside exactly. Without this information we can only speculate and provide generic answers:
To provide some points for consideration: Docker knows nothing about Maven structure of your project so you can just maintain the following layout:
<some_dir>
|____ Dockerfile
|____ app-0.1.0-SNAPSHOT.jar
Then you can run the docker build command from this directory and this should work. Then you can experiment with target directory and once you'll understand when it works and when it doesn't proceed with your current folders layout, the chances that with this practice you'll find out the answer very quickly.
Related
This is my source code https://github.com/donhuvy/springboot-docker . I follow guide at tutorial video https://www.youtube.com/watch?v=7BCtc9cAS6o . File Dockerfile
# syntax=docker/dockerfile:1
#Which "official Java image" ?
FROM openjdk:oraclelinux8
#working directory
WORKDIR /app
#copy from your Host(PC, laptop) to container
COPY .mvn/ .mvn
COPY mvnw pom.xml ./
#Run this inside the image
RUN ./mvnw dependency:go-offline
COPY src ./src
#run inside container
CMD [ "mvnw", "spring-boot:run" ]
Log
C:\Users\donhu>docker pull donhuvy/springboot-docker:v1.0.0
v1.0.0: Pulling from donhuvy/springboot-docker
e54b73e95ef3: Pull complete
e6e62647f09f: Pull complete
da8e06a8884e: Pull complete
d8cbf9b4e6de: Pull complete
9971eb650313: Pull complete
366b24bf882f: Pull complete
35b5c085babf: Pull complete
b51a76bbfa65: Pull complete
Digest: sha256:f637c16c3b2a930d048e95f89f2a7aa53754f349e08e0c5a86398c5481eb07f1
Status: Downloaded newer image for donhuvy/springboot-docker:v1.0.0
docker.io/donhuvy/springboot-docker:v1.0.0
C:\Users\donhu>docker run donhuvy/springboot-docker:v1.0.0
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "mvnw": executable file not found in $PATH: unknown.
C:\Users\donhu>
How to fix it?
add springboot-docker dir to your $PATH variable.
basically the shell is not able to find the mvnw command, it looks for all the locations in the $PATH var. since your mvnw binary is located in your project dir you need to add it.
if this was in a linux environment it would be done like this
export PATH=$PATH:./springboot-docker
for windows you can search online how this can be edited.
Change CMD [ "mvnw", "spring-boot:run" ] to CMD [ "./mvnw", "spring-boot:run" ]
When your docker want to execute command mvnw springboot:run, it needs to find file mvnw in environment $PATH, but find none.
Change mvnw to ./mvnw which will tell docker to execute the mvnw file in current work directory(where you have copied mvnw before).
it's a permission problem, common on linux docker compose.
In my case it worked when I REMOVED sudo.
i.e
docker-compose up instead of sudo docker-compose up
you can also try adding sudo chmod -R a+rwx to the working directory in Dockerfile
I have java 13 installed on my machine and I have a project where I mentioned java 11 in the Dockerfile, so what should happen here is that when I build the docker image it should be built on top of java 11.
but surprisingly I get this error when running the container com/example/Application has been compiled by a more recent version of the Java Runtime.
The Dockerfile:
FROM openjdk:11.0.2-jdk
# Unpack distribution tar
ADD /distributions/application.tar /
RUN mkdir /src
RUN mkdir /src/main
RUN mkdir /src/main/resources
RUN mkdir /src/main/resources/ssl
ADD ./main/resources/ssl/keystore.p12 /src/main/resources/ssl/keystore.p12
# create JAR with unversioned name
RUN cp /application/lib/application-*.jar /application/lib/application.jar
ENTRYPOINT java -jar /application/lib/application.jar
Does anyone have an explanation for this?
You can use something similar to this:
FROM eclipse-temurin:16.0.2_7-jdk-centos7 AS builder
VOLUME /tmp
COPY . .
WORKDIR /
RUN ./gradlew assemble
FROM eclipse-temurin:16.0.2_7-jdk-centos7
WORKDIR /
COPY --from=builder build/libs build/libs
RUN ls -lah
RUN jar -xvf build/libs/*.jar
COPY build/libs/BOOT-INF/lib app/lib
COPY build/libs/META-INF/ app/META-INF
COPY build/libs/BOOT-INF/classes app/
RUN rm -rf build/libs
ENTRYPOINT ["java", "-cp", "app:app/lib/*", "com.example.springtest.SpringTestApplication"]
which effectively is a multi stage docker file that builds the image internally at the docker container. This means that your choice of Java version for building is locked down and does not get affected by what you run on your local machine. However, as mentioned before there are a few caveats here:
Developing against a newer Java version and then attempting to target an older one can lead to compatibility issues.
Always re-building the project in order to produce a Docker image can affect performance negatively (image what would happen if you were to run this at a CI level).
Thus based on all the above, I would suggest to align your development environment with what you are targeting as a deployment. This is turn would allow you to build the application locally and then simply proceed into copying the necessary artifacts/assets into the created container.
I am getting this error when I am trying to copy the generated jar file from the target folder to /usr/share/ folder in the Docker image. I have scoured Docker forum sites and people are having the exact same issue but there are no clear answer that solves this problem.
Step 9/10 : COPY target/${JAR_FILE} /usr/share/${JAR_FILE}
ERROR: Service 'myservice' failed to build: COPY failed: stat /var/lib/docker/tmp/docker-builder558103764/target/myservice.jar: no such file or directory
Here's my Dockerfile:
----------------------- begin ---------
FROM adoptopenjdk/openjdk11:alpine
MAINTAINER XXX XXX <ramil.xxxxx#xxxx.ai>
# Add the service itself
ARG JAR_FILE="myservice-1.0.0.jar"
RUN apk add maven
WORKDIR /app
COPY . /app/
RUN mvn -f /app/pom.xml clean install -DskipTests
WORKDIR /app
COPY target/${JAR_FILE} /usr/share/${JAR_FILE}
ENTRYPOINT ["java", "-jar", "/usr/share/myservice-1.0.0.jar"]
------ end snip -------
Here's how I run this from the base folder where I have my Dockerfile on my Mac.
docker build -t service-image .
So I guess you are trying to move your src to image and run a mvn build and copy built file from target to share folder.
If so, every thing seems to be fine except this line
COPY target/${JAR_FILE} /usr/share/${JAR_FILE}
COPY takes in a src and destination. It only lets you copy in a local
file or directory from your host (the machine building the Docker
image) into the Docker image itself
I think your intention is to copy file inside your container's /target to /usr/share folder. try this
RUN cp target/${JAR_FILE} /usr/share/${JAR_FILE}
Regrading error which you see its because with COPY command Docker will try to get the file from docker default path in your HOST
i.e /var/lib/docker/tmp/docker-builder558103764/
where /target folder doesn't exist
I had similar issue because of my .dockerignore had following exclusion:
target
Possible solutions are:
do not ignore target
define ignore exception
!target/*.jar
What has also worked after scouring the Docker forums is using multi-stage build. The multi-stage build not only forces you to use the folders where you specify the WORKDIR in your build stage but also significantly reduces the size of your base images up to 5x-6x less than just using the one stage build like I have shown above. Below is what my solution to finding this jar in the folder I specified as my WORKDIR and use that jar file for my smaller base image. Single-stage build in my initial solution produces 560 MB image. This multi-stage Dockerfile below builds image that is only 108 MB.
FROM adoptopenjdk/openjdk11:alpine as compile
MAINTAINER XXXX <ramil.xxxx#xxxx.ai>
# Build the jar using maven
RUN apk add maven
WORKDIR /app
COPY . /app/
RUN mvn -f pom.xml clean package -DskipTests
FROM adoptopenjdk/openjdk11:alpine-jre
# Copy the packaged jar app file to a smaller JRE base image
COPY --from=compile "/app/target/service-1.0.0.jar" /usr/share/
ENTRYPOINT ["java", "-jar", "/usr/share/service-1.0.0.jar"]
It turns out that the Dockerfile I was using wanted to be executed in a folder different from where the Dockerfile was located.
So given a build_config_folder/Dockerfile...
So instead of
docker build --build-arg SOME_ARG=value build_config_folder
# or
cd build_config_folder
docker build --build-arg SOME_ARG=value .
It needed to be
docker build --build-arg SOME_ARG=value -f build_config_folder/Dockerfile .
This is because the final path positional argument determines where the COPY command will look for files and folders.
Hope that helps someone.
I tried to create a container using dockerfile, but I'm not successful.
For loading the application on the docker what files do I need? And what is the build command?
Docker is a relative new technology and it's quite hard to find suitable documentation for your problem, first of all you will need docker-compose.yaml and Dockerfile, wich are the configuration files. Next you need to access the folder where's your project, and run "docker-compose up --build", for building the project, then "docker-compose down" to stop and "docker-compose up" to start again.
Tanta.
So, basically you'd need the docker installed in your machine, and a Dockerfile in your project.
I would indicate this step-by-step for your first example of a docker container:
Enter a folder that you can start a new project
Execute these command (You will ned git (click here to download it) installed):
git clone -b v1 https://github.com/docker-training/node-bulletin-board
cd node-bulletin-board/bulletin-board-app
Create a Dockerfile in the current folder
Paste this following piece of code in your new Dockerfile:
FROM node:6.11.5
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . .
CMD [ "npm", "start" ]
Now you can build and run your all-new container:
docker image build -t bulletinboard:1.0 .
docker container run --publish 8000:8080 --detach --name bb bulletinboard:1.0
So, with these steps, I think you can start to understand how Docker works and how you can introduce this stack in your currently running application.
Please, also check docker-compose docs for reference, it will help you.
Thank you.
I want to start my fat JAR inside a Docker container
Docker file
FROM java:8-jre
COPY config.yml /opt/hello/
COPY build/libs/Dockerwizard.jar /opt/hello/
EXPOSE 80
WORKDIR /opt/hello
CMD ["java", "-Xms128m", "-Xmx1500m", "-Dfile.encoding=UTF-8", "-jar", "Dockerwizard.jar", "server", "config.yml"]
Everytime I run
docker build --tag=myapp .
and
docker run -p 18080:8080 -t -i myapp
I get the message
Error: Unable to access jarfile Dockerwizard.jar
How can I resolve this?
It says:
COPY build/libs/Dockerwizard.jar /opt/hello/
...WORKDIR /opt/chat
So you are putting the Jar into /opt/hello, but then you want to run it from /opt/chat.
Maybe you want to look into using consistent path information. Beyond that, when you are not using the -cp option of java, you always have the issue that your CLASSPATH might be incomplete. So try adding -cp . for example.
Try changing the WORKDIR in your Dockerfile
WORKDIR /opt/chat is incorrect
It should be /opt/hello
Update
you have updated the question and renamed /chat to /hello everywhere - so you have made a correction to your error/ mistake