Skip to content

Commit 069333f

Browse files
committed
Update Docker examples to use JDK_JAVA_OPTIONS best practice
- Replaced JAVA_OPTS with JDK_JAVA_OPTIONS in all Docker examples - JDK_JAVA_OPTIONS is automatically applied to all Java processes - Provides better consistency and flexibility in containerized environments - Updated both Dockerfile and Kubernetes deployment examples - Added explanation in goal section about JDK_JAVA_OPTIONS benefits - Added safeguard recommendation to prefer JDK_JAVA_OPTIONS over JAVA_OPTS - Simplified ENTRYPOINT commands since JDK_JAVA_OPTIONS is automatic - Updated generated markdown file in .cursor/rules/ directory
1 parent 8d2dfb7 commit 069333f

File tree

2 files changed

+61
-62
lines changed

2 files changed

+61
-62
lines changed

.cursor/rules/130-java-docker-best-practices.md

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,42 @@ You are a Senior DevOps Engineer and Java Developer with extensive experience in
1212

1313
Provide comprehensive guidance for containerizing Java 25 applications using Docker best practices. Focus on creating efficient, secure, and maintainable Docker containers that leverage Java 25's latest features including Virtual Threads, improved container awareness, and modern JVM optimizations.
1414

15-
### Key Areas Covered:
16-
- **Multi-stage builds** for optimal image size and security
17-
- **Java 25 specific optimizations** including Virtual Threads and container-aware JVM settings
18-
- **Security hardening** with non-root users and minimal attack surface
19-
- **Performance tuning** for containerized Java applications
20-
- **Development workflow** optimization for faster iteration
21-
- **Production deployment** best practices
22-
- **Monitoring and observability** integration
15+
### Implementing These Principles
2316

17+
These guidelines are built upon the following core principles:
18+
19+
1. **Multi-Stage Build Optimization**: Separate build and runtime environments to create lean, secure final images. Use appropriate base images (JDK for build, JRE for runtime) and minimize the number of layers while maximizing Docker layer caching efficiency.
20+
21+
2. **Java 25 Container Awareness**: Leverage Java 25's enhanced container support with proper JVM configuration for containerized environments. Enable container-aware memory management, configure appropriate garbage collectors, and utilize Virtual Threads for I/O-intensive applications.
22+
23+
3. **Security-First Approach**: Implement defense-in-depth security practices including non-root users, read-only root filesystems, minimal attack surface, regular security scanning, and proper secrets management. Never embed sensitive information in Docker images.
24+
25+
4. **Performance and Resource Optimization**: Configure JVM settings for container resource limits, implement proper health checks, optimize image layers for faster builds and deployments, and use appropriate resource constraints in orchestration platforms.
26+
27+
5. **Development Workflow Enhancement**: Create development-friendly configurations with hot-reload capabilities, remote debugging support, and efficient local development environments using Docker Compose with proper volume mounts and networking.
28+
29+
6. **Production Readiness**: Implement comprehensive monitoring, logging, and observability features. Configure proper graceful shutdown handling, implement circuit breakers and timeouts, and ensure scalability with container orchestration platforms.
30+
31+
7. **Modern Java Features Integration**: Take advantage of Java 25's Virtual Threads, Pattern Matching, Records, and improved garbage collection algorithms. Configure JVM flags specifically for containerized environments using `JDK_JAVA_OPTIONS` environment variable for automatic application to all Java processes.
32+
33+
8. **Container Orchestration Best Practices**: Design containers for Kubernetes and other orchestration platforms with proper resource limits, health checks, service discovery, and configuration management through ConfigMaps and Secrets.
34+
35+
9. **Build and Deployment Pipeline**: Integrate Docker builds into CI/CD pipelines with proper image tagging strategies, security scanning, and multi-environment deployment configurations.
36+
37+
10. **Monitoring and Observability**: Implement comprehensive logging to stdout/stderr, expose metrics endpoints, configure distributed tracing, and integrate with monitoring solutions like Prometheus, Grafana, and APM tools.
2438

2539
## Constraints
2640

27-
Before applying Docker containerization, ensure the Java application builds successfully and follows Java 25 best practices.
41+
Before applying Docker containerization recommendations, ensure the Java application is in a valid state and follows Java 25 best practices. Application compilation failure is a BLOCKING condition that prevents any containerization work.
2842

