Docker Alpine + Oracle Java:找不到Java

18

我一直在尝试创建一个基于alpine的Docker镜像,其中包含Oracle Java(而不是openjdk)。我被要求在此处创建我们自己的镜像。

这是我想到的Dockerfile:

FROM alpine:3.6

RUN apk add --no-cache curl wget

RUN mkdir /opt/ && \
    wget -c --header "Cookie: oraclelicense=accept-securebackup-cookie"\
    http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz && \
    tar xvf jdk-8u131-linux-x64.tar.gz -C /opt/ && \
    rm jdk-8u131-linux-x64.tar.gz && \
    ln -s /opt/jdk1.8.0_131 /opt/jdk

ENV JAVA_HOME /opt/jdk
ENV PATH $PATH:/opt/jdk/bin

RUN echo $JAVA_HOME && \
    echo $PATH

RUN which java
RUN java -version

有一些不必要的命令(比如回显JAVA_HOME目录)被添加用于调试,但是现在我卡住了:RUN which java返回预期的/opt/jdk/bin/java,但是RUN java -version返回/bin/sh: java: not found

我尝试了一些方法,包括将可执行文件链接到/usr/bin中,但是都没有成功。

我错过了什么?

编辑:来自docker的最终输出是:The command '/bin/sh -c java -version' returned a non-zero code: 127

最终编辑:

感谢diginoise提供关于MUSL vs libc的信息。 我发现将以下内容添加到我的Dockerfile中可以构建一个可工作的镜像:

RUN apk --no-cache add ca-certificates && \
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://raw.githubusercontent.com/sgerrand/alpine-pkg-glibc/master/sgerrand.rsa.pub && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.25-r0/glibc-2.25-r0.apk && \
apk add glibc-2.25-r0.apk

发现于: https://github.com/sgerrand/alpine-pkg-glibc


1
你从echo $JAVA_HOME和$PATH中得到什么? - Edwin
JAVA_HOME: /opt/jdk 路径:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/jdk/bin - phanteh
你可以尝试运行 RUN echo "$(java -version)" 吗? - Edwin
1
你假设Java将驻留在哪里... 你能否启动与容器的交互会话并验证Java确切的位置? - diginoise
你尝试过执行 RUN /opt/jdk/bin/java -version 吗? - Edwin
显示剩余6条评论
4个回答

22

你无法实现想要的目标

Alpine Linux使用MUSL作为标准C库。

Oracle的Linux版Java依赖于GNU标准C库(gclib)。

在这里可以找到更详细的信息和Oracle对此问题的官方立场

JDK源代码尚未移植到Alpine Linux,或者更具体地说,是musl C库。也就是说,从JDK源代码的角度来看,Alpine Linux最显着/不同的特点是C库。

解决方案

如果你正在寻找小型Java Docker镜像,请使用OpenJDK镜像

openjdk:11-jre-slim镜像只有77MB


如果你坚持,后果自负...

有一种理论方法,但并不像你想象的那么简单

你可以找到许多运行OracleJDK的Alpine镜像的示例,比如这里或查看专家对此问题的回答。 他们会添加缺失的标准GNU C库。

但要小心...

所有这些解决方案可能违反Oracle的许可协议,该协议规定许可证是不可转让的,可分发的内容是不可修改的。 然而,在Dockerfile中你会发现:

Cookie: oraclelicense=accept-securebackup-cookie"

以及许多类似的条目

rm -rf ${JAVA_HOME}/*src.zip

有关预先打包的OracleJREJDK Docker镜像的合法性的更多详细信息,请查看此文章


1
因为他看到的退出代码来自于一个崩溃的Java进程,该进程缺少上述依赖项。 - Marged
1
您可以在这里找到使用OracleJDK的Alpine镜像的示例:https://hub.docker.com/r/frolvlad/alpine-oraclejdk8/~/dockerfile/ 和 https://hub.docker.com/r/anapsix/alpine-java/~/dockerfile/。这基本上总是涉及添加缺失的GNU C库。 - brass monkey
@LazerBass,请编辑我的答案,添加具有glibC的2个Docker Alpine镜像,我将很乐意批准! - diginoise
从我在互联网上看到的情况来看,这似乎不是一个正确的答案。 https://developer.atlassian.com/blog/2015/08/minimal-java-docker-containers/ - b01
@b01,请在我的回答更新中查找详细信息。将Oracle的Java添加到Docker镜像中可能违反其许可协议。 - diginoise

1
我最终找到了一个可行的答案。只需要 GlibC,非常感谢 S. Gerrand 的帮助。
以下是在 Alpine 1.13 上运行旧版 JDK 8 的方法:
FROM alpine:3.13

RUN apk --no-progress --purge --no-cache upgrade \
&& apk --no-progress --purge --no-cache add --upgrade \
    curl \
    wget \
    openssh \
&& apk --no-progress --purge --no-cache upgrade \
&& rm -vrf /var/cache/apk/* \
&& curl --version

# Install vanilla GLibC: https://github.com/sgerrand/alpine-pkg-glibc
RUN curl -o /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub \
&& curl -LO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.32-r0/glibc-2.32-r0.apk \
&& apk add glibc-2.32-r0.apk

RUN wget -c --header "Cookie: oraclelicense=accept-securebackup-cookie" \
        http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz \
  && tar xvf jdk-8u131-linux-x64.tar.gz -C /opt \
  && rm jdk-8u131-linux-x64.tar.gz \
  && ln -s /opt/jdk1.8.0_131 /opt/jdk

ENV JAVA_HOME /opt/jdk
ENV PATH $PATH:/opt/jdk/bin

RUN echo $JAVA_HOME && \
    echo $PATH

RUN which java
RUN java -version

ENTRYPOINT [ "java" ]

# To test run: docker run -t khalifahks/alpine-java -version
# docker export <container-id> | docker import - khalifahks/alpine-java:exported
# quick interative termnal: docker run -it --entrypoint=sh khalifahks/alpine-java sh

除非有许可问题,否则这个程序可以运行。图像大小为408MB。不是理想的选择,但也不算太糟糕。可能还有一些清理工作需要完成。 - b01

1

请查看我的更新答案以及关于打包Oracle二进制文件合法性的讨论。 - diginoise

0
我正在尝试运行自己的Docker Java应用程序,但遇到了一个问题,当我添加时。
ENV JAVA_HOME /opt/jdk
ENV PATH $PATH:/opt/jdk/bin

对于我的Dockerfile,我遇到了一些问题。
/bin/sh: ENV: not found

我完全不知道如何安装环境,或者如何让它正常工作...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接