Error response from daemon: ADD failed: no source files were specified - java

Dockerfile:
FROM openjdk:11-jre-slim
ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
JHIPSTER_SLEEP=0 \
JAVA_OPTS=""
# Add a jhipster user to run our application so that it doesn't need to run as root
RUN adduser --disabled-login --shell /bin/sh --gecos "" jhipster
WORKDIR /home/jhipster
ADD entrypoint.sh entrypoint.sh
RUN chmod 755 entrypoint.sh && chown jhipster:jhipster entrypoint.sh
USER jhipster
ADD *.jar contourservice.jar
ENTRYPOINT ["./entrypoint.sh"]
EXPOSE 8084
entrypoint.sh:
#!/bin/sh
echo "The application will start in ${JHIPSTER_SLEEP}s..." && sleep "${JHIPSTER_SLEEP}"
exec java "${JAVA_OPTS}" -Djava.security.egd=file:/dev/./urandom -jar "${HOME}/contourservice.jar" "$#"
console:
Step 8/10 : ADD *.jar contourservice.jar
Error response from daemon: ADD failed: no source files were specified
I try to exec command docker build src/main/docker/
but in step 8, when docker try to ADD *.jar it failed.
It is my hierarchy:

Related

Docker Build can't find GradleWrapperMain on GitLab but works on my laptop

Docker build works on my laptop but on GitLab I get
Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain
Tried a lot of different setups but nothing works...fails at gradlew build...Any ideas are welcome
My .gitlab-ci.yaml
....variables here
publish:
image:
name: amazon/aws-cli
entrypoint: [""]
services:
- docker:dind
before_script:
- amazon-linux-extras install docker
- aws --version
- docker --version
- export GRADLE_USER_HOME=`pwd`/gradle
- export CLASSPATH=`pwd`/gradle/wrapper
cache:
paths:
- gradle/wrapper
- .gradle/wrapper
- .gradle/caches
script:
- docker build -t $DOCKER_REGISTRY/$APP_NAME:$CI_PIPELINE_IID .
My Dockerfile
FROM openjdk:11
ENV wdir=code
ENV MY_SERVICE_PORT=8080
WORKDIR /$wdir
COPY . /code
RUN echo "Running build"
RUN ["/code/gradlew", "build"]
EXPOSE $MY_SERVICE_PORT
# Run the service
CMD ["java", "-jar", "build/libs/code-1.0-SNAPSHOT.jar"]
Created a workaround by installing gradle...works now:
FROM openjdk:11
ENV wdir=code
ENV MY_SERVICE_PORT=8080
WORKDIR /code
# Install Gradle
RUN wget -q https://services.gradle.org/distributions/gradle-6.5-bin.zip \
&& unzip gradle-6.5-bin.zip -d /opt \
&& rm gradle-6.5-bin.zip
ENV GRADLE_HOME /opt/gradle-6.5
ENV PATH $PATH:/opt/gradle-6.5/bin
# Prepare by downloading dependencies
ADD build.gradle /code/build.gradle
ADD src /code/src
RUN echo "Running build"
RUN cd /code
RUN gradle --no-daemon build
EXPOSE $MY_SERVICE_PORT
# Run the service
CMD ["java", "-jar", "build/libs/code-1.0-SNAPSHOT.jar"]

Gradle and Docker: How to run a Gradle build within Docker container?

