Dynamically set JAVA_HOME of docker container
Asked Answered
F

8

13

My docker container requires JAVA_HOME to be set. I have added it to the Dockerfile as below

ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/jre

However, this is a hardcoding of the value. Is there a way I can get this value dynamically from the image itself

Forbearance answered 27/4, 2017 at 10:34 Comment(0)
F
13

Set JAVA_HOME in docker container

Default Docker file of the official image is Dockerfile

If you still want your own image with Java home set. Add this lines to your Dockerfile

RUN apt-get update && \
    apt-get install -y openjdk-8-jdk && \
    apt-get install -y ant && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/ && \
    rm -rf /var/cache/oracle-jdk8-installer;
    
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/
RUN export JAVA_HOME

Create the docker-compose.yml, replace the dynamic path with container updating the environment variable in the environment:

Ferrous answered 9/10, 2018 at 15:56 Comment(4)
I think the crux of the issue is on how to do it dynamically. This is not dynamic. You just hardcode the value because you know beforehand what it will be.Bureaucratic
You can make it dynamic by adding the Build args, but that will be the case when you install java in a specific location with apt-get install -y openjdk-8-jdk. If we are confident enough to install at a specific path then we can update the dynamic path with docker build command with docker build -t myjava --build-arg JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ .Ferrous
That also is not dynamic -- it's still using the known (to you) path rather than letting the Dockerfile figure it out (though, I suspect there isn't a way to have the Dockerfile do that. Unfortunately.Stereotaxis
I got #0 10.13 E: Unable to locate package openjdk-8-jdk, which I was able to fix by replacing openjdk-8-jdk with default-jre.Garment
S
6

It's possible add the JAVA_HOME in a ENV Dockerfile instruction. But if the Java package is updated you have to change the ENV JAVA_HOME in your Dockerfile.

But I found a method to set the JAVA_HOME automatically without update the Dockerfile.

RUN export JAVA_HOME="$(dirname $(dirname $(readlink -f $(which java))))"

WARNING: This is only valid if you run all the commands in the same RUN a one-liner command using the '&&' operand as Mig82 says in the comments section.

I hope this can help you.

Saval answered 19/9, 2019 at 9:16 Comment(2)
This won't work. I think the reason is that the export command —like any other command executed with the RUN instruction— runs in an intermediate container. So the only way this works is if you can run whatever needs JAVA_HOME set in a one-liner using the && operand. Like this: RUN export JAVA_HOME="$(dirname $(dirname $(readlink -f $(which java))))" && echo $JAVA_HOME. But if you move the echo down into a new RUN instruction of its own, you'll get a blank (or whatever the old JAVA_HOME value was).Bureaucratic
Hi Mig82. Of course you have the reason. I know what you say, but it's true that my answer is not well explained, sorry for that, and thanks for show me the error. I'm going to correct my answer. If someone is reading this and wants more info about this behaviour, I link here one post explaining this: https://mcmap.net/q/143435/-docker-env-vs-run-exportSaval
H
3

The image built from a Dockerfile is forever static. Its Java location will never change unless rebuilt.

When the image is started as a container, however, anything can happen. If there's any scripts that will edit the Java location during runtime, then this script is probably also where JAVA_HOME should be updated.

If you mean that you want to dynamically build your image using an arbitrary base image with differing java location then this should probably be handled by a build script.

Holarctic answered 27/4, 2017 at 10:50 Comment(0)
T
2

If you need to have it available between multiple RUN commands you should put it in bash profile setup, like /etc/profile.d/ or ~/.bashrc, or whatever shell you are using in the container.

Example:

RUN echo "export JAVA_HOME=$(dirname $(dirname $(readlink -f $(type -P java))))" > /etc/profile.d/javahome.sh
> docker run -it test1 bash
[root@aa425d96829d /]# echo $JAVA_HOME
/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-1.el7_9.x86_64
Trichocyst answered 25/11, 2021 at 0:19 Comment(0)
T
0

May be you can do something like this in CMD :

# rpm -qa | grep java-1.8
java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64

and then

#rpm -ql java-1.8.0-openjdk | sed -n '1p' | cut -d/ -f1-5
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64
Terrier answered 8/5, 2017 at 10:7 Comment(0)
R
0

In case of windows container, you can do something like this within your docker file: [Make sure your windows image should have any such jdk/jre directory present at a location]

For me, I have been using the windows server core:ltsc2019 (FROM mcr.microsoft.com/windows/servercore:ltsc2019) which is customized with some wildfly config and jdk. But all in all the setx worked for me to set the java directly into the path.

Example:

RUN setx path "C:\jdk8u252-b09\bin"
Regelate answered 16/3, 2022 at 12:11 Comment(0)
F
0

If you want the ENV value to be passed as an input during the docker image build - use ARG directive(Instruction).

Syntax : declare ARG in Dockerfile like below :

ARG DYNAMIC_JAVA_HOME=defaultvalue, 

then pass default value as the dynamic value for ENV, ie :

ENV JAVA_HOME=${DYNAMIC_JAVA_HOME}

while building the image pass this ARG as an input ==>

docker image build --build-arg DYNAMIC_JAVA_HOME=value.
Fleecy answered 11/4, 2022 at 16:12 Comment(0)
A
0

I got this setup dynamically for a Keycloak RedHat container, using the following:

RUN JAVA_HOME="$(dirname $(dirname $(update-alternatives --list | head -n 1)) | tail -1)" 

Note that the Keycloak RedHat container is a bit limited in terms of default libraries, and I didn't want to install additional tools just to get the JAVA path.

Also Note that this simply sets a variable to JAVA_HOME, so if you want to use this in a command, you need to include it with an '&&'

Example:

 RUN JAVA_HOME="$(dirname $(dirname $(update-alternatives --list | head -n 1)) | tail -1)" && echo $JAVA_HOME
Ankerite answered 16/11, 2023 at 23:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.