29-
- **MANDATORY**: Verify the application builds with `./mvnw clean package` before containerization
30-
- **VERIFY**: Ensure Java 25 is properly configured in the project's pom.xml
31-
- **SECURITY**: Always use non-root users in production Docker images
32-
- **PERFORMANCE**: Configure JVM for container-aware memory management
33-
- **SAFETY**: Test Docker images locally before pushing to registries
43+
- **MANDATORY**: Run `./mvnw clean package` or `mvn clean package` before applying any Docker configuration
44+
- **PREREQUISITE**: Java application must compile successfully and pass basic validation checks before containerization
45+
- **CRITICAL SAFETY**: If compilation fails, IMMEDIATELY STOP and DO NOT CONTINUE with any Docker recommendations
46+
- **BLOCKING CONDITION**: Compilation errors must be resolved by the user before proceeding with any containerization improvements
47+
- **NO EXCEPTIONS**: Under no circumstances should Docker configurations be applied to a project that fails to compile
48+
- **SECURITY MANDATORY**: Always use non-root users in production Docker images - this is non-negotiable
49+
- **PERFORMANCE CRITICAL**: Configure JVM for container-aware memory management to prevent OOM kills
50+
- **VALIDATION REQUIRED**: Test Docker images locally with `docker build` and `docker run` before pushing to registries
3451

3552
## Examples
3653

@@ -46,7 +63,7 @@ Before applying Docker containerization, ensure the Java application builds succ
4663
### Example 1: Multi-Stage Dockerfile for Java 25 Applications
4764

4865
Title: Optimize build and runtime environments separately
49-
Description: Create efficient Docker images using multi-stage builds that separate the build environment from the runtime environment, leveraging Java 25 features.
66+
Description: Create efficient Docker images using multi-stage builds that separate the build environment from the runtime environment, leveraging Java 25 features. This approach: - Reduces final image size by excluding build tools and dependencies - Improves security by minimizing the attack surface in production images - Enables better layer caching for faster builds - Separates concerns between build-time and runtime requirements - Optimizes for Java 25's container-aware JVM features
5067

5168
**Good example:**
5269