I have the following docker file that runs a spring boot application:
# For Java 11, try this
FROM adoptopenjdk/openjdk11:alpine-jre
#
ARG JAR_FILE=/build/libs/pokerstats-0.0.1-SNAPSHOT.jar
#
WORKDIR /opt/app
#
COPY ${JAR_FILE} app.jar
#
ENTRYPOINT ["java","-jar","app.jar"]
The issue is that currently I have to run gradle clean build on my host machine first to create the jar file on my local machine at path:
/build/libs/pokerstats-0.0.1-SNAPSHOT.jar
How can I put this gradle clean build into my docker file so that the build step is done inside the container?
edit:
I want the steps for a user to be:
Clone my project from github
run docker build -t pokerstats . - which will do the gradle build
run docker container run -d -p 8080:8080 pokerstats
The user will clone my project from github - I then want them to be able to run the docker container without having to build the project with gradle first - I.e. I want the docker file to do the build and copy the jar into the container.
After reading this article I have been able to solve this using a Multi Stage Docker Build. Please see the Docker file below:
# using multistage docker build
# ref: https://docs.docker.com/develop/develop-images/multistage-build/
# temp container to build using gradle
FROM gradle:5.3.0-jdk-alpine AS TEMP_BUILD_IMAGE
ENV APP_HOME=/usr/app/
WORKDIR $APP_HOME
COPY build.gradle settings.gradle $APP_HOME
COPY gradle $APP_HOME/gradle
COPY --chown=gradle:gradle . /home/gradle/src
USER root
RUN chown -R gradle /home/gradle/src
RUN gradle build || return 0
COPY . .
RUN gradle clean build
# actual container
FROM adoptopenjdk/openjdk11:alpine-jre
ENV ARTIFACT_NAME=pokerstats-0.0.1-SNAPSHOT.jar
ENV APP_HOME=/usr/app/
WORKDIR $APP_HOME
COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME .
EXPOSE 8080
ENTRYPOINT exec java -jar ${ARTIFACT_NAME}
Build stage
FROM gradle:jdk11-alpine AS BUILD_STAGE
COPY --chown=gradle:gradle . /home/gradle
RUN gradle build || return 1
Package stage
FROM openjdk:11.0.11-jre
ENV ARTIFACT_NAME=app.jar
ENV APP_HOME=/app
COPY --from=BUILD_STAGE /home/gradle/build/libs/$ARTIFACT_NAME $APP_HOME/
WORKDIR $APP_HOME
RUN groupadd -r -g 1000 user && useradd -r -g user -u 1000 user
RUN chown -R user:user /app
USER user
ENTRYPOINT exec java -jar ${ARTIFACT_NAME}
Mutli stage build. Be sure to have build.gradle and settings.gradle files included in your project directory, I tried to make it as clean and concise as possible:
#Build stage
FROM gradle:latest AS BUILD
WORKDIR /usr/app/
COPY . .
RUN gradle build
# Package stage
FROM openjdk:11-jre-slim
ENV JAR_NAME=app.jar
ENV APP_HOME=/usr/app/
WORKDIR $APP_HOME
COPY --from=BUILD $APP_HOME .
EXPOSE 8080
ENTRYPOINT exec java -jar $APP_HOME/build/libs/$JAR_NAME
Make sure to change JAR_NAME variable to your generated jar file name.

Dockerfile Spring Boot property from variable not working

I can't seem to get Spring boot properties to work via variable in my Dockerfile. This is what I am doing:
ENTRYPOINT exec java -Dapp-version=$app_version -jar /app.jar
If I do RUN echo "App Version: $app_version" inside of my Dockerfile then I get then I get the correct output like App Version: 1.70.0.
If I manually put the version like this: ENTRYPOINT exec java -Dapp-version=1.70.0 -jar /app.jar then the value is injected correctly.
In fact, if I do RUN echo "ENTRYPOINT exec java -Dapp-version=$app_version -jar /app.jar" then I get output like
Step 9/10 : RUN echo "ENTRYPOINT exec java -D******ion=$app_version -jar /app.jar"
---> Running in b6c3cd9bb69a
ENTRYPOINT exec java -D******ion=1.70.0 -jar /app.jar
The value inside of Spring is being set as an empty string when I use the Dockerfile variable. When I hard code it to 1.70.0 then it is being set correctly. What am I missing?
I have tried many different things including using {}, quotes, etc.
Edit: Added Dockerfile
FROM java:8
ARG app_version
RUN echo -------------------
RUN echo "App Version: $app_version"
RUN echo -------------------
VOLUME /tmp
COPY ./build/libs/mango-sticky-rice-1.0.0-SNAPSHOT.jar /app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT exec java -Dapp-version=$app_version -jar /app.jar
This answer worked: https://stackoverflow.com/a/49889134/3088642. This is what my Dockerfile looks like:
FROM java:8
ARG app_version
RUN echo -------------------
RUN echo "App Version: ${app_version}"
RUN echo -------------------
VOLUME /tmp
COPY ./build/libs/mango-sticky-rice-1.0.0-SNAPSHOT.jar /app.jar
RUN bash -c 'touch /app.jar'
RUN echo "#!/bin/bash \n java -Dapp-version=${app_version} -jar /app.jar" > ./entrypoint.sh
RUN chmod +x ./entrypoint.sh
RUN cat ./entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]

