fix(docker): replace outdated tcnative 1.2.35 with Apache tcnative 1.3.8 - #37399
fix(docker): replace outdated tcnative 1.2.35 with Apache tcnative 1.3.8#37399wezell wants to merge 10 commits into
Conversation
The Ubuntu 24.04 libtcnative-1 package (1.2.35) segfaults with OpenSSL 3.x during AprLifecycleListener SSL initialization (SIGSEGV in libcrypto.so.3). Tomcat 9 requires the tcnative 1.x line; build the current Apache release (1.3.8, SHA-512 pinned) from source in the java-base image and reuse it in the runtime and dev-env images instead of the distro package. Also handles SDKMAN ids containing '+' (e.g. 25.0.4+1-ms), which are not valid docker tags: the canonical id stays in .sdkmanrc and '+' is converted to '-' wherever the value becomes a docker tag. Fixes #34067
|
Claude finished @wezell's task in 2m 59s —— View job Code ReviewI reviewed the full diff against New Issues
Existing
Resolved
No blocking issues. The two medium items are behavior-change call-outs, both already discussed/accepted in the PR threads.
|
downloads.apache.org only hosts the current release; once tcnative 1.3.8 is superseded the URL would 404 and break java-base builds. Fall back to archive.apache.org, which retains all releases. Checksum still enforced.
dotCMS-Machine-User
left a comment
There was a problem hiding this comment.
✅ dotbot review: all reviewer models (meta/muse-spark-1.3, ~z-ai/glm-latest) agree — patch is correct.
approved automatically by dotbot
🐳 PR Docker test imageLatest build for commit docker pull dotcms/dotcms-test:pr-37399-issue-34067-fix-tcnative-apr-openssl3
docker pull dotcms/dotcms-test:pr-37399-issue-34067-fix-tcnative-apr-openssl3_5168177 |
…e library path - DataSourceStrategyProvider: default DATASOURCE_PROVIDER_STRATEGY_CLASS to SystemEnvDataSourceStrategy so DB_* environment variables work out of the box without setting DOT_DATASOURCE_PROVIDER_STRATEGY_CLASS - setenv.sh: prepend /usr/local/tomcat-native/lib to java.library.path. -Djava.library.path overrides LD_LIBRARY_PATH, so the previously hardcoded multiarch path prevented Tomcat's AprLifecycleListener from finding libtcnative-1, silently falling back to JSSE on 8443
…_SSL_PROTOCOLS
Ship with TLSv1.3 only (SSLProtocol="${CMS_SSL_PROTOCOLS:-TLSv1.3}").
TLS 1.2 with modern AEAD ciphers remains available by setting
CMS_SSL_PROTOCOLS=TLSv1.2+TLSv1.3 (or all) for deployments with legacy
TLS 1.2 clients. Validated live: TLS 1.2 rejected, TLS 1.3 accepted,
server starts cleanly with the restriction in place.
…escape hatch Review follow-up: the empty-value escape hatch (which restores the legacy db.properties / Docker Secrets resolution order) was undocumented and, worse, unreachable in Docker because setenv.sh force-exported DOT_DATASOURCE_PROVIDER_STRATEGY_CLASS, overriding any operator-provided value. - setenv.sh: drop the forced export; the code default in DataSourceStrategyProvider already covers Dockerized environments - javadoc: document all three resolution modes (default SystemEnv, explicit class override, empty-value escape hatch) and when to use each - add DataSourceStrategyProviderTest covering the default, the explicit override, and the empty-value escape hatch (3 tests)
…stemEnv default Previously, setting DATASOURCE_PROVIDER_STRATEGY_CLASS to default to SystemEnvDataSourceStrategy routed all unconfigured lookups directly to the custom-strategy branch, bypassing existsDBPropertiesFile() and dockerSecretPathExists(). Now DataSourceStrategyProvider preserves the full resolution precedence: 1. Explicit custom class (if configured and != SystemEnvDataSourceStrategy) 2. db.properties (if file exists) 3. Docker Secrets (if secret path exists) 4. SystemEnvDataSourceStrategy (the default when no other config present) 5. TomcatDataSourceStrategy (context.xml fallback on failure) Added unit tests covering all resolution branches (6 tests).
dotCMS-Machine-User
left a comment
There was a problem hiding this comment.
✅ dotbot review: all reviewer models (meta/muse-spark-1.3, ~z-ai/glm-latest) agree — patch is correct.
approved automatically by dotbot
The integration test harness sets DATASOURCE_PROVIDER_STRATEGY_CLASS to SystemEnvDataSourceStrategy explicitly and expects it to run directly via the custom-strategy branch. The previous change treated an explicit SystemEnv as the implicit default and re-routed it through the precedence chain, causing the harness to fall through to the JNDI fallback (NoInitialContextException) and fail MainSuite 2a. Now an explicitly configured value (including an explicit SystemEnvDataSourceStrategy) is honored directly; only the implicit default (property unset) walks the precedence chain (db.properties -> Docker Secrets -> SystemEnv -> context.xml fallback). Extracted isDataSourceProviderExplicitlyConfigured() (VisibleForTesting) and reworked the unit tests to drive the resolution deterministically (7 tests).
dotCMS-Machine-User
left a comment
There was a problem hiding this comment.
✅ dotbot review: all reviewer models (meta/muse-spark-1.3, ~z-ai/glm-latest) agree — patch is correct.
approved automatically by dotbot
|
dotbot code review:
Patch replaces distro libtcnative with source-built 1.3.8 and fixes datasource precedence with tests. No P0/P1 bug with concrete in-repo evidence remains; open points are intentional trade-offs. Tip: comment with "/dotbot address comments" to attempt automated fixes for unresolved review threads. reviewed by dotbot · meta/muse-spark-1.3 · medium |
|
|
||
| Logger.info(DataSourceStrategyProvider.class, | ||
| "Datasource loaded using custom class " + providerClassName); | ||
| } else { |
There was a problem hiding this comment.
🔴 [P1] DataSourceStrategyProvider.java:96 shipped commented-out db.properties now short-circuits env-var datasource
Current code:
if (getDBPropertiesInstance()
.existsDBPropertiesFile()) {
defaultDataSource = getDBPropertiesInstance()
.apply();Problem: dotCMS/src/main/resources/db.properties ships in the WAR's WEB-INF/classes but is entirely commented out ("This property file is no longer used"). existsDBPropertiesFile() is therefore true in every stock deployment, while HikariConfig(propertiesFile.getPath()) in DBPropertiesDataSourceStrategy.getHikariConfig() fails (no jdbcUrl). Previously setenv.sh force-exported DOT_DATASOURCE_PROVIDER_STRATEGY_CLASS=SystemEnvDataSourceStrategy, so this branch was unreachable in Docker; this patch removes that export and makes the chain reachable. The exception is swallowed in get(), defaultDataSource stays null, and the finally falls back to TomcatDataSourceStrategy, whose JNDI lookup is undefined in the shipped container/tomcat9/conf/context.xml (no <Resource>), so it throws DotRuntimeException and DB init fails for env-var-configured containers. Separately, reordering Docker Secrets ahead of DB_* env vars silently changes resolution for deployments that mount /run/secrets/ while configuring via env vars.
Fix:
} else if (getDBPropertiesInstance().hasActiveJdbcUrl()) {
defaultDataSource = getDBPropertiesInstance().apply();Or stop shipping the vestigial db.properties so SystemEnvDataSourceStrategy resolves for the stock image.
| String getCustomDataSourceProvider() { | ||
| return Config | ||
| .getStringProperty("DATASOURCE_PROVIDER_STRATEGY_CLASS", null); | ||
| .getStringProperty("DATASOURCE_PROVIDER_STRATEGY_CLASS", "com.dotmarketing.db.SystemEnvDataSourceStrategy"); |
There was a problem hiding this comment.
🟡 [P2] DataSourceStrategyProvider.java:133 dead default in getCustomDataSourceProvider
Current code:
return Config
.getStringProperty("DATASOURCE_PROVIDER_STRATEGY_CLASS", "com.dotmarketing.db.SystemEnvDataSourceStrategy");Problem: This default is only read on the hasExplicitCustomProvider branch, where the property is guaranteed set — it is dead and misleading.
Fix:
return Config.getStringProperty("DATASOURCE_PROVIDER_STRATEGY_CLASS", null);If the explicit-config check is ever simplified, this default would silently resurrect the precedence bypass.
| useSendfile="${CMS_USE_SENDFILE:-false}" | ||
| maxHttpHeaderSize="${CMS_MAX_HTTP_HEADER_SIZE:-16384}" | ||
| SSLEnabled="${CMS_SSL_ENABLED:-true}" | ||
| SSLProtocol="${CMS_SSL_PROTOCOLS:-TLSv1.3}" |
There was a problem hiding this comment.
🟡 [P2] server.xml:133 TLSv1.3-only default drops TLS 1.2 clients on the direct connector
Current code:
SSLProtocol="${CMS_SSL_PROTOCOLS:-TLSv1.3}"Problem: Previously Tomcat's default (TLSv1.2+TLSv1.3) applied; now TLS 1.2-only clients are rejected unless CMS_SSL_PROTOCOLS is set — a silent breaking default for deployments terminating TLS directly at dotCMS.
Fix:
SSLProtocol="${CMS_SSL_PROTOCOLS:-TLSv1.2+TLSv1.3}"Assumption: the hardening is deliberate per the comment. What to verify: no supported clients/proxies negotiate only TLS 1.2 against port 8443.
|
dotbot code review:
The tcnative 1.3.8 build, LD_LIBRARY_PATH plumbing, and docker-tag '+'→'-' handling are sound, but removing the setenv.sh export combined with the new implicit chain makes the shipped, all-commented db.properties take precedence over DB_* env vars in every stock deployment; Hikari fails on it and the JNDI fallback (no Resource in context.xml) throws, breaking the default datasource path. Tip: comment with "/dotbot address comments" to attempt automated fixes for unresolved review threads. reviewed by dotbot · ~z-ai/glm-latest · medium |
Summary
dotCMS's SSL offloading to openssl has been broken since we moved to Ubuntu 24.04. We haven't noticed because it would fall back to using java's SSL but this has performance implications and it is better to offload it.
Fixes #34067
dotCMS crashed on startup with a JVM SIGSEGV inside
libcrypto.so.3when the Tomcat Native APR library initialized OpenSSL 3.x. Root cause: the Ubuntu 24.04libtcnative-1package (1.2.35, Jan 2023) is incompatible with OpenSSL 3.x — the very library version all our images install to offload Tomcat 9's SSL.Tomcat 9 requires the tcnative 1.x line (2.x is Tomcat 10.1+ only). This PR builds the current Apache release, tcnative 1.3.8, from source (SHA-512 pinned) against the image's own APR 1.7 / OpenSSL 3, and stops installing the distro package.
Changes
docker/java-base/Dockerfile/usr/local/tomcat-native(built once per java-base release, reused downstream); build deps purged; JDK default25.0.4+1-msdotCMS/src/main/docker/original/Dockerfilelibtcnative-1; copies tcnative from java-base; setsLD_LIBRARY_PATHdocker/dev-env/Dockerfile15-detect-fips-and-set-ssl-engine.sh.sdkmanrc25.0.4+1-msmaven-jobaction,deployment-phase,legacy-release,java-baseworkflows+→-where the SDKMAN id becomes a docker tag (docker tags cannot contain+)parent/pom.xmlruntime.docker.sdkman.java.versiondefaults to docker-tag-safe25.0.4-1-ms(maven cannot transform the.sdkmanrc-loaded property)Deployment note
The java-base image with tcnative is already pushed as
dotcms/java-base:25.0.4-1-ms(built viacicd_manual_build-java-base.yml), so downstream builds resolve immediately.Validation
just build(./mvnw -DskipTests clean install): BUILD SUCCESS, including the maven-driven docker image builddotcms/dotcms-test:1.0.0-SNAPSHOT): tcnative 1.3.8 present from java-base, no distrolibtcnative-1,LD_LIBRARY_PATHset, Java 25.0.4.1tomcat-jni.jar(whatAprLifecycleListenerdoes at startup):LD_LIBRARY_PATH+→-substitution verified for both+-containing and plain versions