Reproducible experiments for Java application container behavior on OpenShift and Kubernetes
A comprehensive resource hub for testing and understanding how different Java runtimes, JVM versions, and configurations behave in containerized environments. Provides ready-to-deploy samples with Prometheus metrics integration for comparing container ergonomics, memory tuning, thread scaling, and cgroups behavior.
This repository helps developers and operators:
- Understand container-aware JVM behavior across Java versions (11, 17, 21, 23)
- Compare runtime characteristics of different application servers (Undertow, Spring Boot, Tomcat, WildFly)
- Experiment with memory limits, CPU quotas, and JVM tuning flags
- Monitor application metrics using Prometheus and Grafana
- Validate containerization patterns using Red Hat Universal Base Images (UBI 9)
- 4 Application Server Runtimes: Undertow (lightweight), Spring Boot (framework), Tomcat (servlet), WildFly (full Jakarta EE)
- Multiple Java Versions: OpenJDK 11, 17, 21, and 23 per runtime (15 total configurations)
- Container-Aware Tuning: Pre-configured with
-XX:MaxRAMPercentage,-XX:InitialRAMPercentage, and container detection logging - Prometheus Metrics: JVM metrics (memory, GC, threads), HTTP metrics, and application metrics
- OpenShift Native: BuildConfig resources for cluster-native builds from Git sources
- Dynamic Versioning: ARG-based Dockerfiles supporting version overrides at build time
- Security Hardened: Runs as non-root with OpenShift restricted SCC compliance
| Runtime | Java 11 | Java 17 | Java 21 | Java 23 | Base Image | Memory Limit |
|---|---|---|---|---|---|---|
| Undertow | β | β | β | β | UBI 9 openjdk | 512Mi |
| Spring Boot | β | β | β | β | UBI 9 openjdk | 768Mi |
| Tomcat 10.1.49 | β | β | β | β | UBI 9 minimal + openjdk | 768Mi |
| WildFly 34/38 | β | β | β | β | Official WildFly | 1Gi |
Java 23 uses Java 21 base images (Red Hat does not provide native OpenJDK 23 images)
# Prerequisites: oc, podman, maven
git clone https://github.com/davidecelano/openshift-java-playground.git
cd openshift-java-playground
# Verify repository structure
./scripts/verify-structure.sh
# Quick local test (Spring Boot)
cd metrics-sample-springboot && mvn clean package
java -jar target/metrics-sample-springboot-1.0.0.jar
curl http://localhost:8080/actuator/prometheus | grep jvm_memoryπ Next Steps: See Quick Start Guide for complete 10-minute OpenShift deployment
| Document | Description |
|---|---|
| β‘ Quick Start | Get running in 10 minutes with OpenShift-native builds |
| π Deployment Guide | Complete deployment procedures (local, OpenShift, GitHub Actions) |
| π¬ Testing & Validation | Validate builds, troubleshoot issues, run performance tests |
| π§ Implementation Details | Technical architecture, design decisions, runtime comparisons |
| π Version Matrix | Image versions, compatibility, update procedures |
| π Version Management | Update procedures, testing checklist, rollback strategies |
| π Changelog | Release history, breaking changes, upgrade guides |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β OpenShift / Kubernetes β
β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β Undertow β β Spring Boot β β Tomcat β β
β β (Micrometer)β β (Actuator) β β (Prometheus) β ... β
β ββββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββ¬ββββββββ β
β β /metrics β /actuator/ β /metrics β
β β β prometheus β β
β βββββββββββββββββββ΄βββββββββββββββββββ β
β β β
β ββββββββββΌβββββββββ β
β β ServiceMonitor β β
β ββββββββββ¬βββββββββ β
β β β
β ββββββββββΌβββββββββ β
β β Prometheus β β
β ββββββββββ¬βββββββββ β
β β β
β ββββββββββΌβββββββββ β
β β Grafana β β
β βββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Build Flow: Git β OpenShift BuildConfig β ImageStream β Deployment β Service β ServiceMonitor β Prometheus
openshift-java-playground/
βββ metrics-sample-undertow/ # Lightweight HTTP server (Undertow)
βββ metrics-sample-springboot/ # Spring Boot with Actuator
βββ metrics-sample-tomcat/ # Apache Tomcat 10.1.x
βββ metrics-sample-wildfly/ # WildFly 34/38 application server
βββ scripts/ # Build, deploy, and validation scripts
βββ plans/ # Phase completion documents
βββ QUICKSTART.md # 10-minute getting started
βββ DEPLOYMENT.md # Complete deployment guide
βββ TESTING.md # Validation and troubleshooting
βββ IMPLEMENTATION.md # Technical architecture
βββ VERSIONS.md # Image version matrix
βββ versions.env.example # Version override template
Each sample directory contains:
Dockerfile.openjdk{11,17,21,23}- Multi-stage builds with ARG parameterizationopenshift/buildconfig-*.yaml- OpenShift BuildConfig resourcesk8s/deployment-*.yaml- Kubernetes deployment manifestsk8s/service.yaml- Service definitionk8s/servicemonitor.yaml- Prometheus ServiceMonitorpom.xml- Maven build configurationsrc/- Java source code
Compare heap sizing strategies across runtimes:
# Test with 50% vs 70% heap
podman run -m 512m -e JAVA_OPTS="-XX:MaxRAMPercentage=50.0" <image>
podman run -m 512m -e JAVA_OPTS="-XX:MaxRAMPercentage=70.0" <image>
# Monitor via Prometheus metrics
curl http://localhost:8080/metrics | grep jvm_memoryTest thread pool behavior under CPU quotas:
# Limit to 0.5 CPU and observe thread allocation
oc set resources deployment/undertow-openjdk17 --limits=cpu=500m
oc logs -f deployment/undertow-openjdk17 | grep "Active Processor Count"Compare container detection across cgroups versions.
# Creates ImageStreams and triggers cluster builds from Git
./scripts/trigger-openshift-builds.sh
oc logs -f bc/metrics-undertow-openjdk17# Build locally and push to registry
export REGISTRY=quay.io/yourorg
./scripts/build-all.sh
./scripts/push-all.sh
./scripts/deploy-all.sh# Automated builds on push to main
# See .github/workflows/build-and-push.ymlπ Details: See Deployment Guide for complete procedures
All samples expose Prometheus-compatible metrics:
JVM Metrics:
jvm_memory_used_bytes/jvm_memory_max_bytesjvm_gc_pause_seconds(histogram)jvm_threads_live/jvm_threads_peakjvm_classes_loaded
HTTP Metrics (Spring Boot, Undertow):
http_server_requests_seconds(histogram)- Request counts, rates, error rates
Application Metrics:
- Custom business metrics (extend per sample)
Container Metrics:
- Container CPU/memory via Kubernetes API
- cgroups v1/v2 detection logged at startup
π Access: kubectl port-forward svc/undertow-openjdk17 8080:8080 && curl http://localhost:8080/metrics
All 15 configurations validated with 100% success rate:
# Quick build validation (all 15 configs)
./scripts/quick-validate-builds.sh
# BuildConfig YAML validation + ARG override tests
./scripts/validate-buildconfigs.sh
# Runtime container startup and endpoint health
./scripts/validate-runtime.sh
# Comprehensive validation suite
./scripts/validate-all-builds.shπ Details: See Testing Guide for troubleshooting and validation procedures
- Non-root: All containers run as non-root user (UID 1001 or defined by base image)
- Restricted SCC: Compatible with OpenShift restricted Security Context Constraints
- No privilege escalation:
allowPrivilegeEscalation: false - Capability drop:
capabilities.drop: ["ALL"] - Seccomp:
seccompProfile.type: RuntimeDefault - UBI 9: Red Hat Universal Base Images with CVE monitoring and security patches
- Phase 1-7: UBI 9 migration with Tomcat 10.1.49 & WildFly 34/38 upgrades
- Comprehensive validation suite with 100% test coverage
- Load testing framework with resource limit scenarios
- Grafana dashboard templates for runtime comparison
- OpenShift ServiceMonitor integration guide
- Java 24 EA support when base images available
- Native image (GraalVM) samples
- Quarkus runtime samples
- OpenJDK Container Awareness
- Red Hat Container Catalog
- Container Memory Tuning
- WildFly Container Guide
- Spring Boot Actuator
- Prometheus JVM Metrics
This project is provided as-is for educational and experimental purposes. Individual components (OpenJDK, WildFly, Tomcat, Spring Boot) are governed by their respective licenses.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: See docs section above
Version: 2.0.0
Last Updated: November 2025
Total Configurations: 15 (Undertow 4, Spring Boot 3, Tomcat 4, WildFly 4)
Test Coverage: 100% (38/38 tests passing)
Documentation: 14 files, ~3,200 lines
β Star this repository if you find it useful for understanding Java container behavior!
π Related Projects: