Skip to content

Commit

Permalink
build: Use consistent java versions using sdkman (#28868)
Browse files Browse the repository at this point in the history
### Proposed Changes
* Change java base image to use sdkman to get java version. Use
SDKMAN_JAVA_VERSION build arg to specify SDKMAN version and
implementation.
* Create manual workflow specifically for creating java base image based
upon SDKMAN version string being tagged and pushed with that version.
* Modify maven to pick up version specified in ~/.sdkmanrc and use that
by default to specify which upstream java base image to used.
* Cleanup places where java version is specified in maven pom files to
default to a single location in parent/pom.xml. Set default value in
environments/environment.properties so it can be modified locally be
developers easily and changed in one place. setting
java.compat.version=11
* Use independent version for compatibility of build allowing Java 21 to
be upgraded to but still allowing plugins to be build with Java 11 with
easy switch later.
* Cleanup DockerFiles with some AI help.


Note: 
* This change does not actually update to java 21 yet. We should do
internal test to upgrade to latest point release of java 11 first. e.g.
11.0.22-ms -> 11.0.23-ms
* This change does not modify the version used in the ci build
workflows. We will follow up a change to enable consistent use of the
.sdkmanrc in the workflows after this PR.
  • Loading branch information
spbolton authored Jun 17, 2024
1 parent beec45b commit 1114b54
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 86 deletions.
57 changes: 57 additions & 0 deletions .github/workflows/build-java-base.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Build SDKMan Base java image
on:
workflow_dispatch:
inputs:
sdkman_java_version:
description: 'SDKMAN version string run "sdk list java" for options'
required: true
multi_arch:
description: 'Multi-arch flag, true: linux/amd64,linux/arm64 or false: linux/amd64'
type: boolean
required: false
default: true
push:
description: 'Push flag'
type: boolean
required: false
default: true
jobs:
build_image:
name: Build Docker Base Image
runs-on: ubuntu-20.04
steps:
- name: Checkout core
uses: actions/checkout@v4
- name: Set Common Vars
run: |
PLATFORMS='linux/amd64'
[[ "${{ github.event.inputs.multi_arch }}" == 'true' ]] && PLATFORMS='linux/amd64,linux/arm64'
echo "PLATFORMS=${PLATFORMS}" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/[email protected]
with:
platforms: amd64,arm64
if: github.event.inputs.multi_arch == 'true'
- id: docker-setup-buildx
name: Docker Setup Buildx
uses: docker/[email protected]
with:
platforms: ${{ env.PLATFORMS }}
driver-opts: |
image=moby/buildkit:v0.12.2
if: github.event.inputs.multi_arch == 'true'
- name: Docker Hub login
uses: docker/[email protected]
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push
uses: docker/[email protected]
with:
context: ./docker/java-base
push: ${{ github.event.inputs.push }}
tags: ${{ github.event.inputs.tags }}
platforms: ${{ env.PLATFORMS }}
build-args:
SDKMAN_JAVA_VERSION=${{ github.event.inputs.sdkman_java_version }}
43 changes: 21 additions & 22 deletions docker/java-base/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,48 +1,47 @@
# ----------------------------------------------
# Stage 1: Minimal java image with sdkman + Ubuntu LTS
# ----------------------------------------------
FROM mcr.microsoft.com/openjdk/jdk:11-ubuntu as base-builder
FROM ubuntu:20.04 AS base-builder

WORKDIR /srv

# Defining default Java, can be any java provided by sdkman
ARG JAVA_VERSION="11.0.17-amzn"
# Defining default Java version, can be any java version provided by sdkman
ARG SDKMAN_JAVA_VERSION="11.0.22-ms"

ENV JAVA_OUTPUT_DIR="/java"
ENV DEBIAN_FRONTEND=noninteractive
ENV PATH="$PATH:/java/bin"
ENV SDKMAN_DIR="/root/.sdkman"
ENV PATH="$SDKMAN_DIR/bin:$PATH"

# Installing basic packages
# 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

# Install curl
RUN wget -O - https://repo.dotcms.com/artifactory/ext-release-local/com/dotcms/curl-static/curl-`uname -m` | install /dev/stdin /usr/bin/curl && \
chmod a+x /usr/bin/curl
apt install -y --no-install-recommends zip unzip wget libtcnative-1 tzdata tini ca-certificates openssl libapr1 libpq-dev curl gnupg && \
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" && \
apt update && \
apt install -y --no-install-recommends postgresql-common && \
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && \
apt install -y --no-install-recommends postgresql-client-16 && \
apt purge -y postgresql-common gnupg && \
/usr/bin/pg_dump --version || exit 1 && \
rm -rf /var/lib/apt/lists/*

RUN jlink \
# Create a custom JRE using jlink
RUN bash -c "source $SDKMAN_DIR/bin/sdkman-init.sh && jlink \
--verbose \
--add-modules \
java.base,jdk.crypto.ec,jdk.jdwp.agent,jdk.management,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument,jdk.unsupported,java.scripting,java.rmi,jdk.compiler,jdk.zipfs,jdk.naming.dns,jdk.localedata,java.xml,jdk.xml.dom \
--compress 2 \
--no-header-files \
--no-man-pages \
--output "$JAVA_OUTPUT_DIR"

# install postgres clients, for pg_dump
ARG PG_BUILD_PACKAGES="postgresql-common gnupg"

RUN apt install -y --no-install-recommends $PG_BUILD_PACKAGES \
&& /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y \
&& apt install -y postgresql-client-16 \
&& apt purge -y $PG_BUILD_PACKAGES

RUN /usr/bin/pg_dump --version || exit 1
--output \"$JAVA_OUTPUT_DIR\""

# Cleanup
RUN rm -rf /root/.sdkman && \
apt purge -y zip unzip wget msopenjdk-11 packages-microsoft-prod fontconfig-config && \
apt purge -y zip unzip wget curl libpq-dev && \
apt autoremove -y && \
apt clean && \
rm -rf /var/lib/apt/lists/*
Expand Down
3 changes: 3 additions & 0 deletions dotCMS/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,9 @@
<descriptor>original/docker-descriptor.xml</descriptor>
<targetDir>/maven</targetDir>
</assembly>
<args>
<SDKMAN_JAVA_VERSION>${runtime.docker.sdkman.java.version}</SDKMAN_JAVA_VERSION>
</args>
</build>
</dotcms>
</imagesMap>
Expand Down
89 changes: 47 additions & 42 deletions dotCMS/src/main/docker/original/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,68 +1,73 @@
# ----------------------------------------------
# Stage 2: Construct our container using the minimal-java image
# and copying the prebuilt dotcms
# Stage 1: Construct our container using the minimal-java image and copying the prebuilt dotcms
# ----------------------------------------------
FROM dotcms/java-base:ms-jdk-11 as container-base

ARG SDKMAN_JAVA_VERSION="11.0.22-ms"
FROM dotcms/java-base:${SDKMAN_JAVA_VERSION} AS container-base
WORKDIR /srv

ENV DEBIAN_FRONTEND=noninteractive

# Installing basic packages
RUN apt update \
&& apt upgrade -y

# Cleanup
RUN apt purge --allow-remove-essential -y \
&& apt autoremove -y \
&& apt clean \
&& rm -rf /var/lib/apt/lists/*

# Defining default non-root user UID, GID, and name
ARG USER_UID="65001"
ARG USER_GID="65001"
ARG USER_GROUP="dotcms"
ARG USER_NAME="dotcms"

RUN groupadd -f -g $USER_GID $USER_GROUP
# Creating default non-user
# the useradd
RUN useradd -l -d /srv -g $USER_GID -u $USER_UID $USER_NAME

RUN mkdir -p /srv/utils /srv/templates /srv/config /srv/home
# Ensure group and user are created with proper permissions
RUN groupadd -g "$USER_GID" "$USER_GROUP" && \
useradd -l -d /srv -u "$USER_UID" -g "$USER_GROUP" -s /bin/bash "$USER_NAME" && \
mkdir -p /srv/utils /srv/templates /srv/config /srv/home /data/shared/assets /data/shared/felix/load /data/shared/felix/undeployed /data/local/dotsecure/license && \
chown -R "$USER_NAME:$USER_GROUP" /data && \
chown -R "$USER_NAME:$USER_GROUP" /srv

# Copy our build
COPY --chown=$USER_NAME:$USER_GROUP maven /srv/
COPY --chown=$USER_NAME:$USER_GROUP ROOT/ /

RUN ln -s $(ls -d /srv/dotserver/tomcat-*) /srv/dotserver/tomcat

# Make scripts runable
RUN find /srv/ -type f -name "*.sh" -exec chmod a+x {} \; && \
RUN ln -s $(ls -d /srv/dotserver/tomcat-*) /srv/dotserver/tomcat && \
# Make scripts runnable
find /srv/ -type f -name "*.sh" -exec chmod a+x {} \; && \
# Make plugin merging directories writable
find /srv/templates -type d -exec chmod 770 {} \; && \
# Make dotcms user owner
mkdir -p /data/shared/assets && \
mkdir -p /data/shared/felix/load && \
mkdir -p /data/shared/felix/undeployed && \
mkdir -p /data/local/dotsecure/license && \
chown -R $USER_NAME:$USER_NAME /data
find /srv/templates -type d -exec chmod 770 {} \;

# ----------------------------------------------
# Stage 3: Flatten everything to 1 layer
# Stage 2: Final stage for minimal runtime image
# ----------------------------------------------
FROM scratch

LABEL com.dotcms.contact "[email protected]"
LABEL com.dotcms.vendor "dotCMS LLC"
LABEL com.dotcms.description "dotCMS Content Management System"
FROM ubuntu:20.04

LABEL com.dotcms.contact="[email protected]" \
com.dotcms.vendor="dotCMS LLC" \
com.dotcms.description="dotCMS Content Management System"

# Install basic packages and tini
RUN apt update && \
apt upgrade -y && \
apt install -y --no-install-recommends \
wget \
gnupg \
tini && \
rm -rf /var/lib/apt/lists/*

# Install PostgreSQL client and pg_dump
RUN apt update && \
apt install -y --no-install-recommends postgresql-common && \
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && \
apt install -y --no-install-recommends postgresql-client-16 && \
apt purge -y postgresql-common gnupg && \
/usr/bin/pg_dump --version || exit 1 && \
rm -rf /var/lib/apt/lists/*

ARG USER_UID="65001"
ARG USER_GID="65001"
ARG USER_GROUP="dotcms"
ARG USER_NAME="dotcms"

# Ensure the group and user are created in the final image as well
RUN groupadd -g "$USER_GID" "$USER_GROUP" && \
useradd -l -d /srv -u "$USER_UID" -g "$USER_GROUP" -s /bin/bash "$USER_NAME"

COPY --from=container-base / /
COPY --from=container-base /java /java
COPY --from=container-base /srv /srv
COPY --from=container-base /data /data

# Switching to non-root user to install SDKMAN!
USER $USER_UID:$USER_GID
ENV JAVA_HOME="/java"
ENV PATH=$PATH:/java/bin
Expand All @@ -82,4 +87,4 @@ EXPOSE 8081
# Connect from proxy, HTTPS/443, secure
EXPOSE 8082
# Direct connect for HTTPS, secure
EXPOSE 8443
EXPOSE 8443
16 changes: 11 additions & 5 deletions dotCMS/src/main/docker/original/ROOT/srv/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@ source /srv/20-copy-overriden-files.sh
source /srv/30-override-config-props.sh
source /srv/40-custom-starter-zip.sh

echo ""
echo "Starting dotCMS ..."
echo "-------------------"
echo ""

[[ -n "${WAIT_FOR_DEPS}" ]] && echo "Waiting ${WAIT_FOR_DEPS} seconds for DotCMS dependencies to load..." && sleep ${WAIT_FOR_DEPS}

exec -- ${TOMCAT_HOME}/bin/catalina.sh run
if [[ "$1" == "dotcms" ]]; then
shift
echo ""
echo "Starting dotCMS ..."s
echo "-------------------"
echo ""
exec -- ${TOMCAT_HOME}/bin/catalina.sh run "$@"
else
echo starting "$@"
exec -- "$@"
fi
1 change: 1 addition & 0 deletions environments/environment.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ docker.image.postgres=ankane/pgvector
postman.collections=Maintenance_Resource
docker.image.wiremock=wiremock/wiremock:3.5.3
wiremock.api.key=some-api-key-1a2bc3
java.compat.version=11
3 changes: 0 additions & 3 deletions independent-projects/core-plugins/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@

<properties>
<maven.deploy.skip>false</maven.deploy.skip>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tika.api.version>${project.version}</tika.api.version>
</properties>

Expand Down
3 changes: 0 additions & 3 deletions independent-projects/core-plugins/tika-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@

<properties>
<maven.deploy.skip>false</maven.deploy.skip>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
Expand Down
4 changes: 0 additions & 4 deletions independent-projects/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,9 @@

<packaging>pom</packaging>

<groupId>com.dotcms</groupId>
<artifactId>dotcms-independent-projects</artifactId>

<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tika.api.version>${project.version}</tika.api.version>
</properties>

Expand Down
2 changes: 0 additions & 2 deletions osgi-base/system-bundles/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

<properties>
<maven.deploy.skip>false</maven.deploy.skip>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<tika.version>1.28.5</tika.version>
<spifly.version>1.3.6</spifly.version>
<asm.version>9.4</asm.version>
Expand Down
20 changes: 15 additions & 5 deletions parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,20 @@
<sha1/>
<flatten.mode>oss</flatten.mode>
<flatten.skip>false</flatten.skip>
<!-- 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>

<java.version>11</java.version>
<maven.compiler.release>11</maven.compiler.release>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<!-- 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
support new version default in environments/environment.properties and can be changed for local developer in
environments/dev/user-dev.properties -->
<!--suppress UnresolvedMavenProperty -->
<maven.compiler.release>${ext.java.compat.version}</maven.compiler.release>
<maven.compiler.source>${maven.compiler.release}</maven.compiler.source>
<maven.compiler.target>${maven.compiler.release}</maven.compiler.target>
<maven.compiler.testSource>${maven.compiler.source}</maven.compiler.testSource>
<maven.compiler.testTarget>${maven.compiler.target}</maven.compiler.testTarget>
<java.module.args>
Expand Down Expand Up @@ -645,7 +654,7 @@
<version>${version.compiler.plugin}</version>
<configuration>
<fork>true</fork>
<release>${java.version}</release>
<release>${maven.compiler.release}</release>
<compilerArgs>
<arg>-Xlint:unchecked</arg>
</compilerArgs>
Expand Down Expand Up @@ -963,6 +972,7 @@
<useDefaultValues>true</useDefaultValues>
<files>
<file>${environment.properties.defaults}</file>
<file>${maven.multiModuleProjectDirectory}/.sdkmanrc</file>
</files>
<keyPrefix>ext.</keyPrefix>
</configuration>
Expand Down

0 comments on commit 1114b54

Please sign in to comment.