我正在使用Dockerfile,它安装了两个Java版本(Java 8和Java 11)。我想将 Java 11 设置为默认版本。根据需要,它从Java 11切换到Java 8。为此,我从私有基础映像构建了Docker镜像,并安装了两个版本并为Java 11提供了环境,并创建了一个shell脚本,该脚本在运行容器期间将Java版本从Java 11切换到Java 8。这种方法失败了。请让我知道解决此问题的任何可能性。
Dockerfile :
FROM private=base-image
ARG JAVA_VERSION=11.0.12.0
ARG JAVA_ARCHIVE_NAME=java-certified-jdk_x64_linux_11.0.12.0.bin
RUN curl {java-resource}/cloud/runtimes/java/${JAVA_VERSION}/linux/x86_64/${JAVA_ARCHIVE_NAME} -o /tmp/java-sdk-${JAVA_VERSION}.bin &&
chmod +x /tmp/java-sdk-${JAVA_VERSION}.bin &&
echo "INSTALLER_UI=silent" > /tmp/java-installer.properties &&
echo "LICENSE_ACCEPTED=TRUE" >> /tmp/java-installer.properties &&
echo "USER_INSTALL_DIR=/opt/java/java-certified-11-jdk" >> /tmp/java-installer.properties &&
/tmp/java-java-sdk-${JAVA_VERSION}.bin -i silent -f /tmp/java-installer.properties &&
ln -sf /opt/java/java-certified-11-jdk/bin/* /usr/local/bin/ &&
rm /tmp/java-java-sdk-${JAVA_VERSION}.bin &&
rm /tmp/java-installer.properties
ARG JAVA8_VERSION=8.0.6.35
ARG JAVA8_ARCHIVE_NAME=java-sdk-8.0-6.35-x86_64-archive.bin
RUN curl https://public.dhe.java.com/javadl/export/pub/systems/cloud/runtimes/java/${JAVA8_VERSION}/linux/x86_64/${JAVA8_ARCHIVE_NAME} -o /tmp/java-java-sdk-${JAVA8_VERSION}.bin &&
chmod +x /tmp/java-java-sdk-${JAVA8_VERSION}.bin &&
echo "INSTALLER_UI=silent" > /tmp/java-installer.properties &&
echo "LICENSE_ACCEPTED=TRUE" >> /tmp/java-installer.properties &&
echo "USER_INSTALL_DIR=/opt/java/java" >> /tmp/java-installer.properties &&
/tmp/java-sdk-${JAVA8_VERSION}.bin -i silent -f /tmp/java-installer.properties &&
rm /tmp/java-java-sdk-${JAVA8_VERSION}.bin &&
rm /tmp/java-installer.properties
ENV PATH=$PATH:/opt/java/java-certified-11-jdk/bin
JAVA_HOME=/opt/java/java-certified-11-jdk
java_JAVA_OPTIONS="-XX:+UseContainerSupport"
容器内的外壳逻辑:
#!/bin/bash
TARGET_JDK=JAVA8
if [ $TARGET_JDK == JAVA8 ]; then
JAVA_PATH="/opt/xxx/java"
echo "${JAVA_PATH}"
export PATH=$PATH:${JAVA_PATH}/bin
export JAVA_HOME=${JAVA_PATH}
export xxx_JAVA_OPTIONS="-XX:+UseContainerSupport"
else
JAVA_PATH="/opt/xxx/xxx-yyy-certified-11-jdk"
echo "${JAVA_PATH}"
export PATH=$PATH:${JAVA_PATH}/bin
export JAVA_HOME=${JAVA_PATH}
export xxx_JAVA_OPTIONS="-XX:+UseContainerSupport"
fi
当您运行应用程序时,它将只使用一个 JRE 或另一个。 无需在映像中包含未使用的 JRE。
您可以使用 DockerfileARG
来指定应使用哪个 JRE 构建映像。 这在RUN
命令看来是一个正常的环境变量。 这得益于两个 JRE 版本中的大多数安装逻辑相同。
我可能写的第一件事是一个独立的 shell 脚本来执行安装。 这将更容易在您喜欢的 IDE 中进行编辑,并在容器外部进行测试。
#!/bin/sh
if [ "$1" = 8 ]; then
JAVA_VERSION=8.0.6.35
JAVA_ARCHIVE_NAME=java-sdk-8.0-6.35-x86_64-archive.bin
elsif [ "$1" = 11 ]; then
JAVA_VERSION=11.0.12.0
JAVA_ARCHIVE_NAME=java-certified-jdk_x64_linux_11.0.12.0.bin
else
echo >&2 <<EOF
Usage: install-java.sh [8|11]
EOF
exit 1
fi
curl {java-resource}/cloud/runtimes/java/${JAVA_VERSION}/linux/x86_64/${JAVA_ARCHIVE_NAME} -o /tmp/java-sdk-${JAVA_VERSION}.bin
chmod +x /tmp/java-sdk-${JAVA_VERSION}.bin
cat >/tmp/java-installer.properties <<EOF
INSTALLER_UI=silent
LICENSE_ACCEPTED=TRUE
USER_INSTALL_DIR=/opt/java
EOF
/tmp/java-java-sdk-${JAVA_VERSION}.bin -i silent -f /tmp/java-installer.properties
rm /tmp/java-java-sdk-${JAVA_VERSION}.bin
rm /tmp/java-installer.properties
然后在 Dockerfile 中,您需要设置一个ARG
以接受脚本中的版本设置、COPY
并对其进行RUN
。
COPY install-java.sh ./
ARG java_version=11
RUN ./install-java.sh ${java_version}
ENV PATH=/opt/java/bin:$PATH
现在您可以像往常一样构建和运行容器,它只包含 Java 11
docker build -t myapp-java11 .
docker run --rm myapp-java11 java -version
docker run myapp-java11
但您也可以构建基于 Java 8 构建的备用映像
。docker build --build-arg java_version=8 myapp-java8 .
docker run --rm myapp-java8 java -version
docker run myapp-java8
这为您省去了在启动时尝试找出安装路径的麻烦,并为您提供了一个较小的映像,该映像不包含您不使用的整个 JRE。
此设置不做的一件事是添加+XX:ContainerSupport
设置,但在较旧的 Java 8 的最新版本中也没有必要这样做。 有条件地设置ENV
很难,但您可以根据java -version
返回的内容在入口点包装器脚本中执行此操作。