Docker image does not rebuild after code change - java

I am playing around with a docker project that builds and starts with
docker run -p 8888:8888 -v /$(pwd)/example/proto:/proto <image-name>
Inside it is a gradle based java application, about which I would like to get to know somewhat more, so I started to modify its source, adding some logs etc.
I tried to rebuild and rerun the docker image the above way but the results of my modifications don't seem to visible, the logs aren't printed etc.
I removed the image with docker rmi, but after every rebuild it seems to be the same image is being created. docker images always shows it is created 3 weeks ago and the image id is always the same
Checking on the application level the build directory contains the newly compiled java classes, so apparently on that level my changes are in effect, but it seems docker still uses the old code
Any help would be appreciated
Updated: Dockerfile
FROM gradle:7.0.0-jdk11 as cache
RUN mkdir -p /home/gradle/cache_home
RUN mkdir -p /proto
RUN touch /proto/any.proto
ENV GRADLE_USER_HOME /home/gradle/cache_home
COPY build.gradle /home/gradle/java-code/
COPY gradle.properties /home/gradle/java-code/
WORKDIR /home/gradle/java-code
RUN gradle build -i --no-daemon || return 0
FROM gradle:7.0.0-jdk11 as runner
COPY --from=cache /home/gradle/cache_home /home/gradle/.gradle
COPY . /usr/src/java-code/
WORKDIR /usr/src/java-code
EXPOSE 8888
ENTRYPOINT ["gradle", "bootRun", "-i"]

A docker build will send your local changes to your local docker deamon to be built into an image.
cd projectWithDockerfile
docker build -f ./Dockerfile -t me/gradlethingy .
docker run -p 8888:8888 -v /$(pwd)/example/proto:/proto me/gradlethingy
Without the build I'm guessing you are pulling in their <image-name> from the net each time.

Related

gradle build image using a different version than the one mentioned in docker file

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.

Docker for an Angular-Java app : ports not exposed properly

I am trying to dockerize a full-stack Java(Springboot)-Angular app. The Angular app is embedded in the application and makes REST calls to the Java app as GET localhost:8080/getSomeInfo. My Dockerfile is as
FROM maven:3.6.3-openjdk-8 AS build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package
FROM openjdk:8-jdk-alpine
COPY --from=build /home/app/target/*.jar /usr/local/lib/app.jar
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} /usr/local/lib/app.jar
ENTRYPOINT ["java","-jar","/usr/local/lib/app.jar"]
FROM node:12.2.0
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY src/main/web/package.json /app/package.json
RUN npm install
RUN npm install -g #angular/cli#10.1.2
COPY src/main/web /app
CMD ng serve --host 0.0.0.0
I build it as
docker build -t springio/myapp .
I need to expose both the angular port and the java port, so I run it as
docker run -p 9898:4200 -p 8080:8080 -t springio/myapp
I am able to bring up the web page, but it cannot reach out to the Java server (can't connect to 8080). How can this be fixed please?
I have tried putting 'EXPOSE 8080' in the dockerfile, but that did not work
You should not put 2 applications in the same container. Although you can, it is considered a bad practise and it defeats the purpose of using containers.
I suggest having 2 Dockerfile: one for the back-end (java app) and one for the front-end (Angular app). Build each of them separately and start them independently.
For your specific problem I don't think the port is the problem, but is the Java app that is not even starting (it is actually not even present in the final image). Splitting the Dockerfile and starting the apps separately will fix your issue.
EXPOSE doesn't actually do anything. It is there to inform users of the Dockerfile which ports the application is listening on, so that they know which ports to map on the host.

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"]

Docker files and build command

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.

Simple Docker container dies immediatelly after docker run command

I have a Dockerfile which looks like this:
FROM alpine:3.9
RUN apk add --update openjdk8
RUN mkdir /var/generator/
COPY generator.jar /var/generator
EXPOSE 8080
ENTRYPOINT [ "/bin/sh" ]
Dockerfile is inside generator/ folder. I am building it using:
docker build -t generator generator/
It builds successfully:
Successfully built 878e81f622cc
Successfully tagged generator:latest
but when I am trying to run this image with
docker run -d -p 8080:8080 generator
it dies immediately. docker logs gives no output.
What is wrong with my Dockerfile? Why is the container dying?
Try to run the JAR. Currently, it just runs sh command and exits. Make it something as below to run the JAR in foreground -
FROM alpine:3.9
RUN apk add --update openjdk8
RUN mkdir /var/generator/
COPY generator.jar /var/generator
EXPOSE 8080
ENTRYPOINT ["java","-jar","/var/generator/generator.jar"]
Beside your entrypoint is wrong (sh exits immediately) I would also recommend to start with an appropriate base image instead of starting with alpine and installing the openjdk package. Since you want to run a java application just use the JRE and not a full JDK and start the application as a foreground process.
Here's a minimal version which is also more efficient in disksize as the image will be smaller.
FROM openjdk:8-jre-alpine
COPY generator.jar /opt/generator.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/opt/generator.jar"]

Categories