fix: Get Java from GitHub release artifacts directly (#27862)

What are we solving here?

1. Installing Java in the `Dockerfile` by using Adoptium's package
repositories is fragile since they've started blocking some IP addresses
used by GitHub Actions runners. We see a message like this:
   ```
Failed to fetch
https://packages.adoptium.net/artifactory/deb/pool/main/t/temurin-17/temurin-17-jdk_17.0.8.1.0+1_amd64.deb
403 Forbidden [IP: 146.75.107.42 443]
   ```
We're seeing more and more cases of these and PRs are getting blocked.

2. Installing Java via `apt` also installs other packages like X11
libraries, that aren't really relevant to our usage of Java. Yet, these
packages are present in our Docker image, and are the source of several
CVEs to be reported by scanners on our Docker image.

3. This will give us control over trusted CA certificates, which we can
now perform under `$TMP`, which aligns with our move towards supporting
readonly root filesystem. Which is essentially not write to anything in
the Docker image at runtime, except for under `/tmp` and
`/appsmith-stacks`. This will help us move in that direction.
This commit is contained in:
Shrikant Sharat Kandula 2023-10-06 19:38:19 +05:30 committed by GitHub
parent 22e10c6fdb
commit 53bcdafe91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 19 deletions

View File

@ -15,10 +15,7 @@ RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends --yes \
supervisor curl cron nfs-common nginx nginx-extras gnupg wget netcat openssh-client \
gettext \
python3-pip python3-venv git ca-certificates-java \
&& wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | apt-key add - \
&& echo "deb https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list \
&& apt-get update && apt-get install --no-install-recommends --yes temurin-17-jdk \
python3-pip python3-venv git ca-certificates \
&& pip install --no-cache-dir git+https://github.com/coderanger/supervisor-stdout@973ba19967cdaf46d9c1634d1675fc65b9574f6e \
&& python3 -m venv --prompt certbot /opt/certbot/venv \
&& /opt/certbot/venv/bin/pip install --upgrade certbot setuptools pip \
@ -38,6 +35,14 @@ RUN curl --silent --show-error --location https://www.mongodb.org/static/pgp/ser
# This is to get semver 7.5.2, for a CVE fix, might be able to remove it with later versions on NodeJS.
&& npm install -g npm@9.7.2
# Install Java
RUN set -o xtrace \
&& mkdir -p /opt/java \
# Assets from https://github.com/adoptium/temurin17-binaries/releases
&& version="$(curl --write-out '%{redirect_url}' 'https://github.com/adoptium/temurin17-binaries/releases/latest' | sed 's,.*jdk-,,')" \
&& curl --location --output /tmp/java.tar.gz "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-$version/OpenJDK17U-jdk_$(uname -m | sed s/x86_64/x64/)_linux_hotspot_$(echo $version | tr + _).tar.gz" \
&& tar -xzf /tmp/java.tar.gz -C /opt/java --strip-components 1
# Clean up cache file - Service layer
RUN rm -rf \
/root/.cache \
@ -87,8 +92,8 @@ RUN cd ./utils && npm install --only=prod && npm install --only=prod -g . && cd
&& find / \( -path /proc -prune \) -o \( \( -perm -2000 -o -perm -4000 \) -print -exec chmod -s '{}' + \) || true \
&& node prepare-image.mjs
# Update path to load appsmith utils tool as default
ENV PATH /opt/appsmith/utils/node_modules/.bin:$PATH
ENV PATH /opt/appsmith/utils/node_modules/.bin:/opt/java/bin:$PATH
LABEL com.centurylinklabs.watchtower.lifecycle.pre-check=/watchtower-hooks/pre-check.sh
LABEL com.centurylinklabs.watchtower.lifecycle.pre-update=/watchtower-hooks/pre-update.sh

View File

@ -255,6 +255,7 @@ is_empty_directory() {
}
check_setup_custom_ca_certificates() {
# old, deprecated, should be removed.
local stacks_ca_certs_path
stacks_ca_certs_path="$stacks_path/ca-certs"
@ -279,13 +280,42 @@ check_setup_custom_ca_certificates() {
fi
if [[ -n "$(ls "$stacks_ca_certs_path"/*.pem 2>/dev/null)" ]]; then
echo "Looks like you have some '.pem' files in your 'ca-certs' folder. Please rename them to '.crt' to be picked up autatically.".
fi
update-ca-certificates --fresh
}
setup-custom-ca-certificates() (
local stacks_ca_certs_path="$stacks_path/ca-certs"
local store="$TMP/cacerts"
local opts_file="$TMP/java-cacerts-opts"
rm -f "$store" "$opts_file"
if [[ -n "$(ls "$stacks_ca_certs_path"/*.pem 2>/dev/null)" ]]; then
echo "Looks like you have some '.pem' files in your 'ca-certs' folder. Please rename them to '.crt' to be picked up automatically.".
fi
if ! [[ -d "$stacks_ca_certs_path" && "$(find "$stacks_ca_certs_path" -maxdepth 1 -type f -name '*.crt' | wc -l)" -gt 0 ]]; then
echo "No custom CA certificates found."
return
fi
# Import the system CA certificates into the store.
keytool -importkeystore \
-srckeystore /opt/java/lib/security/cacerts \
-destkeystore "$store" \
-srcstorepass changeit \
-deststorepass changeit
# Add the custom CA certificates to the store.
find "$stacks_ca_certs_path" -maxdepth 1 -type f -name '*.crt' \
-exec keytool -import -noprompt -keystore "$store" -file '{}' -storepass changeit ';'
{
echo "-Djavax.net.ssl.trustStore=$store"
echo "-Djavax.net.ssl.trustStorePassword=changeit"
} > "$opts_file"
)
configure_supervisord() {
local supervisord_conf_source="/opt/appsmith/templates/supervisord"
if [[ -n "$(ls -A "$SUPERVISORD_CONF_TARGET")" ]]; then
@ -438,6 +468,8 @@ else
fi
check_setup_custom_ca_certificates
setup-custom-ca-certificates
mount_letsencrypt_directory
check_redis_compatible_page_size

View File

@ -5,7 +5,7 @@ set -o pipefail
set -o nounset
set -o noglob
declare -a proxy_args
declare -a extra_args
proxy_configured=0
match-proxy-url() {
@ -22,23 +22,23 @@ match-proxy-url() {
}
if match-proxy-url "${HTTP_PROXY-}"; then
proxy_args+=(-Dhttp.proxyHost="$proxy_host" -Dhttp.proxyPort="$proxy_port")
extra_args+=(-Dhttp.proxyHost="$proxy_host" -Dhttp.proxyPort="$proxy_port")
if [[ -n $proxy_user ]]; then
proxy_args+=(-Dhttp.proxyUser="$proxy_user")
extra_args+=(-Dhttp.proxyUser="$proxy_user")
fi
if [[ -n $proxy_pass ]]; then
proxy_args+=(-Dhttp.proxyPassword="$proxy_pass")
extra_args+=(-Dhttp.proxyPassword="$proxy_pass")
fi
proxy_configured=1
fi
if match-proxy-url "${HTTPS_PROXY-}"; then
proxy_args+=(-Dhttps.proxyHost="$proxy_host" -Dhttps.proxyPort="$proxy_port")
extra_args+=(-Dhttps.proxyHost="$proxy_host" -Dhttps.proxyPort="$proxy_port")
if [[ -n $proxy_user ]]; then
proxy_args+=(-Dhttps.proxyUser="$proxy_user")
extra_args+=(-Dhttps.proxyUser="$proxy_user")
fi
if [[ -n $proxy_pass ]]; then
proxy_args+=(-Dhttps.proxyPassword="$proxy_pass")
extra_args+=(-Dhttps.proxyPassword="$proxy_pass")
fi
proxy_configured=1
fi
@ -50,7 +50,11 @@ if [[ -z "${NO_PROXY-}" ]]; then
fi
if [[ $proxy_configured == 1 ]]; then
proxy_args+=(-Djava.net.useSystemProxies=true -Dhttp.nonProxyHosts="${NO_PROXY//,/|}")
extra_args+=(-Djava.net.useSystemProxies=true -Dhttp.nonProxyHosts="${NO_PROXY//,/|}")
fi
if [[ -f "$TMP/java-cacerts-opts" ]]; then
extra_args+=("@$TMP/java-cacerts-opts")
fi
# Wait until RTS started and listens on port 8091
@ -69,5 +73,5 @@ exec java ${APPSMITH_JAVA_ARGS:-} ${APPSMITH_JAVA_HEAP_ARG:-} \
-XX:+ShowCodeDetailsInExceptionMessages \
-Djava.security.egd=file:/dev/./urandom \
-Dlog4j2.formatMsgNoLookups=true \
"${proxy_args[@]}" \
"${extra_args[@]}" \
-jar server.jar