Docker file COPY then WORKDIR, but the file is in different directory

I have two docker images: imageA and imageB.
ImageA Dockerfile
FROM openjdk:11-jre-slim
COPY ./target/java-app.jar /java-application/
ImageB Dockerfile
FROM imageA
# Install Python.
RUN \
apt-get update && \
apt-get install -y python python-dev python-pip python-virtualenv && \
rm -rf /var/lib/apt/lists/*
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt
ENTRYPOINT ./startPythonServiceAndJavaApp.sh
startPythonServiceAndJavaApp.sh - is the scrip to start both java app and python app.
java -XX:+UseContainerSupport $JAVA_OPTIONS -jar ./java-application/java-app.jar & python app.py;
Then I build imageA - docker build -t imageA .. It builds successfully.
Then I build imageB and start the container. The python app starts successfully, but I get error
Error: Unable to access jarfile ./java-application/java-app.jar
When I ssh to the running container (note, it is running), I go into app directory. I ran ls and I saw these files:
C:\Users\user>docker exec -it 12345 bash
root#12345:/app# ls
Dockerfile app.py deploy.sh requirements.txt java-app.jar startPythonServiceAndJavaApp.sh
My question, why did java-app.jar end up in the app directory? In the Dockerfile of the imageA I told it to be in java-application directory:
COPY ./target/java-app.jar /java-application/
My question can be rephrased COPY and WORKDIR together. As a quick solution, I put the jar file into root of the docker context. Then I started both application from that context.
Here are the changes:
ImageA Dockerfile - just copy to the root of container.
COPY ./target/java-app.jar /
startPythonServiceAndJavaApp.sh
java -XX:+UseContainerSupport $JAVA_OPTIONS -jar ./java-app.jar & python app.py;
Both applications are running now in the single container. Hope this will help others. Please, correct me if I am wrong or share your ideas.

Redeploy spring-boot application in docker container?

I have a spring-boot project and I want automatically redeploy my jar in the container.
How to do it correctly?
So far, all I see is this way. It's the right way?
# cd /home/jdev;
# sudo docker stop ca_spring_boot;
# sudo docker rm ca_spring_boot;
# sudo docker rmi ca_app_image;
# sudo docker build -t ca_app_image .;
# sudo docker run -d -p 8888:8080 --name ca_spring_boot ca_app_image
And my Dockerfile
FROM java:8
VOLUME /tmp
EXPOSE 8080
ADD docker-storage/jenkins/workspace/CA/build/libs/ca-1.0.jar app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=container","-jar","/app.jar"]
Thanks.
You could mount a volume and put your app.jar in there. So you do not need to rebuild the image, you just restart the container.
Dockerfile
FROM java:8
ENTRYPOINT [ "sh", "-c", "java -jar /mnt/app.jar" ]
Put your app.jar in /docker/spring/
Build and run:
docker build -t spring_test .
docker run -d -v /docker/spring/:/mnt -p 12384:8080 --name spring_test_running spring_test
If you update your spring application you just do:
docker restart spring_test_running
The previous answer is good. But there is need to restart container every time when you want to test your code. But we can avoid this problem. Just use Spring dev tool
And mount destination directory as described above.

Categories