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"]
Related
I want to execute a java jar with the help of shell script in docker container. My java program simply accepts command line argument and print the message along with the malue passed as command line argument.
class SampleJar {
public static void main(String [] args) {
String msg = args[0];
System.out.println("Hello " + msg);
}
}
I build the jar and jar is working fine.
java -jar SampleJar.jar John
o/p: Hello John.
Inside my working directory there is Dockerfile and scripts folder.
Script folder having 3 files:
executeJar.sh
execute.sh
SampleJar.jar
My Dockerfile content:
FROM ubuntu
WORKDIR /opt
#COPY execute.sh .
#COPY executejar.sh .
#COPY SampleJar.jar .
COPY scripts /
ENTRYPOINT ["/execute.sh"]
CMD ["alpha"]
executeJar.sh content:
#!/bin/bash
echo "This is from execute jar . sh"
java -cp SampleJar.jar SampleJar John
execute.sh content:
#!/bin/bash
echo "This is from execute.sh"
case "$1" in
alpha)
echo "executing alpha script"
/executejar.sh "#"
;;
esac
The jar file is working fine tested independently.
I build the image using command:
docker build -t exp .
exp is the name of the image & . indicates the Dockerfile present in current directory
I create container
docker run -it --name exp-container exp:latest alpha
-it for interactive mode
exp-container is the name of the container
So execute.sh will be executed and case alpha will be executed and executeJar.sh will invoke.
Now executejar.sh should execute the java jar.
So the final output comes as
docker run -it --name exp-container2 exp:latest alpha
This is from execute.sh
executing alpha script
This is from execute jar . sh
/executejar.sh: line 3: java: command not found
How can I get the ouput of the jar?
The plain ubuntu docker container (FROM ubuntu) does not include the java runtime environment.
You have the following options:
Install java into the ubuntu container. See here: https://dzone.com/articles/creating-a-docker-image-with-ubuntu-and-java
Use the openjdk as your base container, e.g. FROM openjdk:11
I would prefer the second option unless you really need ubuntu as your base container.
See also the docker hub page for openjkd, which has several other variantes available, e.g. opnejdk
I have a large scale java application with 5 Main methods in different classes. I want to run this application as a docker container. From DockerHub OpenJDK Image, I started my Dockerfile as follows
FROM openjdk:latest
COPY . /usr/src/APP
WORKDIR /usr/src/APP`
and I want to add the lines to run the main methods. Without Docker, I run the app using the below lines
echo 'Starting App'
nohup $JAVA_HOME/bin/java .:./App.jar path.to.main.class1 >>
/path/to/nohup/nohup.out 2>&1 &
nohup $JAVA_HOME/bin/java .:./App.jar path.to.main.class2 >>
/path/to/nohup/nohup.out 2>&1 &
nohup $JAVA_HOME/bin/java .:./App.jar path.to.main.class3 >>
/path/to/nohup/nohup.out 2>&1 &
nohup $JAVA_HOME/bin/java .:./App.jar path.to.main.class4 >>
/path/to/nohup/nohup.out 2>&1 &
nohup $JAVA_HOME/bin/java .:./App.jar path.to.main.class5 >>
/path/to/nohup/nohup.out 2>&1 &
echo 'App Started Successfully'`
Is it possible to run the above scenario in one docker container? If possible, how can it be done while there can only be one ENTRYPOINT and CMD instructions in a Dockerfile ?
The usual answer to "how do I run multiple processes from one image" is to run multiple containers. Given the Dockerfile you show this is fairly straightforward:
# Build the image (once)
docker build -t myapp .
# Then run the five containers as background processes
docker run -d --name app1 java .:./App.jar path.to.main.class1
docker run -d --name app2 java .:./App.jar path.to.main.class2
docker run -d --name app3 java .:./App.jar path.to.main.class3
docker run -d --name app4 java .:./App.jar path.to.main.class4
docker run -d --name app5 java .:./App.jar path.to.main.class5
Since all of the commands are pretty similar, you could write a script to run them
#!/bin/sh
# Use the first command-line argument as the main class
MAIN_CLASS="$1"
shift
# Can also set JAVA_OPTS, other environment variables, ...
# Run the application
exec java -jar App.jar "path.to.main.$MAIN_CLASS" "$#"
copy that into the image
COPY run_main.sh /usr/local/bin
and then when you launch the containers just run that wrapper
docker run -d --name app1 run_main.sh class1
I have a java console application that I package as jar and run it as
java -jar target/myProject-1.0-SNAPSHOT.jar -arg1 145 -arg2 345 -arg3 99
I want to run the same command inside a container and pass these arguments (arg1, arg2, arg3) to docker run command. My docker file look like:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD target/myProject-1.0-SNAPSHOT.jar myProject-1.0-SNAPSHOT.jar
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /myProject-1.0-SNAPSHOT.jar" ]
then I try to run the image as follows:
docker run myProject:0.3 -e -arg1 145 -arg2 345 -arg3 99
but my program don't get the arguments. what I'm missing ?
You have to add the ENV command in the DOCKERFILE so that you can receive the arguments that you are passing in and then pass that onto the ENTRYPOINT script
Dockerfile will look something like this
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ENV arg1
ENV arg2
ENV arg3
ADD target/myProject-1.0-SNAPSHOT.jar myProject-1.0-SNAPSHOT.jar
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /myProject-1.0-SNAPSHOT.jar ${arg1} ${arg2} ${arg3}" ]
Let me know if you have any questions
The arguments you pass to docker run are the command it's running, which it appends to the end of the entry point. So what you're doing is equivalent to running:
sh -c "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /myProject-1.0-SNAPSHOT.jar" -arg1 145 -arg2 345 -arg3 99
Presented like this, you can see that the arguments are going to sh and not to java. If you want to combine a set of options that you define when you build the image with a set of options that you can append at runtime, you'll need to use a wrapper script or something similar.
Create file wrapper.sh and make it executable:
#!/bin/sh
exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /myProject-1.0-SNAPSHOT.jar "$#"
Add it to your container with ADD wrapper.sh /bin in the Dockerfile
Change your entrypoint to ["/bin/wrapper.sh"]
Now, when you run the image, it will append the arguments to the java command line
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.
I have a Dockerfile based on the spring guide about docker. My application consumes some private data, so I want to pass these parameters through environment variables. When I run a docker container:
docker run -p 8080:8080 -t myname/myapplication --env-file=~/env.list
it appears that the variables are not set and the application can't see them, what do I do wrong? How to pass these parameters?
env.list:
ACCOUNT_ID=my_account_id
ACCOUNT_PASSWORD=my_secret_password
My ENTRYPOINT:
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar $APPLICATION_NAME
I think
docker run
takes all parameters before the image and the command. If I do
docker run -t --env-file=env.list ubuntu sh -c "while true; do echo world; sleep 100 ;done"
and then
docker exec -it container_id env
I get
HOSTNAME=195f18677a91
TERM=xterm
ACCOUNT_ID=my_account_id
ACCOUNT_PASSWORD=my_secret_password
HOME=/root
Try
docker run -p 8080:8080 --env-file=~/env.list -t myname/myapplication
This works very well:
cat <<EOF > test.env
MYVAR=test
EOF
docker run -it --env-file test.env busybox env | grep MYVAR
That will print as expected:
MYVAR=test
In your case in your Java application you can access the environment variables via System.getenv().