Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/actions/core-cicd/maven-job/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,9 @@ runs:
echo "Error: .sdkmanrc file not found and no java-version override provided"
exit 1
fi
# This value is used as the dotcms/java-base docker tag (FROM dotcms/java-base:<tag>),
# which cannot contain '+' - convert SDKMAN's '+' to '-' (e.g. 25.0.4+1-ms -> 25.0.4-1-ms)
SDKMAN_JAVA_VERSION="${SDKMAN_JAVA_VERSION//+/-}"
echo "SDKMAN_JAVA_VERSION=${SDKMAN_JAVA_VERSION}" >> $GITHUB_ENV

- id: build-docker-image-from-archive
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/cicd_comp_deployment-phase.yml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ jobs:
exit 1
fi

# Used as the dotcms/java-base docker tag (FROM dotcms/java-base:<tag>), which
# cannot contain '+' - convert SDKMAN's '+' to '-' (e.g. 25.0.4+1-ms -> 25.0.4-1-ms)
SDKMAN_JAVA_VERSION="${SDKMAN_JAVA_VERSION//+/-}"

{
echo "SDKMAN_JAVA_VERSION=${SDKMAN_JAVA_VERSION}"
echo "raw_suffix=${RAW_SUFFIX}"
Expand Down
12 changes: 10 additions & 2 deletions .github/workflows/cicd_manual_build-java-base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
workflow_dispatch:
inputs:
sdkman_java_version:
description: 'SDKMAN version string run "sdk list java" for options'
description: 'SDKMAN version string run "sdk list java" for options. Docker tags cannot contain +, so the image tag replaces + with - (e.g. 25.0.4+1-ms -> 25.0.4-1-ms)'
required: true
image_suffix:
description: 'append suffix to image tag (can be empty)'
Expand Down Expand Up @@ -49,12 +49,20 @@ jobs:
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Compute Docker Tag
id: docker-tag
run: |
# Docker tags cannot contain '+' - convert SDKMAN's '+' to '-'
# (e.g. 25.0.4+1-ms -> 25.0.4-1-ms). The raw input is still passed to the
# build (sdk install java) via build-args below.
TAG="$(echo '${{ inputs.sdkman_java_version }}' | tr '+' '-')"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
- name: Build and push
uses: docker/build-push-action@v6.15.0
with:
context: ./docker/java-base
push: ${{ github.event.inputs.push }}
tags: dotcms/java-base:${{ github.event.inputs.sdkman_java_version }}${{ github.event.inputs.image_suffix }}
tags: dotcms/java-base:${{ steps.docker-tag.outputs.tag }}${{ github.event.inputs.image_suffix }}
platforms: ${{ env.PLATFORMS }}
build-args:
SDKMAN_JAVA_VERSION=${{ github.event.inputs.sdkman_java_version }}
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ jobs:
if [ -f .sdkmanrc ]; then
SDKMAN_JAVA_VERSION=$(awk -F "=" '/^java=/ {print $2}' .sdkmanrc)
echo "using default Java version from .sdkmanrc: ${SDKMAN_JAVA_VERSION}"
# Used as the dotcms/java-base docker tag (FROM dotcms/java-base:<tag>), which
# cannot contain '+' - convert SDKMAN's '+' to '-' (e.g. 25.0.4+1-ms -> 25.0.4-1-ms)
SDKMAN_JAVA_VERSION="${SDKMAN_JAVA_VERSION//+/-}"
echo "SDKMAN_JAVA_VERSION=${SDKMAN_JAVA_VERSION}" >> $GITHUB_OUTPUT
else
echo "No .sdkmanrc file found"
Expand Down
7 changes: 5 additions & 2 deletions .sdkmanrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# sets the SDKMAN_JAVA_VERSION for dotCMS
# this is the version of java that will be used as the base image for the docker build
# Use "sdk list java" to see available 25.x identifiers (e.g. 25.0.2-tem, 25.0.2-ms)
java=25.0.2-ms
# Use "sdk list java" to see available 25.x identifiers (e.g., 25.0.2-tem, 25.0.4+1-ms)
# NOTE: SDKMAN ids may contain '+', which is not valid in docker tags. Where this value
# is used as a docker tag (dotcms/java-base), '+' is converted to '-'
# (e.g. 25.0.4+1-ms -> 25.0.4-1-ms).
java=25.0.4+1-ms
11 changes: 10 additions & 1 deletion docker/dev-env/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ RUN useradd -l -d /srv -g $USER_GID -u $USER_UID $USER_NAME

COPY --from=dotcms --chown=$USER_NAME:$USER_GROUP /srv/ /srv/
COPY --from=dotcms /java /java
# Tomcat Native (tcnative) built for Tomcat 9 in the java-base image and
# shipped in the dotcms image; runtime deps (libapr1, libssl3) are in the apt
# packages below.
COPY --from=dotcms /usr/local/tomcat-native /usr/local/tomcat-native

ARG DEBIAN_FRONTEND=noninteractive
ARG UBUNTU_RELEASE=jammy
Expand All @@ -33,7 +37,7 @@ RUN chmod 777 /data
# Installing basic packages
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y --no-install-recommends bash zip unzip wget libtcnative-1\
apt-get install -y --no-install-recommends bash zip unzip wget \
tzdata tini ca-certificates openssl libapr1 libpq-dev curl gnupg\
vim libarchive-tools postgresql-common libmimalloc2.0 libjemalloc2 libarchive-tools

Expand Down Expand Up @@ -66,4 +70,9 @@ RUN chmod 755 /entrypoint.sh
FROM scratch
COPY --from=dev-env-builder / /

# ENVs from dev-env-builder do not survive the flatten to scratch, so (re)declare
# what this change needs. LD_LIBRARY_PATH makes tcnative visible to the JVM
# (JAVA_HOME is exported by /entrypoint.sh).
ENV LD_LIBRARY_PATH="/usr/local/tomcat-native/lib"

ENTRYPOINT ["/usr/bin/tini", "--", "/entrypoint.sh"]
44 changes: 41 additions & 3 deletions docker/java-base/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ FROM ubuntu:24.04 AS base-builder
WORKDIR /srv

# Defining default Java version, can be any java version provided by sdkman
ARG SDKMAN_JAVA_VERSION="25.0.2-ms"
ARG SDKMAN_JAVA_VERSION="25.0.4+1-ms"
ARG TCNATIVE_VERSION="1.3.8"
ARG TCNATIVE_SHA512="a12b97979037720465300cbc05777ff6ee2ec1dc59ff698864d7068800bf0c2d2606a4e0e29a4d7b16f92c9130604a13e0cc27929a224c9ff77e532ac98a4695"

ENV JAVA_OUTPUT_DIR="/java"
ENV DEBIAN_FRONTEND=noninteractive
Expand All @@ -17,7 +19,8 @@ ENV PATH="$SDKMAN_DIR/bin:$PATH"
# Installing basic packages and SDKMAN
RUN apt update && \
apt upgrade -y && \
apt install -y --no-install-recommends zip unzip wget libtcnative-1 tzdata tini ca-certificates openssl libapr1 libpq-dev curl gnupg && \
apt install -y --no-install-recommends zip unzip wget tzdata tini ca-certificates openssl libapr1 libpq-dev curl gnupg \
gcc make libapr1-dev libssl-dev && \
rm -rf /var/lib/apt/lists/* && \
wget -O - https://get.sdkman.io | bash && \
bash -c "source $SDKMAN_DIR/bin/sdkman-init.sh && sdk install java ${SDKMAN_JAVA_VERSION} && sdk flush archives" && \
Expand All @@ -43,9 +46,40 @@ RUN bash -c "source $SDKMAN_DIR/bin/sdkman-init.sh && jlink \
--no-man-pages \
--output \"$JAVA_OUTPUT_DIR\""

# Build the Tomcat Native library (tcnative) for Tomcat 9.
# Tomcat 9 requires the tcnative 1.x line (tcnative 2.x is Tomcat 10.1+ only).
# Ubuntu 24.04 only packages libtcnative-1 1.2.35, which is old and known to
# segfault with OpenSSL 3.x in FIPS environments, so we build the current
# Apache release from source, linked against this image's APR/OpenSSL 3.
# Built once here and reused by downstream images (the dotcms runtime image
# copies it from this image). Must run before the SDKMAN cleanup below,
# since the full JDK (JNI headers) is required. The build deps were installed
# with the Ubuntu repos only (before the pgdg repo is added), so no apt
# update is needed here; they are purged afterwards to keep the image slim.
# libpq-dev is purged here too because it depends on libssl-dev (purging
# libssl-dev removes it), and the cleanup step below no longer lists it.
# See https://tomcat.apache.org/download-native.cgi
Comment thread
wezell marked this conversation as resolved.
# downloads.apache.org only hosts the current release; older ones move to
# archive.apache.org, so fall back there once ${TCNATIVE_VERSION} is superseded.
RUN cd /tmp && \
(wget -q "https://downloads.apache.org/tomcat/tomcat-connectors/native/${TCNATIVE_VERSION}/source/tomcat-native-${TCNATIVE_VERSION}-src.tar.gz" || \
wget -q "https://archive.apache.org/dist/tomcat/tomcat-connectors/native/${TCNATIVE_VERSION}/source/tomcat-native-${TCNATIVE_VERSION}-src.tar.gz") && \
echo "${TCNATIVE_SHA512} *tomcat-native-${TCNATIVE_VERSION}-src.tar.gz" | sha512sum -c - && \
tar xzf "tomcat-native-${TCNATIVE_VERSION}-src.tar.gz" && \
cd "tomcat-native-${TCNATIVE_VERSION}-src/native" && \
./configure --with-apr=/usr/bin/apr-1-config \
--with-java-home="${SDKMAN_DIR}/candidates/java/current" \
--with-ssl=/usr \
--prefix=/usr/local/tomcat-native && \
make -j"$(nproc)" && \
make install && \
cd / && rm -rf /tmp/tomcat-native-${TCNATIVE_VERSION}-src.tar.gz "tomcat-native-${TCNATIVE_VERSION}-src" && \
apt purge -y gcc make libapr1-dev libssl-dev libpq-dev && \
apt autoremove -y

# Cleanup
RUN rm -rf /root/.sdkman && \
apt purge -y zip unzip wget curl libpq-dev && \
apt purge -y zip unzip wget curl && \
apt autoremove -y && \
apt clean && \
rm -rf /var/lib/apt/lists/*
Expand All @@ -55,3 +89,7 @@ RUN rm -rf /root/.sdkman && \
# ----------------------------------------------
FROM scratch
COPY --from=base-builder / /

# tcnative built in base-builder; downstream images inherit it via COPY and
# redeclare this ENV themselves (ENVs do not survive the flatten to scratch).
ENV LD_LIBRARY_PATH="/usr/local/tomcat-native/lib"
7 changes: 6 additions & 1 deletion dotCMS/src/main/docker/original/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ RUN apt update && \
tini \
zip \
unzip \
libtcnative-1 \
tzdata \
ca-certificates \
libmimalloc2.0 \
Expand Down Expand Up @@ -100,10 +99,16 @@ RUN groupadd -g "$USER_GID" "$USER_GROUP" && \
COPY --from=container-base /java /java
COPY --from=container-base /srv /srv
COPY --from=container-base /data /data
# Tomcat Native (tcnative) built for Tomcat 9 in the java-base image, so it is
# built once per java-base release and reused here. Runtime deps (libapr1,
# libssl3) come from the apt packages above.
COPY --from=container-base /usr/local/tomcat-native /usr/local/tomcat-native

USER $USER_UID:$USER_GID
ENV JAVA_HOME="/java"
ENV PATH=$PATH:/java/bin
# Makes the tcnative library visible to the JVM (System.loadLibrary("tcnative-1"))
ENV LD_LIBRARY_PATH="/usr/local/tomcat-native/lib"

ENTRYPOINT ["/usr/bin/tini", "--", "/srv/entrypoint.sh"]
CMD ["dotcms"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
# This script automatically detects FIPS-enabled environments and disables the
# Tomcat Native APR SSL Engine to prevent JVM crashes with OpenSSL 3.x.
#
# The Tomcat Native APR library (libtcnative-1) version 1.2.35 is incompatible
# with OpenSSL 3.x when running in FIPS mode, causing segmentation faults.
# The Tomcat Native APR library (libtcnative-1) has historically been incompatible
# with OpenSSL 3.x when running in FIPS mode, causing segmentation faults (e.g.
# the libtcnative-1 1.2.35 distro package this image used to ship). The image
# now builds the current Apache tcnative 1.x release from source (see the
# Dockerfile), but this guard is kept as defense-in-depth for FIPS hosts.
# Setting SSLEngine=off alone is insufficient: libtcnative-1 still loads
# libcrypto.so.3 and calls OpenSSL for non-SSL operations (e.g. random number
# generation), which triggers the same FIPS provider crash.
Expand Down
5 changes: 4 additions & 1 deletion dotCMS/src/main/resources/container/tomcat9/bin/setenv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
# Set default environment variables
export LANG=${LANG:-"C.UTF-8"}

export JAVA_OPTS_BASE=${JAVA_OPTS_BASE:-"-Djava.awt.headless=true -Djava.library.path=/usr/lib/$( uname -m )-linux-gnu/ -XX:+UseCompactObjectHeaders --enable-preview "}
# java.library.path must include the bundled tcnative dir (see java-base image):
# -Djava.library.path overrides LD_LIBRARY_PATH, so without it Tomcat's
# AprLifecycleListener cannot find libtcnative-1 and silently falls back to JSSE.
export JAVA_OPTS_BASE=${JAVA_OPTS_BASE:-"-Djava.awt.headless=true -Djava.library.path=/usr/local/tomcat-native/lib:/usr/lib/$( uname -m )-linux-gnu/ -XX:+UseCompactObjectHeaders --enable-preview "}

# Auto-tune GC algorithm based on available vCPUs:
# 1-3 cores → G1GC (default) + G1PeriodicGCInterval to return memory to OS on idle
Expand Down
3 changes: 3 additions & 0 deletions dotCMS/src/main/resources/container/tomcat9/conf/server.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@
client <-HTTPS-> proxy:443 <-HTTPS-> dotCMS:8443
To use APR and native openssl for https, add:
sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation"
CMS_SSL_PROTOCOLS restricts the offered TLS versions (default TLSv1.3;
set e.g. "TLSv1.2+TLSv1.3" or "all" to allow legacy TLS 1.2 clients)
-->
<Connector
port="${CMS_SSL_PORT:-8443}"
Expand All @@ -128,6 +130,7 @@
useSendfile="${CMS_USE_SENDFILE:-false}"
maxHttpHeaderSize="${CMS_MAX_HTTP_HEADER_SIZE:-16384}"
SSLEnabled="${CMS_SSL_ENABLED:-true}"
SSLProtocol="${CMS_SSL_PROTOCOLS:-TLSv1.3}"
Comment thread
wezell marked this conversation as resolved.
Comment thread
wezell marked this conversation as resolved.
SSLCertificateFile="${CMS_SSL_CERTIFICATE_FILE:-/data/shared/assets/certs/local.dotcms.site.pem}"
SSLCertificateKeyFile="${CMS_SSL_CERTIFICATE_KEY_FILE:-/data/shared/assets/certs/local.dotcms.site-key.pem}"
keystorePass="${CMS_KEYSTORE_PASS:-dotcms}"
Expand Down
7 changes: 5 additions & 2 deletions parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
<!-- default load from .sdkmanrc file -->
<!--suppress UnresolvedMavenProperty -->
<sdkman.java.version>${ext.java}</sdkman.java.version>
<!-- allows for override version of base for docker container separate from build -->
<runtime.docker.sdkman.java.version>${sdkman.java.version}</runtime.docker.sdkman.java.version>
<!-- allows for override version of base for docker container separate from build.
Docker-tag-safe form of sdkman.java.version: docker tags cannot contain '+',
so the SDKMAN id (e.g. 25.0.4+1-ms) is written 25.0.4-1-ms. Keep in sync
with .sdkmanrc when bumping the java version. -->
<runtime.docker.sdkman.java.version>25.0.4-1-ms</runtime.docker.sdkman.java.version>
Comment thread
wezell marked this conversation as resolved.

<!-- this is the version of source we support in source must be same or less that running version
run version is set by .sdkmanrc file in project root should update only after downstream plugins and projects
Expand Down
Loading