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
Related
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"]
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.
Is it possible to copy an existing WebSphere profile and run it on WebSphere in Docker?
I am doing some research on containerization, virtualization, etc. and am currently working with Docker. Getting WebSphere up and running on Docker is simple enough:
docker run --name wasserver -h wasserver -p 9043:9043 -p 9443:9443 -d ibmcom/websphere-traditional:install
What I'd like to do is use a profile from another WebSphere instance and run that on the Docker WebSphere. I have tried to do the following in an attempt to mount a directory that contains the profile in question, and to run same:
docker run -v /opt/WebSphere/WAS8_5/:/WASDIR --name myprofileserver -h myprofileserver -p 9043:9043 -p 9443:9443 -d ibmcom/websphere-traditional:install -e PROFILE_NAME=/WASDIR/profiles/myprofile1
The end result of this command is that the container is created, but does not run:
docker: Error response from daemon: oci runtime error: exec: "-e": executable file not found in $PATH
Perhaps there is a switch, setup, or other configuration I am missing here?
The last argument to docker run is the command you want to run inside the container (or the name of the image if you're running the default entrypoint / cmd). You just need to move your environment variable definition back in the command like this:
docker run -v /opt/WebSphere/WAS8_5/:/WASDIR --name myprofileserver -h myprofileserver -p 9043:9043 -p 9443:9443 -d -e PROFILE_NAME=/WASDIR/profiles/myprofile1 ibmcom/websphere-traditional:install
I am having an weird issue using --ulimit cpu=10. I want to make sure the process gets killed after 10 seconds of using the CPU. When the java process is invoked directly it fails, but when it is invoked by first running bask it works.
This works fine.The process gets killed after 10s
docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
bash -c 'java -cp /classes/ InfiniteLoop'
But this doesn't.
docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
java -cp /classes/ InfiniteLoop
Any idea how to fix this issue?
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().