From 127c9674917835cede83ec8de23df188bbb2cae9 Mon Sep 17 00:00:00 2001 From: eclipse-temurin-bot Date: Fri, 12 Dec 2025 12:22:06 +0000 Subject: [PATCH] dockerfile: automated nightly updates --- 11/jdk/alpine/3.23/Dockerfile | 90 ++++++++++++++++++++++++ 11/jdk/alpine/3.23/entrypoint.sh | 114 ++++++++++++++++++++++++++++++ 11/jre/alpine/3.23/Dockerfile | 86 +++++++++++++++++++++++ 11/jre/alpine/3.23/entrypoint.sh | 114 ++++++++++++++++++++++++++++++ 17/jdk/alpine/3.23/Dockerfile | 93 +++++++++++++++++++++++++ 17/jdk/alpine/3.23/entrypoint.sh | 114 ++++++++++++++++++++++++++++++ 17/jre/alpine/3.23/Dockerfile | 86 +++++++++++++++++++++++ 17/jre/alpine/3.23/entrypoint.sh | 114 ++++++++++++++++++++++++++++++ 21/jdk/alpine/3.23/Dockerfile | 97 ++++++++++++++++++++++++++ 21/jdk/alpine/3.23/entrypoint.sh | 114 ++++++++++++++++++++++++++++++ 21/jre/alpine/3.23/Dockerfile | 90 ++++++++++++++++++++++++ 21/jre/alpine/3.23/entrypoint.sh | 114 ++++++++++++++++++++++++++++++ 25/jdk/alpine/3.23/Dockerfile | 97 ++++++++++++++++++++++++++ 25/jdk/alpine/3.23/entrypoint.sh | 114 ++++++++++++++++++++++++++++++ 25/jre/alpine/3.23/Dockerfile | 90 ++++++++++++++++++++++++ 25/jre/alpine/3.23/entrypoint.sh | 114 ++++++++++++++++++++++++++++++ 8/jdk/alpine/3.23/Dockerfile | 87 +++++++++++++++++++++++ 8/jdk/alpine/3.23/entrypoint.sh | 115 +++++++++++++++++++++++++++++++ 8/jre/alpine/3.23/Dockerfile | 86 +++++++++++++++++++++++ 8/jre/alpine/3.23/entrypoint.sh | 114 ++++++++++++++++++++++++++++++ 20 files changed, 2043 insertions(+) create mode 100644 11/jdk/alpine/3.23/Dockerfile create mode 100644 11/jdk/alpine/3.23/entrypoint.sh create mode 100644 11/jre/alpine/3.23/Dockerfile create mode 100644 11/jre/alpine/3.23/entrypoint.sh create mode 100644 17/jdk/alpine/3.23/Dockerfile create mode 100644 17/jdk/alpine/3.23/entrypoint.sh create mode 100644 17/jre/alpine/3.23/Dockerfile create mode 100644 17/jre/alpine/3.23/entrypoint.sh create mode 100644 21/jdk/alpine/3.23/Dockerfile create mode 100644 21/jdk/alpine/3.23/entrypoint.sh create mode 100644 21/jre/alpine/3.23/Dockerfile create mode 100644 21/jre/alpine/3.23/entrypoint.sh create mode 100644 25/jdk/alpine/3.23/Dockerfile create mode 100644 25/jdk/alpine/3.23/entrypoint.sh create mode 100644 25/jre/alpine/3.23/Dockerfile create mode 100644 25/jre/alpine/3.23/entrypoint.sh create mode 100644 8/jdk/alpine/3.23/Dockerfile create mode 100644 8/jdk/alpine/3.23/entrypoint.sh create mode 100644 8/jre/alpine/3.23/Dockerfile create mode 100644 8/jre/alpine/3.23/entrypoint.sh diff --git a/11/jdk/alpine/3.23/Dockerfile b/11/jdk/alpine/3.23/Dockerfile new file mode 100644 index 000000000..0c02e4123 --- /dev/null +++ b/11/jdk/alpine/3.23/Dockerfile @@ -0,0 +1,90 @@ +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM alpine:3.23 + +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH=$JAVA_HOME/bin:$PATH + +# Default to UTF-8 file.encoding +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8' + +RUN set -eux; \ + apk add --no-cache \ + # java.lang.UnsatisfiedLinkError: libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory + # java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager + # https://github.com/docker-library/openjdk/pull/235#issuecomment-424466077 + fontconfig ttf-dejavu \ + # gnupg required to verify the signature + gnupg \ + # utilities for keeping Alpine and OpenJDK CA certificates in sync + # https://github.com/adoptium/containers/issues/293 + ca-certificates p11-kit-trust \ + # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 + musl-locales musl-locales-lang \ + tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ + ; \ + rm -rf /var/cache/apk/* + +ENV JAVA_VERSION=jdk-11.0.29+7 + +RUN set -eux; \ + ARCH="$(apk --print-arch)"; \ + case "${ARCH}" in \ + x86_64) \ + ESUM='c7b58655ffde7b5e6fce4a32fdcd21be5745b3bb64ee2bc723fcf55eae720ebe'; \ + BINARY_URL='https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.29%2B7/OpenJDK11U-jdk_x64_alpine-linux_hotspot_11.0.29_7.tar.gz'; \ + ;; \ + *) \ + echo "Unsupported arch: ${ARCH}"; \ + exit 1; \ + ;; \ + esac; \ + wget -O /tmp/openjdk.tar.gz ${BINARY_URL}; \ + wget -O /tmp/openjdk.tar.gz.sig ${BINARY_URL}.sig; \ + export GNUPGHOME="$(mktemp -d)"; \ + # gpg: key 843C48A565F8F04B: "Adoptium GPG Key (DEB/RPM Signing Key) " imported + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 3B04D753C9050D9A5D343F39843C48A565F8F04B; \ + gpg --batch --verify /tmp/openjdk.tar.gz.sig /tmp/openjdk.tar.gz; \ + rm -rf "${GNUPGHOME}" /tmp/openjdk.tar.gz.sig; \ + echo "${ESUM} */tmp/openjdk.tar.gz" | sha256sum -c -; \ + mkdir -p "$JAVA_HOME"; \ + tar --extract \ + --file /tmp/openjdk.tar.gz \ + --directory "$JAVA_HOME" \ + --strip-components 1 \ + --no-same-owner \ + ; \ + rm -f /tmp/openjdk.tar.gz ${JAVA_HOME}/lib/src.zip; + +RUN set -eux; \ + echo "Verifying install ..."; \ + fileEncoding="$(echo 'System.out.println(System.getProperty("file.encoding"))' | jshell -s -)"; [ "$fileEncoding" = 'UTF-8' ]; rm -rf ~/.java; \ + echo "javac --version"; javac --version; \ + echo "java --version"; java --version; \ + echo "Complete." +COPY --chmod=755 entrypoint.sh /__cacert_entrypoint.sh +ENTRYPOINT ["/__cacert_entrypoint.sh"] + +CMD ["jshell"] diff --git a/11/jdk/alpine/3.23/entrypoint.sh b/11/jdk/alpine/3.23/entrypoint.sh new file mode 100644 index 000000000..7822fe589 --- /dev/null +++ b/11/jdk/alpine/3.23/entrypoint.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env sh +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. + +set -e + +TMPDIR=${TMPDIR:-/tmp} + +# JDK truststore location +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts + +# Opt-in is only activated if the environment variable is set +if [ -n "$USE_SYSTEM_CA_CERTS" ]; then + + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." + exit 1 + fi + + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$JRE_CACERTS_PATH" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" + fi + + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Extract the Common Name (CN) and Serial Number from the certificate + CN=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + SERIAL=$(openssl x509 -in "$crt" -noout -serial | sed -n 's/^serial=\(.*\)$/\1/p') + + # Check if an alias with the CN already exists in the keystore + ALIAS=$CN + if keytool -list -keystore "$JRE_CACERTS_PATH" -storepass changeit -alias "$ALIAS" >/dev/null 2>&1; then + # If the CN already exists, append the serial number to the alias + ALIAS="${CN}_${SERIAL}" + fi + + echo "Adding certificate with alias $ALIAS to the JVM truststore" + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done + done + + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + cp -La /certificates/* /usr/local/share/ca-certificates/ + fi + update-ca-certificates + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi +fi + +# Let's provide a variable with the correct path for tools that want or need to use it +export JRE_CACERTS_PATH + +exec "$@" diff --git a/11/jre/alpine/3.23/Dockerfile b/11/jre/alpine/3.23/Dockerfile new file mode 100644 index 000000000..210dab3bb --- /dev/null +++ b/11/jre/alpine/3.23/Dockerfile @@ -0,0 +1,86 @@ +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM alpine:3.23 + +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH=$JAVA_HOME/bin:$PATH + +# Default to UTF-8 file.encoding +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8' + +RUN set -eux; \ + apk add --no-cache \ + # java.lang.UnsatisfiedLinkError: libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory + # java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager + # https://github.com/docker-library/openjdk/pull/235#issuecomment-424466077 + fontconfig ttf-dejavu \ + # gnupg required to verify the signature + gnupg \ + # utilities for keeping Alpine and OpenJDK CA certificates in sync + # https://github.com/adoptium/containers/issues/293 + ca-certificates p11-kit-trust \ + # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 + musl-locales musl-locales-lang \ + tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ + ; \ + rm -rf /var/cache/apk/* + +ENV JAVA_VERSION=jdk-11.0.29+7 + +RUN set -eux; \ + ARCH="$(apk --print-arch)"; \ + case "${ARCH}" in \ + x86_64) \ + ESUM='a37e818c23e19a0f3f6a77827eac9c6dab572c22efafa6c0e888cce2555d39a2'; \ + BINARY_URL='https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.29%2B7/OpenJDK11U-jre_x64_alpine-linux_hotspot_11.0.29_7.tar.gz'; \ + ;; \ + *) \ + echo "Unsupported arch: ${ARCH}"; \ + exit 1; \ + ;; \ + esac; \ + wget -O /tmp/openjdk.tar.gz ${BINARY_URL}; \ + wget -O /tmp/openjdk.tar.gz.sig ${BINARY_URL}.sig; \ + export GNUPGHOME="$(mktemp -d)"; \ + # gpg: key 843C48A565F8F04B: "Adoptium GPG Key (DEB/RPM Signing Key) " imported + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 3B04D753C9050D9A5D343F39843C48A565F8F04B; \ + gpg --batch --verify /tmp/openjdk.tar.gz.sig /tmp/openjdk.tar.gz; \ + rm -rf "${GNUPGHOME}" /tmp/openjdk.tar.gz.sig; \ + echo "${ESUM} */tmp/openjdk.tar.gz" | sha256sum -c -; \ + mkdir -p "$JAVA_HOME"; \ + tar --extract \ + --file /tmp/openjdk.tar.gz \ + --directory "$JAVA_HOME" \ + --strip-components 1 \ + --no-same-owner \ + ; \ + rm -f /tmp/openjdk.tar.gz; + +RUN set -eux; \ + echo "Verifying install ..."; \ + echo "java --version"; java --version; \ + echo "Complete." +COPY --chmod=755 entrypoint.sh /__cacert_entrypoint.sh +ENTRYPOINT ["/__cacert_entrypoint.sh"] diff --git a/11/jre/alpine/3.23/entrypoint.sh b/11/jre/alpine/3.23/entrypoint.sh new file mode 100644 index 000000000..7822fe589 --- /dev/null +++ b/11/jre/alpine/3.23/entrypoint.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env sh +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. + +set -e + +TMPDIR=${TMPDIR:-/tmp} + +# JDK truststore location +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts + +# Opt-in is only activated if the environment variable is set +if [ -n "$USE_SYSTEM_CA_CERTS" ]; then + + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." + exit 1 + fi + + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$JRE_CACERTS_PATH" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" + fi + + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Extract the Common Name (CN) and Serial Number from the certificate + CN=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + SERIAL=$(openssl x509 -in "$crt" -noout -serial | sed -n 's/^serial=\(.*\)$/\1/p') + + # Check if an alias with the CN already exists in the keystore + ALIAS=$CN + if keytool -list -keystore "$JRE_CACERTS_PATH" -storepass changeit -alias "$ALIAS" >/dev/null 2>&1; then + # If the CN already exists, append the serial number to the alias + ALIAS="${CN}_${SERIAL}" + fi + + echo "Adding certificate with alias $ALIAS to the JVM truststore" + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done + done + + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + cp -La /certificates/* /usr/local/share/ca-certificates/ + fi + update-ca-certificates + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi +fi + +# Let's provide a variable with the correct path for tools that want or need to use it +export JRE_CACERTS_PATH + +exec "$@" diff --git a/17/jdk/alpine/3.23/Dockerfile b/17/jdk/alpine/3.23/Dockerfile new file mode 100644 index 000000000..0d4513069 --- /dev/null +++ b/17/jdk/alpine/3.23/Dockerfile @@ -0,0 +1,93 @@ +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM alpine:3.23 + +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH=$JAVA_HOME/bin:$PATH + +# Default to UTF-8 file.encoding +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8' + +RUN set -eux; \ + apk add --no-cache \ + # java.lang.UnsatisfiedLinkError: libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory + # java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager + # https://github.com/docker-library/openjdk/pull/235#issuecomment-424466077 + fontconfig ttf-dejavu \ + # gnupg required to verify the signature + gnupg \ + # utilities for keeping Alpine and OpenJDK CA certificates in sync + # https://github.com/adoptium/containers/issues/293 + ca-certificates p11-kit-trust \ + # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 + musl-locales musl-locales-lang \ + # jlink --strip-debug on 13+ needs objcopy: https://github.com/docker-library/openjdk/issues/351 + # Error: java.io.IOException: Cannot run program "objcopy": error=2, No such file or directory + binutils \ + tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ + ; \ + rm -rf /var/cache/apk/* + +ENV JAVA_VERSION=jdk-17.0.17+10 + +RUN set -eux; \ + ARCH="$(apk --print-arch)"; \ + case "${ARCH}" in \ + x86_64) \ + ESUM='4dfea527f66034c5b6f4ca26afe692ae292fd267fd3b295c7f54f6461c65fd33'; \ + BINARY_URL='https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.17%2B10/OpenJDK17U-jdk_x64_alpine-linux_hotspot_17.0.17_10.tar.gz'; \ + ;; \ + *) \ + echo "Unsupported arch: ${ARCH}"; \ + exit 1; \ + ;; \ + esac; \ + wget -O /tmp/openjdk.tar.gz ${BINARY_URL}; \ + wget -O /tmp/openjdk.tar.gz.sig ${BINARY_URL}.sig; \ + export GNUPGHOME="$(mktemp -d)"; \ + # gpg: key 843C48A565F8F04B: "Adoptium GPG Key (DEB/RPM Signing Key) " imported + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 3B04D753C9050D9A5D343F39843C48A565F8F04B; \ + gpg --batch --verify /tmp/openjdk.tar.gz.sig /tmp/openjdk.tar.gz; \ + rm -rf "${GNUPGHOME}" /tmp/openjdk.tar.gz.sig; \ + echo "${ESUM} */tmp/openjdk.tar.gz" | sha256sum -c -; \ + mkdir -p "$JAVA_HOME"; \ + tar --extract \ + --file /tmp/openjdk.tar.gz \ + --directory "$JAVA_HOME" \ + --strip-components 1 \ + --no-same-owner \ + ; \ + rm -f /tmp/openjdk.tar.gz ${JAVA_HOME}/lib/src.zip; + +RUN set -eux; \ + echo "Verifying install ..."; \ + fileEncoding="$(echo 'System.out.println(System.getProperty("file.encoding"))' | jshell -s -)"; [ "$fileEncoding" = 'UTF-8' ]; rm -rf ~/.java; \ + echo "javac --version"; javac --version; \ + echo "java --version"; java --version; \ + echo "Complete." +COPY --chmod=755 entrypoint.sh /__cacert_entrypoint.sh +ENTRYPOINT ["/__cacert_entrypoint.sh"] + +CMD ["jshell"] diff --git a/17/jdk/alpine/3.23/entrypoint.sh b/17/jdk/alpine/3.23/entrypoint.sh new file mode 100644 index 000000000..7822fe589 --- /dev/null +++ b/17/jdk/alpine/3.23/entrypoint.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env sh +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. + +set -e + +TMPDIR=${TMPDIR:-/tmp} + +# JDK truststore location +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts + +# Opt-in is only activated if the environment variable is set +if [ -n "$USE_SYSTEM_CA_CERTS" ]; then + + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." + exit 1 + fi + + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$JRE_CACERTS_PATH" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" + fi + + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Extract the Common Name (CN) and Serial Number from the certificate + CN=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + SERIAL=$(openssl x509 -in "$crt" -noout -serial | sed -n 's/^serial=\(.*\)$/\1/p') + + # Check if an alias with the CN already exists in the keystore + ALIAS=$CN + if keytool -list -keystore "$JRE_CACERTS_PATH" -storepass changeit -alias "$ALIAS" >/dev/null 2>&1; then + # If the CN already exists, append the serial number to the alias + ALIAS="${CN}_${SERIAL}" + fi + + echo "Adding certificate with alias $ALIAS to the JVM truststore" + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done + done + + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + cp -La /certificates/* /usr/local/share/ca-certificates/ + fi + update-ca-certificates + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi +fi + +# Let's provide a variable with the correct path for tools that want or need to use it +export JRE_CACERTS_PATH + +exec "$@" diff --git a/17/jre/alpine/3.23/Dockerfile b/17/jre/alpine/3.23/Dockerfile new file mode 100644 index 000000000..ada4d6e81 --- /dev/null +++ b/17/jre/alpine/3.23/Dockerfile @@ -0,0 +1,86 @@ +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM alpine:3.23 + +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH=$JAVA_HOME/bin:$PATH + +# Default to UTF-8 file.encoding +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8' + +RUN set -eux; \ + apk add --no-cache \ + # java.lang.UnsatisfiedLinkError: libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory + # java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager + # https://github.com/docker-library/openjdk/pull/235#issuecomment-424466077 + fontconfig ttf-dejavu \ + # gnupg required to verify the signature + gnupg \ + # utilities for keeping Alpine and OpenJDK CA certificates in sync + # https://github.com/adoptium/containers/issues/293 + ca-certificates p11-kit-trust \ + # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 + musl-locales musl-locales-lang \ + tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ + ; \ + rm -rf /var/cache/apk/* + +ENV JAVA_VERSION=jdk-17.0.17+10 + +RUN set -eux; \ + ARCH="$(apk --print-arch)"; \ + case "${ARCH}" in \ + x86_64) \ + ESUM='6c3047e8edd3878e8d2a1cee95c04606042c6a55954ad365d20b58f88cc9ecd5'; \ + BINARY_URL='https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.17%2B10/OpenJDK17U-jre_x64_alpine-linux_hotspot_17.0.17_10.tar.gz'; \ + ;; \ + *) \ + echo "Unsupported arch: ${ARCH}"; \ + exit 1; \ + ;; \ + esac; \ + wget -O /tmp/openjdk.tar.gz ${BINARY_URL}; \ + wget -O /tmp/openjdk.tar.gz.sig ${BINARY_URL}.sig; \ + export GNUPGHOME="$(mktemp -d)"; \ + # gpg: key 843C48A565F8F04B: "Adoptium GPG Key (DEB/RPM Signing Key) " imported + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 3B04D753C9050D9A5D343F39843C48A565F8F04B; \ + gpg --batch --verify /tmp/openjdk.tar.gz.sig /tmp/openjdk.tar.gz; \ + rm -rf "${GNUPGHOME}" /tmp/openjdk.tar.gz.sig; \ + echo "${ESUM} */tmp/openjdk.tar.gz" | sha256sum -c -; \ + mkdir -p "$JAVA_HOME"; \ + tar --extract \ + --file /tmp/openjdk.tar.gz \ + --directory "$JAVA_HOME" \ + --strip-components 1 \ + --no-same-owner \ + ; \ + rm -f /tmp/openjdk.tar.gz; + +RUN set -eux; \ + echo "Verifying install ..."; \ + echo "java --version"; java --version; \ + echo "Complete." +COPY --chmod=755 entrypoint.sh /__cacert_entrypoint.sh +ENTRYPOINT ["/__cacert_entrypoint.sh"] diff --git a/17/jre/alpine/3.23/entrypoint.sh b/17/jre/alpine/3.23/entrypoint.sh new file mode 100644 index 000000000..7822fe589 --- /dev/null +++ b/17/jre/alpine/3.23/entrypoint.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env sh +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. + +set -e + +TMPDIR=${TMPDIR:-/tmp} + +# JDK truststore location +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts + +# Opt-in is only activated if the environment variable is set +if [ -n "$USE_SYSTEM_CA_CERTS" ]; then + + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." + exit 1 + fi + + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$JRE_CACERTS_PATH" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" + fi + + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Extract the Common Name (CN) and Serial Number from the certificate + CN=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + SERIAL=$(openssl x509 -in "$crt" -noout -serial | sed -n 's/^serial=\(.*\)$/\1/p') + + # Check if an alias with the CN already exists in the keystore + ALIAS=$CN + if keytool -list -keystore "$JRE_CACERTS_PATH" -storepass changeit -alias "$ALIAS" >/dev/null 2>&1; then + # If the CN already exists, append the serial number to the alias + ALIAS="${CN}_${SERIAL}" + fi + + echo "Adding certificate with alias $ALIAS to the JVM truststore" + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done + done + + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + cp -La /certificates/* /usr/local/share/ca-certificates/ + fi + update-ca-certificates + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi +fi + +# Let's provide a variable with the correct path for tools that want or need to use it +export JRE_CACERTS_PATH + +exec "$@" diff --git a/21/jdk/alpine/3.23/Dockerfile b/21/jdk/alpine/3.23/Dockerfile new file mode 100644 index 000000000..1445ecdcb --- /dev/null +++ b/21/jdk/alpine/3.23/Dockerfile @@ -0,0 +1,97 @@ +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM alpine:3.23 + +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH=$JAVA_HOME/bin:$PATH + +# Default to UTF-8 file.encoding +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8' + +RUN set -eux; \ + apk add --no-cache \ + # java.lang.UnsatisfiedLinkError: libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory + # java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager + # https://github.com/docker-library/openjdk/pull/235#issuecomment-424466077 + fontconfig ttf-dejavu \ + # gnupg required to verify the signature + gnupg \ + # utilities for keeping Alpine and OpenJDK CA certificates in sync + # https://github.com/adoptium/containers/issues/293 + ca-certificates p11-kit-trust \ + # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 + musl-locales musl-locales-lang \ + # jlink --strip-debug on 13+ needs objcopy: https://github.com/docker-library/openjdk/issues/351 + # Error: java.io.IOException: Cannot run program "objcopy": error=2, No such file or directory + binutils \ + tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ + ; \ + rm -rf /var/cache/apk/* + +ENV JAVA_VERSION=jdk-21.0.9+10 + +RUN set -eux; \ + ARCH="$(apk --print-arch)"; \ + case "${ARCH}" in \ + aarch64) \ + ESUM='6d3c2b956d6b837bfdc992e58488fb16c96e5852820e9feaa42a8672bbca9c7b'; \ + BINARY_URL='https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.9%2B10/OpenJDK21U-jdk_aarch64_alpine-linux_hotspot_21.0.9_10.tar.gz'; \ + ;; \ + x86_64) \ + ESUM='52e30d3157432e87ee464b656f776f0a22946f1f3182eea779258284bc6f55da'; \ + BINARY_URL='https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.9%2B10/OpenJDK21U-jdk_x64_alpine-linux_hotspot_21.0.9_10.tar.gz'; \ + ;; \ + *) \ + echo "Unsupported arch: ${ARCH}"; \ + exit 1; \ + ;; \ + esac; \ + wget -O /tmp/openjdk.tar.gz ${BINARY_URL}; \ + wget -O /tmp/openjdk.tar.gz.sig ${BINARY_URL}.sig; \ + export GNUPGHOME="$(mktemp -d)"; \ + # gpg: key 843C48A565F8F04B: "Adoptium GPG Key (DEB/RPM Signing Key) " imported + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 3B04D753C9050D9A5D343F39843C48A565F8F04B; \ + gpg --batch --verify /tmp/openjdk.tar.gz.sig /tmp/openjdk.tar.gz; \ + rm -rf "${GNUPGHOME}" /tmp/openjdk.tar.gz.sig; \ + echo "${ESUM} */tmp/openjdk.tar.gz" | sha256sum -c -; \ + mkdir -p "$JAVA_HOME"; \ + tar --extract \ + --file /tmp/openjdk.tar.gz \ + --directory "$JAVA_HOME" \ + --strip-components 1 \ + --no-same-owner \ + ; \ + rm -f /tmp/openjdk.tar.gz ${JAVA_HOME}/lib/src.zip; + +RUN set -eux; \ + echo "Verifying install ..."; \ + fileEncoding="$(echo 'System.out.println(System.getProperty("file.encoding"))' | jshell -s -)"; [ "$fileEncoding" = 'UTF-8' ]; rm -rf ~/.java; \ + echo "javac --version"; javac --version; \ + echo "java --version"; java --version; \ + echo "Complete." +COPY --chmod=755 entrypoint.sh /__cacert_entrypoint.sh +ENTRYPOINT ["/__cacert_entrypoint.sh"] + +CMD ["jshell"] diff --git a/21/jdk/alpine/3.23/entrypoint.sh b/21/jdk/alpine/3.23/entrypoint.sh new file mode 100644 index 000000000..7822fe589 --- /dev/null +++ b/21/jdk/alpine/3.23/entrypoint.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env sh +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. + +set -e + +TMPDIR=${TMPDIR:-/tmp} + +# JDK truststore location +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts + +# Opt-in is only activated if the environment variable is set +if [ -n "$USE_SYSTEM_CA_CERTS" ]; then + + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." + exit 1 + fi + + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$JRE_CACERTS_PATH" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" + fi + + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Extract the Common Name (CN) and Serial Number from the certificate + CN=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + SERIAL=$(openssl x509 -in "$crt" -noout -serial | sed -n 's/^serial=\(.*\)$/\1/p') + + # Check if an alias with the CN already exists in the keystore + ALIAS=$CN + if keytool -list -keystore "$JRE_CACERTS_PATH" -storepass changeit -alias "$ALIAS" >/dev/null 2>&1; then + # If the CN already exists, append the serial number to the alias + ALIAS="${CN}_${SERIAL}" + fi + + echo "Adding certificate with alias $ALIAS to the JVM truststore" + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done + done + + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + cp -La /certificates/* /usr/local/share/ca-certificates/ + fi + update-ca-certificates + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi +fi + +# Let's provide a variable with the correct path for tools that want or need to use it +export JRE_CACERTS_PATH + +exec "$@" diff --git a/21/jre/alpine/3.23/Dockerfile b/21/jre/alpine/3.23/Dockerfile new file mode 100644 index 000000000..507e078b6 --- /dev/null +++ b/21/jre/alpine/3.23/Dockerfile @@ -0,0 +1,90 @@ +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM alpine:3.23 + +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH=$JAVA_HOME/bin:$PATH + +# Default to UTF-8 file.encoding +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8' + +RUN set -eux; \ + apk add --no-cache \ + # java.lang.UnsatisfiedLinkError: libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory + # java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager + # https://github.com/docker-library/openjdk/pull/235#issuecomment-424466077 + fontconfig ttf-dejavu \ + # gnupg required to verify the signature + gnupg \ + # utilities for keeping Alpine and OpenJDK CA certificates in sync + # https://github.com/adoptium/containers/issues/293 + ca-certificates p11-kit-trust \ + # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 + musl-locales musl-locales-lang \ + tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ + ; \ + rm -rf /var/cache/apk/* + +ENV JAVA_VERSION=jdk-21.0.9+10 + +RUN set -eux; \ + ARCH="$(apk --print-arch)"; \ + case "${ARCH}" in \ + aarch64) \ + ESUM='7f8c230ba505b418e4288e2b34758a6e4da32470944740e5ba0cfaae02271c22'; \ + BINARY_URL='https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.9%2B10/OpenJDK21U-jre_aarch64_alpine-linux_hotspot_21.0.9_10.tar.gz'; \ + ;; \ + x86_64) \ + ESUM='17aca4ecc1600f70ec88ea0f8bf3a06ba6806bdae8c96d03c07683c800f0d4e8'; \ + BINARY_URL='https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.9%2B10/OpenJDK21U-jre_x64_alpine-linux_hotspot_21.0.9_10.tar.gz'; \ + ;; \ + *) \ + echo "Unsupported arch: ${ARCH}"; \ + exit 1; \ + ;; \ + esac; \ + wget -O /tmp/openjdk.tar.gz ${BINARY_URL}; \ + wget -O /tmp/openjdk.tar.gz.sig ${BINARY_URL}.sig; \ + export GNUPGHOME="$(mktemp -d)"; \ + # gpg: key 843C48A565F8F04B: "Adoptium GPG Key (DEB/RPM Signing Key) " imported + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 3B04D753C9050D9A5D343F39843C48A565F8F04B; \ + gpg --batch --verify /tmp/openjdk.tar.gz.sig /tmp/openjdk.tar.gz; \ + rm -rf "${GNUPGHOME}" /tmp/openjdk.tar.gz.sig; \ + echo "${ESUM} */tmp/openjdk.tar.gz" | sha256sum -c -; \ + mkdir -p "$JAVA_HOME"; \ + tar --extract \ + --file /tmp/openjdk.tar.gz \ + --directory "$JAVA_HOME" \ + --strip-components 1 \ + --no-same-owner \ + ; \ + rm -f /tmp/openjdk.tar.gz; + +RUN set -eux; \ + echo "Verifying install ..."; \ + echo "java --version"; java --version; \ + echo "Complete." +COPY --chmod=755 entrypoint.sh /__cacert_entrypoint.sh +ENTRYPOINT ["/__cacert_entrypoint.sh"] diff --git a/21/jre/alpine/3.23/entrypoint.sh b/21/jre/alpine/3.23/entrypoint.sh new file mode 100644 index 000000000..7822fe589 --- /dev/null +++ b/21/jre/alpine/3.23/entrypoint.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env sh +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. + +set -e + +TMPDIR=${TMPDIR:-/tmp} + +# JDK truststore location +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts + +# Opt-in is only activated if the environment variable is set +if [ -n "$USE_SYSTEM_CA_CERTS" ]; then + + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." + exit 1 + fi + + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$JRE_CACERTS_PATH" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" + fi + + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Extract the Common Name (CN) and Serial Number from the certificate + CN=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + SERIAL=$(openssl x509 -in "$crt" -noout -serial | sed -n 's/^serial=\(.*\)$/\1/p') + + # Check if an alias with the CN already exists in the keystore + ALIAS=$CN + if keytool -list -keystore "$JRE_CACERTS_PATH" -storepass changeit -alias "$ALIAS" >/dev/null 2>&1; then + # If the CN already exists, append the serial number to the alias + ALIAS="${CN}_${SERIAL}" + fi + + echo "Adding certificate with alias $ALIAS to the JVM truststore" + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done + done + + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + cp -La /certificates/* /usr/local/share/ca-certificates/ + fi + update-ca-certificates + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi +fi + +# Let's provide a variable with the correct path for tools that want or need to use it +export JRE_CACERTS_PATH + +exec "$@" diff --git a/25/jdk/alpine/3.23/Dockerfile b/25/jdk/alpine/3.23/Dockerfile new file mode 100644 index 000000000..343e5e1e6 --- /dev/null +++ b/25/jdk/alpine/3.23/Dockerfile @@ -0,0 +1,97 @@ +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM alpine:3.23 + +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH=$JAVA_HOME/bin:$PATH + +# Default to UTF-8 file.encoding +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8' + +RUN set -eux; \ + apk add --no-cache \ + # java.lang.UnsatisfiedLinkError: libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory + # java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager + # https://github.com/docker-library/openjdk/pull/235#issuecomment-424466077 + fontconfig ttf-dejavu \ + # utilities for keeping Alpine and OpenJDK CA certificates in sync + # https://github.com/adoptium/containers/issues/293 + ca-certificates p11-kit-trust \ + # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 + musl-locales musl-locales-lang \ + # jlink --strip-debug on 13+ needs objcopy: https://github.com/docker-library/openjdk/issues/351 + # Error: java.io.IOException: Cannot run program "objcopy": error=2, No such file or directory + binutils \ + tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ + ; \ + rm -rf /var/cache/apk/* + +ENV JAVA_VERSION=jdk-25.0.1+8 + +RUN set -eux; \ + ARCH="$(apk --print-arch)"; \ + case "${ARCH}" in \ + aarch64) \ + ESUM='e95584c7fb7d4020003b325d5c3af9c29dde514571da362aac04586a88f2d728'; \ + BINARY_URL='https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25.0.1%2B8/OpenJDK25U-jdk_aarch64_alpine-linux_hotspot_25.0.1_8.tar.gz'; \ + ;; \ + x86_64) \ + ESUM='375a1f22ef1a488737330ea10bbc7418a1a49c5d0df36d4f59d18fd82fc63593'; \ + BINARY_URL='https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25.0.1%2B8/OpenJDK25U-jdk_x64_alpine-linux_hotspot_25.0.1_8.tar.gz'; \ + ;; \ + *) \ + echo "Unsupported arch: ${ARCH}"; \ + exit 1; \ + ;; \ + esac; \ + apk add --no-cache --virtual .fetch-deps gnupg; \ + wget -O /tmp/openjdk.tar.gz ${BINARY_URL}; \ + wget -O /tmp/openjdk.tar.gz.sig ${BINARY_URL}.sig; \ + export GNUPGHOME="$(mktemp -d)"; \ + # gpg: key 843C48A565F8F04B: "Adoptium GPG Key (DEB/RPM Signing Key) " imported + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 3B04D753C9050D9A5D343F39843C48A565F8F04B; \ + gpg --batch --verify /tmp/openjdk.tar.gz.sig /tmp/openjdk.tar.gz; \ + rm -rf "${GNUPGHOME}" /tmp/openjdk.tar.gz.sig; \ + echo "${ESUM} */tmp/openjdk.tar.gz" | sha256sum -c -; \ + mkdir -p "$JAVA_HOME"; \ + tar --extract \ + --file /tmp/openjdk.tar.gz \ + --directory "$JAVA_HOME" \ + --strip-components 1 \ + --no-same-owner \ + ; \ + rm -f /tmp/openjdk.tar.gz ${JAVA_HOME}/lib/src.zip; \ + apk del --no-network .fetch-deps; + +RUN set -eux; \ + echo "Verifying install ..."; \ + fileEncoding="$(echo 'System.out.println(System.getProperty("file.encoding"))' | jshell -s -)"; [ "$fileEncoding" = 'UTF-8' ]; rm -rf ~/.java; \ + echo "javac --version"; javac --version; \ + echo "java --version"; java --version; \ + echo "Complete." +COPY --chmod=755 entrypoint.sh /__cacert_entrypoint.sh +ENTRYPOINT ["/__cacert_entrypoint.sh"] + +CMD ["jshell"] diff --git a/25/jdk/alpine/3.23/entrypoint.sh b/25/jdk/alpine/3.23/entrypoint.sh new file mode 100644 index 000000000..7822fe589 --- /dev/null +++ b/25/jdk/alpine/3.23/entrypoint.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env sh +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. + +set -e + +TMPDIR=${TMPDIR:-/tmp} + +# JDK truststore location +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts + +# Opt-in is only activated if the environment variable is set +if [ -n "$USE_SYSTEM_CA_CERTS" ]; then + + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." + exit 1 + fi + + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$JRE_CACERTS_PATH" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" + fi + + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Extract the Common Name (CN) and Serial Number from the certificate + CN=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + SERIAL=$(openssl x509 -in "$crt" -noout -serial | sed -n 's/^serial=\(.*\)$/\1/p') + + # Check if an alias with the CN already exists in the keystore + ALIAS=$CN + if keytool -list -keystore "$JRE_CACERTS_PATH" -storepass changeit -alias "$ALIAS" >/dev/null 2>&1; then + # If the CN already exists, append the serial number to the alias + ALIAS="${CN}_${SERIAL}" + fi + + echo "Adding certificate with alias $ALIAS to the JVM truststore" + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done + done + + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + cp -La /certificates/* /usr/local/share/ca-certificates/ + fi + update-ca-certificates + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi +fi + +# Let's provide a variable with the correct path for tools that want or need to use it +export JRE_CACERTS_PATH + +exec "$@" diff --git a/25/jre/alpine/3.23/Dockerfile b/25/jre/alpine/3.23/Dockerfile new file mode 100644 index 000000000..323eb7ff4 --- /dev/null +++ b/25/jre/alpine/3.23/Dockerfile @@ -0,0 +1,90 @@ +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM alpine:3.23 + +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH=$JAVA_HOME/bin:$PATH + +# Default to UTF-8 file.encoding +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8' + +RUN set -eux; \ + apk add --no-cache \ + # java.lang.UnsatisfiedLinkError: libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory + # java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager + # https://github.com/docker-library/openjdk/pull/235#issuecomment-424466077 + fontconfig ttf-dejavu \ + # utilities for keeping Alpine and OpenJDK CA certificates in sync + # https://github.com/adoptium/containers/issues/293 + ca-certificates p11-kit-trust \ + # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 + musl-locales musl-locales-lang \ + tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ + ; \ + rm -rf /var/cache/apk/* + +ENV JAVA_VERSION=jdk-25.0.1+8 + +RUN set -eux; \ + ARCH="$(apk --print-arch)"; \ + case "${ARCH}" in \ + aarch64) \ + ESUM='0176d4b18047ce6669c451e7293998961340a6720e979adfbfefb7356d21d597'; \ + BINARY_URL='https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25.0.1%2B8/OpenJDK25U-jre_aarch64_alpine-linux_hotspot_25.0.1_8.tar.gz'; \ + ;; \ + x86_64) \ + ESUM='46a7eca285957dadb0adacd96fe385bc5512f31b7f90a3dd01f04679d614a420'; \ + BINARY_URL='https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25.0.1%2B8/OpenJDK25U-jre_x64_alpine-linux_hotspot_25.0.1_8.tar.gz'; \ + ;; \ + *) \ + echo "Unsupported arch: ${ARCH}"; \ + exit 1; \ + ;; \ + esac; \ + apk add --no-cache --virtual .fetch-deps gnupg; \ + wget -O /tmp/openjdk.tar.gz ${BINARY_URL}; \ + wget -O /tmp/openjdk.tar.gz.sig ${BINARY_URL}.sig; \ + export GNUPGHOME="$(mktemp -d)"; \ + # gpg: key 843C48A565F8F04B: "Adoptium GPG Key (DEB/RPM Signing Key) " imported + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 3B04D753C9050D9A5D343F39843C48A565F8F04B; \ + gpg --batch --verify /tmp/openjdk.tar.gz.sig /tmp/openjdk.tar.gz; \ + rm -rf "${GNUPGHOME}" /tmp/openjdk.tar.gz.sig; \ + echo "${ESUM} */tmp/openjdk.tar.gz" | sha256sum -c -; \ + mkdir -p "$JAVA_HOME"; \ + tar --extract \ + --file /tmp/openjdk.tar.gz \ + --directory "$JAVA_HOME" \ + --strip-components 1 \ + --no-same-owner \ + ; \ + rm -f /tmp/openjdk.tar.gz; \ + apk del --no-network .fetch-deps; + +RUN set -eux; \ + echo "Verifying install ..."; \ + echo "java --version"; java --version; \ + echo "Complete." +COPY --chmod=755 entrypoint.sh /__cacert_entrypoint.sh +ENTRYPOINT ["/__cacert_entrypoint.sh"] diff --git a/25/jre/alpine/3.23/entrypoint.sh b/25/jre/alpine/3.23/entrypoint.sh new file mode 100644 index 000000000..7822fe589 --- /dev/null +++ b/25/jre/alpine/3.23/entrypoint.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env sh +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. + +set -e + +TMPDIR=${TMPDIR:-/tmp} + +# JDK truststore location +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts + +# Opt-in is only activated if the environment variable is set +if [ -n "$USE_SYSTEM_CA_CERTS" ]; then + + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." + exit 1 + fi + + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$JRE_CACERTS_PATH" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" + fi + + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Extract the Common Name (CN) and Serial Number from the certificate + CN=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + SERIAL=$(openssl x509 -in "$crt" -noout -serial | sed -n 's/^serial=\(.*\)$/\1/p') + + # Check if an alias with the CN already exists in the keystore + ALIAS=$CN + if keytool -list -keystore "$JRE_CACERTS_PATH" -storepass changeit -alias "$ALIAS" >/dev/null 2>&1; then + # If the CN already exists, append the serial number to the alias + ALIAS="${CN}_${SERIAL}" + fi + + echo "Adding certificate with alias $ALIAS to the JVM truststore" + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done + done + + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + cp -La /certificates/* /usr/local/share/ca-certificates/ + fi + update-ca-certificates + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi +fi + +# Let's provide a variable with the correct path for tools that want or need to use it +export JRE_CACERTS_PATH + +exec "$@" diff --git a/8/jdk/alpine/3.23/Dockerfile b/8/jdk/alpine/3.23/Dockerfile new file mode 100644 index 000000000..fba1774a9 --- /dev/null +++ b/8/jdk/alpine/3.23/Dockerfile @@ -0,0 +1,87 @@ +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM alpine:3.23 + +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH=$JAVA_HOME/bin:$PATH + +# Default to UTF-8 file.encoding +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8' + +RUN set -eux; \ + apk add --no-cache \ + # java.lang.UnsatisfiedLinkError: libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory + # java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager + # https://github.com/docker-library/openjdk/pull/235#issuecomment-424466077 + fontconfig ttf-dejavu \ + # gnupg required to verify the signature + gnupg \ + # utilities for keeping Alpine and OpenJDK CA certificates in sync + # https://github.com/adoptium/containers/issues/293 + ca-certificates p11-kit-trust \ + # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 + musl-locales musl-locales-lang \ + tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ + ; \ + rm -rf /var/cache/apk/* + +ENV JAVA_VERSION=jdk8u472-b08 + +RUN set -eux; \ + ARCH="$(apk --print-arch)"; \ + case "${ARCH}" in \ + x86_64) \ + ESUM='2ded87ce3a1f912ac7263f7df526fb0a2ccbc09a2a0124e0b35e22c3decb9bc5'; \ + BINARY_URL='https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u472-b08/OpenJDK8U-jdk_x64_alpine-linux_hotspot_8u472b08.tar.gz'; \ + ;; \ + *) \ + echo "Unsupported arch: ${ARCH}"; \ + exit 1; \ + ;; \ + esac; \ + wget -O /tmp/openjdk.tar.gz ${BINARY_URL}; \ + wget -O /tmp/openjdk.tar.gz.sig ${BINARY_URL}.sig; \ + export GNUPGHOME="$(mktemp -d)"; \ + # gpg: key 843C48A565F8F04B: "Adoptium GPG Key (DEB/RPM Signing Key) " imported + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 3B04D753C9050D9A5D343F39843C48A565F8F04B; \ + gpg --batch --verify /tmp/openjdk.tar.gz.sig /tmp/openjdk.tar.gz; \ + rm -rf "${GNUPGHOME}" /tmp/openjdk.tar.gz.sig; \ + echo "${ESUM} */tmp/openjdk.tar.gz" | sha256sum -c -; \ + mkdir -p "$JAVA_HOME"; \ + tar --extract \ + --file /tmp/openjdk.tar.gz \ + --directory "$JAVA_HOME" \ + --strip-components 1 \ + --no-same-owner \ + ; \ + rm -f /tmp/openjdk.tar.gz ${JAVA_HOME}/src.zip; + +RUN set -eux; \ + echo "Verifying install ..."; \ + echo "javac -version"; javac -version; \ + echo "java -version"; java -version; \ + echo "Complete." +COPY --chmod=755 entrypoint.sh /__cacert_entrypoint.sh +ENTRYPOINT ["/__cacert_entrypoint.sh"] diff --git a/8/jdk/alpine/3.23/entrypoint.sh b/8/jdk/alpine/3.23/entrypoint.sh new file mode 100644 index 000000000..59c24f493 --- /dev/null +++ b/8/jdk/alpine/3.23/entrypoint.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env sh +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. + +set -e + +TMPDIR=${TMPDIR:-/tmp} + +# JDK truststore location +# JDK8 puts its JRE in a subdirectory +JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts + +# Opt-in is only activated if the environment variable is set +if [ -n "$USE_SYSTEM_CA_CERTS" ]; then + + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." + exit 1 + fi + + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$JRE_CACERTS_PATH" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" + fi + + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Extract the Common Name (CN) and Serial Number from the certificate + CN=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + SERIAL=$(openssl x509 -in "$crt" -noout -serial | sed -n 's/^serial=\(.*\)$/\1/p') + + # Check if an alias with the CN already exists in the keystore + ALIAS=$CN + if keytool -list -keystore "$JRE_CACERTS_PATH" -storepass changeit -alias "$ALIAS" >/dev/null 2>&1; then + # If the CN already exists, append the serial number to the alias + ALIAS="${CN}_${SERIAL}" + fi + + echo "Adding certificate with alias $ALIAS to the JVM truststore" + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done + done + + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + cp -La /certificates/* /usr/local/share/ca-certificates/ + fi + update-ca-certificates + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi +fi + +# Let's provide a variable with the correct path for tools that want or need to use it +export JRE_CACERTS_PATH + +exec "$@" diff --git a/8/jre/alpine/3.23/Dockerfile b/8/jre/alpine/3.23/Dockerfile new file mode 100644 index 000000000..d60c8372b --- /dev/null +++ b/8/jre/alpine/3.23/Dockerfile @@ -0,0 +1,86 @@ +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM alpine:3.23 + +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH=$JAVA_HOME/bin:$PATH + +# Default to UTF-8 file.encoding +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8' + +RUN set -eux; \ + apk add --no-cache \ + # java.lang.UnsatisfiedLinkError: libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory + # java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager + # https://github.com/docker-library/openjdk/pull/235#issuecomment-424466077 + fontconfig ttf-dejavu \ + # gnupg required to verify the signature + gnupg \ + # utilities for keeping Alpine and OpenJDK CA certificates in sync + # https://github.com/adoptium/containers/issues/293 + ca-certificates p11-kit-trust \ + # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 + musl-locales musl-locales-lang \ + tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ + ; \ + rm -rf /var/cache/apk/* + +ENV JAVA_VERSION=jdk8u472-b08 + +RUN set -eux; \ + ARCH="$(apk --print-arch)"; \ + case "${ARCH}" in \ + x86_64) \ + ESUM='0f169a177121cfd09b43ec5898770717482d02483f07b1b92a2e930dfd32fdb8'; \ + BINARY_URL='https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u472-b08/OpenJDK8U-jre_x64_alpine-linux_hotspot_8u472b08.tar.gz'; \ + ;; \ + *) \ + echo "Unsupported arch: ${ARCH}"; \ + exit 1; \ + ;; \ + esac; \ + wget -O /tmp/openjdk.tar.gz ${BINARY_URL}; \ + wget -O /tmp/openjdk.tar.gz.sig ${BINARY_URL}.sig; \ + export GNUPGHOME="$(mktemp -d)"; \ + # gpg: key 843C48A565F8F04B: "Adoptium GPG Key (DEB/RPM Signing Key) " imported + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 3B04D753C9050D9A5D343F39843C48A565F8F04B; \ + gpg --batch --verify /tmp/openjdk.tar.gz.sig /tmp/openjdk.tar.gz; \ + rm -rf "${GNUPGHOME}" /tmp/openjdk.tar.gz.sig; \ + echo "${ESUM} */tmp/openjdk.tar.gz" | sha256sum -c -; \ + mkdir -p "$JAVA_HOME"; \ + tar --extract \ + --file /tmp/openjdk.tar.gz \ + --directory "$JAVA_HOME" \ + --strip-components 1 \ + --no-same-owner \ + ; \ + rm -f /tmp/openjdk.tar.gz; + +RUN set -eux; \ + echo "Verifying install ..."; \ + echo "java -version"; java -version; \ + echo "Complete." +COPY --chmod=755 entrypoint.sh /__cacert_entrypoint.sh +ENTRYPOINT ["/__cacert_entrypoint.sh"] diff --git a/8/jre/alpine/3.23/entrypoint.sh b/8/jre/alpine/3.23/entrypoint.sh new file mode 100644 index 000000000..7822fe589 --- /dev/null +++ b/8/jre/alpine/3.23/entrypoint.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env sh +# ------------------------------------------------------------------------------ +# NOTE: THIS FILE IS GENERATED VIA "generate_dockerfiles.py" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# ------------------------------------------------------------------------------ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. + +set -e + +TMPDIR=${TMPDIR:-/tmp} + +# JDK truststore location +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts + +# Opt-in is only activated if the environment variable is set +if [ -n "$USE_SYSTEM_CA_CERTS" ]; then + + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." + exit 1 + fi + + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$JRE_CACERTS_PATH" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" + fi + + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Extract the Common Name (CN) and Serial Number from the certificate + CN=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + SERIAL=$(openssl x509 -in "$crt" -noout -serial | sed -n 's/^serial=\(.*\)$/\1/p') + + # Check if an alias with the CN already exists in the keystore + ALIAS=$CN + if keytool -list -keystore "$JRE_CACERTS_PATH" -storepass changeit -alias "$ALIAS" >/dev/null 2>&1; then + # If the CN already exists, append the serial number to the alias + ALIAS="${CN}_${SERIAL}" + fi + + echo "Adding certificate with alias $ALIAS to the JVM truststore" + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done + done + + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + cp -La /certificates/* /usr/local/share/ca-certificates/ + fi + update-ca-certificates + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi +fi + +# Let's provide a variable with the correct path for tools that want or need to use it +export JRE_CACERTS_PATH + +exec "$@"