How to start a fat jar in docker? - java

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

Related

unable to start container process: exec: "mvnw": executable file not found in $PATH: unknown

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

How to prepare docker image/ container/ dockerfile with jar file

I'm new to Docker. I have a problem: I have a jar file that processes "in.png" and saves the result as a separate file: out.png. I'd like to create a docker image and put a .jar file in it. It is important that the in.png and out.png files appear / are delivered on the host side. I want to put everything on dockerhub, and ultimately allow the user to process their own graphic files. What is the best solution to this problem? I have tryed something like this (is it good solution?):
FROM java:8
WORKDIR /
ADD Hello.jar in.png
EXPOSE 8080
CMD java - jar Hello.jar
But i can't coppy (or i don't know how) output file from container to host;
Or maybe a better solution is make an image (Java / Ubuntu with Java?), uploading a .jar file to it and providing the user with a set of commands, e.g .:
docker cp Hello.jar 4e673836297e:/
docker cp in.png 4e673836297e:/
docker run ubuntu java -jar Hello.jar
docker cp 4e673836297e:/ .
Please tell me what the best solution is for this problem
You should mount a directory to your docker container using bind mounts.
If your jar writes the output to /output/out.png you can start a container based on your image with the following command.
docker run -v "$(pwd)":/output YOUR_IMAGE_NAME
That option mounts the current working directory to the /outpout folder inside the container. So the files written there will be visible on the outside.
A more detailed explanation can be found here: https://docs.docker.com/storage/bind-mounts/
Edit to answer the additional question:
You can also use the mounted folder for the input, so you can have different image files as input.
First the simple aproach.
Instead of naming the folder output, you could name it workdir and mount the current directory to it.
docker run -v "$(pwd)":/workdir YOUR_IMAGE_NAME
When you have to change your java application to read the in.png from /workdir/in.png. The user has to save his individual input file as in.png in the current folder and can then run the Docker image.
A more advanced and more comfortable aproach is the following.
You change the Dockerfile so it contains an entrypoint and a command.
FROM java:8
WORKDIR /
ADD Hello.jar in.png
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "Hello.jar"]
CMD ["in.png"]
When this docker image is executed, it starts java -jar Hello.jar but with the parameters from the CMD added. The CMD can be overwritten when the image is executed:
docker run -v "$(pwd)":/workdir YOUR_IMAGE_NAME custom.png
You have to change your programm, so that it accepts the first command line parameter as the name of the input file inside the workdir.
Then the user can tell your progamm the name of his or her image file.

Unable to access jarfile from docker run command for java maven project

Build docker images using docker file for maven project
When try running docker run getting error saying Unable to access jarfile.
Can some one assist on whats wrong with .
FROM openjdk:8-jre-alpine as release
RUN addgroup -g 1001 -S user1 && user1 -u 1001 -S user1 -G user1
WORKDIR /home/app
COPY --from=builder /home/app/service-1.0.0.jar .
RUN chown -R user1:user1 /home/app
USER user1
ENTRYPOINT ["java", "-jar" ,"/home/app/service-1.0.0.jar"]
but when i go for docker run with local config files as build mount
docker run -it --mount type=bind,source=D:/Java/service/docker/config,target=/home/app services
Unable to access jarfile /home/app/service-1.0.0.jar
Can someone assist on this or is something wrong i did??
I am not sure if you are looking for multistage docker build. If not, you need not use "COPY --from=builder" as it tires to copy the build artifact from your previous stage to this new stage. If it is a single stage docker build, you might just use the copy as follows -
COPY /home/app/service-1.0.0.jar .
Able to resolve the same, Issue was due to mound of config files not happened properly.
instead of docker run -it --mount type=bind,source=D:/Java/service/docker/config,target=/home/app services changes it to docker run -it --mount type=bind,source=D:/Java/service/docker/config/app.config,target=/home/app services which made service to load and work

COPY or ADD Command in Dockerfile Fails to Find Jar File for Springboot Application

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.

gu No such file or directory

I'm building a docker image out of a micronaut application.
But whenever I run the docker build command
docker build -f Dockerfile -t micronaut .
I get this error
/bin/sh: /bin/gu: No such file or directory
Here's the content of my docker file anyway:
FROM oracle/graalvm-ce:20.0.0-java11 as graalvm
RUN $GRAALVM_HOME/bin/gu install native-image
COPY . /home/app/micronautguide
WORKDIR /home/app/micronautguide
RUN $GRAALVM_HOME/bin/native-image --no-server -cp build/libs/complete-*-all.jar
FROM frolvlad/alpine-glibc
RUN apk update && apk add libstdc++
EXPOSE 8080
COPY --from=graalvm /home/app/micronautguide/micronautguide /micronautguide/micronautguide
ENTRYPOINT ["/micronautguide/micronautguide", "-Xmx68m"]
Though by running gu command from the terminal works.
Your context does not contain RUN $GRAALVM_HOME/bin/gu . What is $GRAAL_VM_HOME? Whatever this variable is, it is set as null. Also, $GRAALVM_HOME/bin/gu needs to be part of docker image.
$GRAALVM_HOME does not exists in the oracle/graalvm-ce:20.0.0-java11 container. Thus, make suer to specify the right path. In this case it is /bin/gu
I think $GRAALVM_HOME is a variable you use in the local machine and gu tool is already installed and available at /bin in the docker image. So I have kept the $GRAALVM_HOME unchanged in the second build stage.
So, the Dockerfile should be like below,
FROM oracle/graalvm-ce:20.0.0-java11 as graalvm
RUN /bin/gu install native-image
COPY . /home/app/micronautguide
WORKDIR /home/app/micronautguide
RUN /bin/native-image --no-server -cp build/libs/complete-*-all.jar
FROM frolvlad/alpine-glibc
RUN apk update && apk add libstdc++
EXPOSE 8080
COPY --from=graalvm /home/app/micronautguide/micronautguide /micronautguide/micronautguide
ENTRYPOINT ["/micronautguide/micronautguide", "-Xmx68m"]

Categories