Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker alpine + oracle java: cannot find java

I've been trying to create an alpine-based docker image with Oracle Java (rather than openjdk). I have been specifically asked to create our own image here.

This is the Dockerfile I've come up with:

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

There are some unnecessary commands (like echoing the JAVA_HOME dir) which were added to help with debugging, but now I'm stuck: RUN which java returns /opt/jdk/bin/java as expected, but RUN java -version returns /bin/sh: java: not found.

I've tried a few things, including symlinking the executable(s) into /usr/bin, to no avail.

What am I missing?

EDIT: Final output from docker is: The command '/bin/sh -c java -version' returned a non-zero code: 127

Final edit:

Thanks to diginoise for putting me on to MUSL vs libc. I found adding the following to my Dockerfile allowed me to build a working image:

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

Found at: https://github.com/sgerrand/alpine-pkg-glibc

like image 484
phanteh Avatar asked Jul 17 '17 14:07

phanteh


2 Answers

You cannot achieve what you want

Alpine Linux uses MUSL as a Standard C library.

Oracle's Java for linux depends on GNU Standard C library (gclib).

Here is a bit more detailed info and official stance from Oracle on the topic

the JDK source code has not yet been ported to Alpine Linux, or more specifically, the musl C library. That is, it turns out that the thing about Alpine Linux that sticks out/is different from a JDK source code perspective is the C library.

The solution

If you looking for small Java Docker images, use OpenJDK ones.

openjdk:11-jre-slim image is only 77MB.


If you insist, on your head be it...

There is theoretical way, but it is not as trivial as you think.

You can find many examples of Alpine images running with OracleJDK like here or see expert's answer to this question as well. They add the missing Standard GNU C library.

Be warned however...

All of these solutions could be in breach of Oracle's license agreement stating that the license is non-transferable, and the distributable is non-modifiable. In the Dockerfiles you will find however:

Cookie: oraclelicense=accept-securebackup-cookie"

and many entries similar to

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

For further details about legality of prepackaged Oracle's JRE or JDK Docker images see this article.

like image 52
diginoise Avatar answered Nov 13 '22 22:11

diginoise


I found an answer that works finally. All is needed is just the GlibC; huge thanks to S. Gerrand, this is such a big help.

Here's how to get the old JDK 8 running in Alpine 1.13:

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
like image 40
b01 Avatar answered Nov 13 '22 22:11

b01