@@ -83,15 +100,15 @@ COPY --from=build --chown=appuser:appuser /app/target/*.jar app.jar
83100
# Switch to non-root user
84101
USER appuser
85102

86-
# Configure JVM for containers and Java 25
87-
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseContainerSupport -XX:+ExitOnOutOfMemoryError"
103+
# Configure JVM for containers and Java 25 - automatically applied to all Java processes
104+
ENV JDK_JAVA_OPTIONS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseContainerSupport -XX:+ExitOnOutOfMemoryError"
88105

89106
# Health check
90107
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
91108
CMD curl -f http://localhost:8080/actuator/health || exit 1
92109

93110
EXPOSE 8080
94-
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
111+
ENTRYPOINT ["java", "-jar", "app.jar"]
95112

96113
```
97114

@@ -116,30 +133,20 @@ CMD ["java", "-jar", "target/*.jar"]
116133
### Example 2: Java 25 JVM Configuration for Containers
117134

118135
Title: Optimize JVM settings for containerized environments
119-
Description: Configure the JVM to work efficiently within container resource constraints, taking advantage of Java 25's container awareness and Virtual Threads.
136+
Description: Configure the JVM to work efficiently within container resource constraints, taking advantage of Java 25's container awareness and Virtual Threads. Key optimizations include: - Enabling container support for automatic memory detection - Configuring appropriate garbage collectors for containerized environments - Setting up Virtual Threads for improved I/O-intensive workload performance - Implementing proper JVM flags for container lifecycle management - Optimizing startup time and memory footprint
120137

121138
**Good example:**
122139

123140
```dockerfile
124-
# Java 25 optimized JVM configuration
125-
ENV JAVA_OPTS="\
126-
-Xms512m \
127-
-Xmx1024m \
128-
-XX:+UseG1GC \
129-
-XX:+UseContainerSupport \
130-
-XX:+ExitOnOutOfMemoryError \
131-
-XX:+UnlockExperimentalVMOptions \
132-
-Djdk.virtualThreadScheduler.parallelism=1 \
133-
-XX:+PrintGCDetails \
134-
-XX:+PrintGCTimeStamps \
135-
-Dfile.encoding=UTF-8"
141+
# Java 25 optimized JVM configuration - automatically applied to all Java processes
142+
ENV JDK_JAVA_OPTIONS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseContainerSupport -XX:+ExitOnOutOfMemoryError -XX:+UnlockExperimentalVMOptions -Djdk.virtualThreadScheduler.parallelism=1 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Dfile.encoding=UTF-8"
136143

137144
# Application-specific configuration
138145
ENV SPRING_PROFILES_ACTIVE=production
139146
ENV SERVER_PORT=8080
140147
ENV MANAGEMENT_PORT=9090
141148

142-
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
149+
ENTRYPOINT ["java", "-jar", "app.jar"]
143150

144151
```
145152

@@ -151,14 +158,15 @@ ENV JAVA_OPTS="-Xmx4g"
151158

152159
# Bad: No container awareness
153160
# Bad: No Virtual Threads optimization
161+
# Bad: Using JAVA_OPTS instead of JDK_JAVA_OPTIONS
154162
CMD ["java", "-Xmx4g", "-jar", "app.jar"]
155163

156164
```
157165

158166
### Example 3: Security Hardening for Docker Images
159167

160168
Title: Implement security best practices for production containers
161-
Description: Enhance container security by following the principle of least privilege and implementing defense-in-depth strategies.
169+
Description: Enhance container security by following the principle of least privilege and implementing defense-in-depth strategies. Security measures include: - Creating and using non-root users with minimal privileges - Implementing read-only root filesystems where possible - Removing unnecessary packages and tools from production images - Using proper signal handling with init systems like tini - Implementing security labels and metadata for compliance - Regular security scanning and vulnerability management
162170

163171
**Good example:**
164172

@@ -233,15 +241,14 @@ RUN ./mvnw dependency:resolve
233241
# Create volumes for source code and target
234242
VOLUME ["/app/src", "/app/target"]
235243

236-
# Enable remote debugging
237-
ENV JAVA_DEBUG_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
238-
ENV JAVA_OPTS="$JAVA_DEBUG_OPTS -XX:+UseG1GC"
244+
# Enable remote debugging and development optimizations
245+
ENV JDK_JAVA_OPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -XX:+UseG1GC"
239246

240247
# Expose application and debug ports
241248
EXPOSE 8080 5005
242249

243250
# Use Spring Boot DevTools for hot reload
244-
CMD ["./mvnw", "spring-boot:run", "-Dspring-boot.run.jvmArguments='$JAVA_OPTS'"]
251+
CMD ["./mvnw", "spring-boot:run"]
245252

246253
```
247254

@@ -370,7 +377,7 @@ spec:
370377
- containerPort: 8080
371378
- containerPort: 9090 # Management port
372379
env:
373-
- name: JAVA_OPTS
380+
- name: JDK_JAVA_OPTIONS
374381
value: "-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseContainerSupport"
375382
- name: SPRING_PROFILES_ACTIVE
376383
value: "production"
@@ -444,4 +451,5 @@ spec:
444451
- Use specific version tags instead of 'latest' for base images in production
445452
- Implement proper resource limits to prevent resource exhaustion
446453
- Configure health checks for all production deployments
447-
- Use read-only root filesystems when possible for enhanced security
454+
- Use read-only root filesystems when possible for enhanced security
455+
- Prefer JDK_JAVA_OPTIONS over JAVA_OPTS for automatic JVM configuration in containers

system-prompts-generator/src/main/resources/130-java-docker-best-practices.xml

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
6. **Production Readiness**: Implement comprehensive monitoring, logging, and observability features. Configure proper graceful shutdown handling, implement circuit breakers and timeouts, and ensure scalability with container orchestration platforms.
3434

35-
7. **Modern Java Features Integration**: Take advantage of Java 25's Virtual Threads, Pattern Matching, Records, and improved garbage collection algorithms. Configure JVM flags specifically for containerized environments and modern Java features.
35+
7. **Modern Java Features Integration**: Take advantage of Java 25's Virtual Threads, Pattern Matching, Records, and improved garbage collection algorithms. Configure JVM flags specifically for containerized environments using `JDK_JAVA_OPTIONS` environment variable for automatic application to all Java processes.
3636

3737
8. **Container Orchestration Best Practices**: Design containers for Kubernetes and other orchestration platforms with proper resource limits, health checks, service discovery, and configuration management through ConfigMaps and Secrets.
3838

@@ -110,15 +110,15 @@ COPY --from=build --chown=appuser:appuser /app/target/*.jar app.jar
110110
# Switch to non-root user
111111
USER appuser
112112

113-
# Configure JVM for containers and Java 25
114-
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseContainerSupport -XX:+ExitOnOutOfMemoryError"
113+
# Configure JVM for containers and Java 25 - automatically applied to all Java processes
114+
ENV JDK_JAVA_OPTIONS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseContainerSupport -XX:+ExitOnOutOfMemoryError"
115115

116116
# Health check
117117
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
118118
CMD curl -f http://localhost:8080/actuator/health || exit 1
119119

120120
EXPOSE 8080
121-
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
121+
ENTRYPOINT ["java", "-jar", "app.jar"]
122122
</code-block>
123123
</good-example>
124124
<bad-example>
@@ -158,25 +158,15 @@ CMD ["java", "-jar", "target/*.jar"]
158158
<code-examples>
159159
<good-example>
160160
<code-block language="dockerfile">
161-
# Java 25 optimized JVM configuration
162-
ENV JAVA_OPTS="\
163-
-Xms512m \
164-
-Xmx1024m \
165-
-XX:+UseG1GC \
166-
-XX:+UseContainerSupport \
167-
-XX:+ExitOnOutOfMemoryError \
168-
-XX:+UnlockExperimentalVMOptions \
169-
-Djdk.virtualThreadScheduler.parallelism=1 \
170-
-XX:+PrintGCDetails \
171-
-XX:+PrintGCTimeStamps \
172-
-Dfile.encoding=UTF-8"
161+
# Java 25 optimized JVM configuration - automatically applied to all Java processes
162+
ENV JDK_JAVA_OPTIONS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseContainerSupport -XX:+ExitOnOutOfMemoryError -XX:+UnlockExperimentalVMOptions -Djdk.virtualThreadScheduler.parallelism=1 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Dfile.encoding=UTF-8"
173163

174164
# Application-specific configuration
175165
ENV SPRING_PROFILES_ACTIVE=production
176166
ENV SERVER_PORT=8080
177167
ENV MANAGEMENT_PORT=9090
178168

179-
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
169+
ENTRYPOINT ["java", "-jar", "app.jar"]
180170
</code-block>
181171
</good-example>
182172
<bad-example>
@@ -185,7 +175,8 @@ ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
185175
ENV JAVA_OPTS="-Xmx4g"
186176

187177
# Bad: No container awareness
188-
# Bad: No Virtual Threads optimization
178+
# Bad: No Virtual Threads optimization
179+
# Bad: Using JAVA_OPTS instead of JDK_JAVA_OPTIONS
189180
CMD ["java", "-Xmx4g", "-jar", "app.jar"]
190181
</code-block>
191182
</bad-example>
@@ -284,15 +275,14 @@ RUN ./mvnw dependency:resolve
284275
# Create volumes for source code and target
285276
VOLUME ["/app/src", "/app/target"]
286277

287-
# Enable remote debugging
288-
ENV JAVA_DEBUG_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
289-
ENV JAVA_OPTS="$JAVA_DEBUG_OPTS -XX:+UseG1GC"
278+
# Enable remote debugging and development optimizations
279+
ENV JDK_JAVA_OPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -XX:+UseG1GC"
290280

291281
# Expose application and debug ports
292282
EXPOSE 8080 5005
293283

294284
# Use Spring Boot DevTools for hot reload
295-
CMD ["./mvnw", "spring-boot:run", "-Dspring-boot.run.jvmArguments='$JAVA_OPTS'"]
285+
CMD ["./mvnw", "spring-boot:run"]
296286
</code-block>
297287
</good-example>
298288
<bad-example>
@@ -427,7 +417,7 @@ spec:
427417
- containerPort: 8080
428418
- containerPort: 9090 # Management port
429419
env:
430-
- name: JAVA_OPTS
420+
- name: JDK_JAVA_OPTIONS
431421
value: "-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseContainerSupport"
432422
- name: SPRING_PROFILES_ACTIVE
433423
value: "production"
@@ -506,6 +496,7 @@ spec:
506496
<safeguards-item>Implement proper resource limits to prevent resource exhaustion</safeguards-item>
507497
<safeguards-item>Configure health checks for all production deployments</safeguards-item>
508498
<safeguards-item>Use read-only root filesystems when possible for enhanced security</safeguards-item>
499+
<safeguards-item>Prefer JDK_JAVA_OPTIONS over JAVA_OPTS for automatic JVM configuration in containers</safeguards-item>
509500
</safeguards-list>
510501
</safeguards>
511502

0 commit comments

Comments
 (0)