I want to build a docker image. And I run
docker build --build-arg project_file_name=account.jar -t account:1.0 .
The docker file looks like this (#1)
FROM anapsix/alpine-java:8u172b11_server-jre
ARG project_file_name
MAINTAINER jim
COPY src/${project_file_name} /home/${project_file_name}
CMD java -jar /home/${project_file_name}
If hardcode the variable, it will look like this (#2)
FROM anapsix/alpine-java:8u172b11_server-jre
MAINTAINER jim
enter code here
COPY src/account.jar /home/account.jar
CMD java -jar /home/account.jar
After I build the image with #1 and #2
Using #1, when I docker run, docker tell me it cannot find the specified jar file
Using #2, when I docker run, docker is able to execute the java jar file correctly.
To me both #1 and #2 are same. Just #1 use build-arg variable way and #2 is hardcoding the value. I believe the way I use build-args is incorrect. Can anyone guide me on this?
Regards
A running container won’t have access to an ARG variable value., you'll need ENV variable for that. Though you can use ARG variable to set ENV variable. In your situation you can do
FROM anapsix/alpine-java:8u172b11_server-jre
ARG project_file_name
ENV PROJECT_FILE=${project_file_name}
MAINTAINER jim
COPY src/${project_file_name} /home/${project_file_name}
CMD java -jar /home/${PROJECT_FILE}
You can read more here
Related
Normally if I were to run .jar file, then I can pass properties like
$ java -Dfoo=bar -jar my_application.jar
And my_application will be able to access the value of foo.
But while trying to run the file generated by distTar it is not able to access the value of foo.
I generated tar file using
$ ./gradlew distTar
$ tar -xvf build/distributions/my_application-1.0.tar
$ my_application-1.0/bin/my_application -Dfoo=bar
My application is not able to get the value of foo.
So turns out we have to pass it as an environment variable. If I open my_application-1.0/bin/my_application, there is comment something like
# Add default JVM options here. You can also use JAVA_OPTS and MY_APPLICATION_OPTS to pass JVM options to this script.
So all I needed to do was to set my arguments in MY_APPLICATION_OPTS in environment variable.
Good day everyone.
I have a simple java-based cucumber application, that runs in Docker. I planing to specify which scenarios to run by using ENV for Cucumber tags.
My Dockerfile that able to run specified tags:
FROM maven:3.6.1-jdk-11
COPY target/cucumber-app.jar ./
CMD java -jar -Dcucumber.options='--tags #default' cucumber-app.jar
In this case, during docker run command all works perfectly.
I plan to set up a default scenario for not specified Tags and ability to set up special scenarios through ENV:
FROM maven:3.6.1-jdk-11
COPY target/cucumber-app.jar ./
ENV TAG '--tags #default'
CMD java -jar -Dcucumber.options=$TAG cucumber-app.jar
Unfortunately in this case after running docker container I got:
Error: could not open `default'
Possible you have any ideas why using ENV crash possibility to specify cucumber.options?
If you have a recent version of Cucumber rather then trying to squeeze command line options in through a system property via an environment variable, you can set the environment variable straight away. I.e:
ENV CUCUMBER_FILTER_TAGS '#Cucumber and not (#Gherkin or #Zucchini)'
CMD java -jar cucumber-app.jar
https://github.com/cucumber/cucumber-jvm/tree/main/core
I have a child image where I'm defining
ARG MX_HEAP_SET=1024
ARG MN_HEAP_SET=1024
ENV MX_HEAP_SET=${MX_HEAP_SET:-${MX_HEAP_SET}}
ENV MN_HEAP_SET=${MN_HEAP_SET:-${MN_HEAP_SET}}
ENV HEAP_SET="-Xmx${MX_HEAP_SET}m -Xms${MN_HEAP_SET}m"
ENV HEAP_SET=${HEAP_SET:-${HEAP_SET}}
and expecting to replace the default value of HEAP_SET which is placed in base image.
So, when I run the base image without any MX or MN value, then it works fine.
However as soon as I run the child image with docker run -e MX_HEAP_SET=2048, I still see the default value in container.
But as soon as I run docker run -e HEAP_SET="-Xmx2048m -Xms1024m" i see the change.
So, how can I implement same behavior with individual MAX and MIN parameters not as a string?
Is there other way to achieve this?
When you use below
ARG MX_HEAP_SET=1024
It means you are adding a build time argument. This can be overridden only during the docker build. What you need is rather startup bash file
/app/start.sh
#!/bin/sh
# export all variables from here on
set -a
MX_HEAP_SET=${MX_HEAP_SET:-1024}
MN_HEAP_SET=${MN_HEAP_SET:-1024}
MX_HEAP_SET=${SDC_MX_HEAP_SET:-${MX_HEAP_SET}}
MN_HEAP_SET=${SDC_MN_HEAP_SET:-${MN_HEAP_SET}}
HEAP_SET="-Xmx${MX_HEAP_SET}m -Xms${MN_HEAP_SET}m"
HEAP_SET=${HEAP_SET:-${HEAP_SET}}
exec "<yourstarting command>" $#
This will respect the environment variables the you give while running the image itself
But you need to make sure override your ENTRYPOINT or CMD to run /app/start.sh
exec is used in the end to make sure the running program replaces the shell process with itself
I need to run a docker image where I pass a bunch of jvm configurations to a jar file. I'm passing the configs via -e parameters as the example bellow.
Dockerfile:
FROM openjdk:9-jre
COPY test.jar /
CMD java -jar -DinstallationDate=$INSTALLATION_DATE /test.jar
Run command:
docker run -e INSTALLATION_DATE="03.05.10.2019 15:00:00" space
The problem is that when I run this, it gives me the following error:
Error: Unable to access jarfile 15:00:00
I tried running it with the json notation, like:
docker run -e ["INSTALLATION_DATE","03.05.10.2019 15:00:00"] space
It doesn't give me an error, but the parameter comes as an empty string.
I also tried to escape the space char with "\", but still didn't work.
Anyone knows how can I send this parameter to the jar execution inside the docker container? Is there another approach to this?
The problem is likely occurring because the CMD in your Dockerfile:
CMD java -jar -DinstallationDate=$INSTALLATION_DATE /test.jar
...is subject to word splitting after the variable $INSTALLATION_DATE is expanded. In order to turn off word splitting for that second argument to java, consider enclosing the variable in double quotes:
CMD java -jar -DinstallationDate="$INSTALLATION_DATE" /test.jar
I am wondering if is possible to do the following...
I have a small application in java (and gradle)
I am trying to set it in a container, so I created the Dockerfile and worked fine UNTIL I have to set a parameter.
To run it locally on my IDLE I set these program arguments:
server application-local.yml
That actually loads a file with many properties, without this the app will fail.
On my Dockerfile I have this
FROM openjdk:8-jdk-alpine
USER root:root
ENV NAME test
LABEL maintainer="myself"
WORKDIR /opt/apps
COPY build/libs/myapp.jar /opt/apps/myapp.jar
EXPOSE 8080
CMD ["java", "myapp.jar"]
I was wondering if I could do the following:
CMD ["java", "-server:application-local.yml", "myapp.jar"]
but doesnt work, also I cannot do
java -jar myapp.jar -server:application-local.yml
simply doesnt do anything
Dont wanna do a gradleBuild because it is supposed to use java only at my docker image...
Any idea how to do this?
Edit:
So, I have done the following, move my application-local.yml to a folder I can copy and added this
COPY some-path/application-local.yml /opt/apps/local.yml
and moved the CMD for this
CMD ["java", "myapp.jar", "server", "local.yml"]
I still get the same error, basically cannot resolve the values from that yml file.
EDIT 2 ---
Basically what I cannot do is to figure out how to send the application.default.yml as configuration file, I realise also that the -server does not anything, is my config file the one I cannot load and is not present in the jar (normal behaviour)
When using the java command, order of the arguments matter
First you put the java options, like -server, then the -jar ... Or the class name in the case of running classes directly, and then the application arguments
The proper way to run your app is:
CMD ["java", "-jar", "myapp.jar", "server", "application-local.yml"]
Then you have another problem, you are only copying the final jar file to your docker container, so it can can't find the application-local.yml file, copy this also to your docker container
COPY build/libs/application-local.yml /opt/apps/application-local.yml