Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker container not using ENV variables

SO I am trying to change the JVM heap memory percentage I have added these two lines in my Dockerfile

ENV JAVA_OPTS="--XX:MinRAMPercentage=50.0 --XX:MaxRAMPercentage=80.0"
CMD ["--spring.profiles.active=${profile}","${JAVA_OPTS}"]

But when I check this command:(java -XX:+PrintFlagsFinal -version | grep -E "UseContainerSupport | InitialRAMPercentage | MaxRAMPercentage | MinRAMPercentage") on my docker container, it shows default values of the above parameter: enter image description here

like image 372
HMT Avatar asked Apr 22 '26 11:04

HMT


1 Answers

No environment variable expansion or other processing is done on exec form CMD (or ENTRYPOINT or RUN). Your application is getting invoked with literally the strings --spring.profiles.active=${profile} and ${JAVA_OPTS}, and you will see these including the ${...} markers in your Java program's main() function.

Docker's normal assumption here is that any expansion like this will be done in a shell, and shell form CMD will wrap its string in /bin/sh -c '...' so this happens. However, this setup isn't compatible with splitting ENTRYPOINT and CMD: due to the mechanics of how the two parts are combined neither part can be wrapped in a shell if you're using the "container as command" pattern where the CMD is just an argument list.

The easiest way to handle this is to ignore ENTRYPOINT entirely; put all of the command and arguments into CMD; and use the shell form rather than the exec form.

ENV JAVA_OPTS="--XX:MinRAMPercentage=50.0 --XX:MaxRAMPercentage=80.0"
# no ENTRYPOINT; shell form of CMD
CMD java ${JAVA_OPTS} -jar /app/app.jar --spring.profiles.default=${profile}

If you docker run a temporary debugging container on this image, it will see the environment variable but the command you provide will replace the image's CMD.

docker run --rm your-image \
  /bin/sh -c 'echo $JAVA_OPTS'
# prints the environment setting

Correspondingly if you run a separate java, it won't see the options that are only provided in the image's CMD. (Similarly try running java -XX:MaxRamPercentage=80.0 in one terminal window, and java -XX:+PrintFlagsFinal with no other options in another window, and the second invocation won't see the JVM options from the first JVM; the same mechanics apply to Docker containers.)

like image 187
David Maze Avatar answered Apr 23 '26 23:04

David Maze



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!