Skip to content

Commit 32d996d

Browse files
cursoragentjabrena
andcommitted
feat: Add Java Docker best practices XML
Co-authored-by: bren <bren@juanantonio.info>
1 parent 76a79e5 commit 32d996d

File tree

1 file changed

+354
-0
lines changed

1 file changed

+354
-0
lines changed
Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<cursor_rules>
3+
<title>Docker Best Practices for Java 25 Applications</title>
4+
<description>
5+
Comprehensive guidelines for containerizing Java 25 applications using Docker, focusing on performance optimization, security enhancements, and efficient resource utilization.
6+
</description>
7+
8+
<rules>
9+
<rule>
10+
<title>Use Appropriate Base Images</title>
11+
<description>
12+
Select the most suitable base image for your Java 25 application, considering size, security, and compatibility requirements.
13+
</description>
14+
<guidelines>
15+
<guideline>Use `eclipse-temurin:25-jre-alpine` for minimal production images</guideline>
16+
<guideline>Use `eclipse-temurin:25-jdk-alpine` only when JDK tools are required at runtime</guideline>
17+
<guideline>Prefer Alpine Linux variants for smaller image sizes</guideline>
18+
<guideline>Use specific version tags instead of `latest` for reproducible builds</guideline>
19+
</guidelines>
20+
<example>
21+
<![CDATA[
22+
# Production runtime image
23+
FROM eclipse-temurin:25-jre-alpine
24+
25+
# Development/build image
26+
FROM eclipse-temurin:25-jdk-alpine AS build
27+
]]>
28+
</example>
29+
</rule>
30+
31+
<rule>
32+
<title>Implement Multi-Stage Builds</title>
33+
<description>
34+
Separate the build environment from the runtime environment to create lean, secure final images by excluding unnecessary build tools and dependencies.
35+
</description>
36+
<guidelines>
37+
<guideline>Use a build stage with JDK for compilation</guideline>
38+
<guideline>Use a runtime stage with JRE for execution</guideline>
39+
<guideline>Copy only necessary artifacts between stages</guideline>
40+
<guideline>Minimize the number of layers in the final image</guideline>
41+
</guidelines>
42+
<example>
43+
<![CDATA[
44+
# Build stage
45+
FROM eclipse-temurin:25-jdk-alpine AS build
46+
WORKDIR /app
47+
COPY pom.xml .
48+
COPY src ./src
49+
RUN ./mvnw clean package -DskipTests
50+
51+
# Runtime stage
52+
FROM eclipse-temurin:25-jre-alpine
53+
WORKDIR /app
54+
COPY --from=build /app/target/*.jar app.jar
55+
EXPOSE 8080
56+
ENTRYPOINT ["java", "-jar", "app.jar"]
57+
]]>
58+
</example>
59+
</rule>
60+
61+
<rule>
62+
<title>Optimize JVM Configuration for Containers</title>
63+
<description>
64+
Configure the JVM to work efficiently within container resource constraints, taking advantage of Java 25's container awareness features.
65+
</description>
66+
<guidelines>
67+
<guideline>Use `-XX:+UseContainerSupport` to enable container awareness (enabled by default in Java 25)</guideline>
68+
<guideline>Set appropriate heap size using `-Xms` and `-Xmx` based on container memory limits</guideline>
69+
<guideline>Use `-XX:+UseG1GC` for better performance in containerized environments</guideline>
70+
<guideline>Enable JVM ergonomics with `-XX:+UnlockExperimentalVMOptions` for Java 25 features</guideline>
71+
<guideline>Use `-XX:+ExitOnOutOfMemoryError` to ensure container restart on OOM</guideline>
72+
</guidelines>
73+
<example>
74+
<![CDATA[
75+
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseContainerSupport -XX:+ExitOnOutOfMemoryError"
76+
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
77+
]]>
78+
</example>
79+
</rule>
80+
81+
<rule>
82+
<title>Implement Security Best Practices</title>
83+
<description>
84+
Enhance container security by following the principle of least privilege and implementing defense-in-depth strategies.
85+
</description>
86+
<guidelines>
87+
<guideline>Create and use a non-root user for running the application</guideline>
88+
<guideline>Use read-only root filesystem when possible</guideline>
89+
<guideline>Minimize the attack surface by removing unnecessary packages</guideline>
90+
<guideline>Scan images for vulnerabilities regularly</guideline>
91+
<guideline>Use secrets management for sensitive data</guideline>
92+
</guidelines>
93+
<example>
94+
<![CDATA[
95+
# Create non-root user
96+
RUN adduser --disabled-password --gecos "" --uid 1001 appuser
97+
98+
# Set ownership and permissions
99+
COPY --chown=appuser:appuser app.jar /app/app.jar
100+
101+
# Switch to non-root user
102+
USER appuser
103+
104+
# Use read-only filesystem
105+
# docker run --read-only --tmpfs /tmp myapp:latest
106+
]]>
107+
</example>
108+
</rule>
109+
110+
<rule>
111+
<title>Optimize Image Layers and Caching</title>
112+
<description>
113+
Structure Dockerfile commands to maximize Docker layer caching and minimize image size.
114+
</description>
115+
<guidelines>
116+
<guideline>Order commands from least to most frequently changing</guideline>
117+
<guideline>Copy dependency files before source code to leverage cache</guideline>
118+
<guideline>Combine related RUN commands to reduce layers</guideline>
119+
<guideline>Use `.dockerignore` to exclude unnecessary files</guideline>
120+
<guideline>Clean up package caches and temporary files in the same layer</guideline>
121+
</guidelines>
122+
<example>
123+
<![CDATA[
124+
# Copy dependency files first for better caching
125+
COPY pom.xml ./
126+
COPY mvnw ./
127+
COPY .mvn ./.mvn
128+
129+
# Download dependencies (cached layer)
130+
RUN ./mvnw dependency:resolve
131+
132+
# Copy source code (changes more frequently)
133+
COPY src ./src
134+
135+
# Build application
136+
RUN ./mvnw clean package -DskipTests && \
137+
rm -rf ~/.m2/repository && \
138+
rm -rf target/classes target/generated-sources
139+
]]>
140+
</example>
141+
</rule>
142+
143+
<rule>
144+
<title>Configure Health Checks and Monitoring</title>
145+
<description>
146+
Implement comprehensive health checking and monitoring to ensure application reliability and observability.
147+
</description>
148+
<guidelines>
149+
<guideline>Define Docker health checks for container orchestration</guideline>
150+
<guideline>Implement application health endpoints</guideline>
151+
<guideline>Configure proper logging to stdout/stderr</guideline>
152+
<guideline>Use structured logging formats (JSON) for better parsing</guideline>
153+
<guideline>Include JVM metrics and garbage collection monitoring</guideline>
154+
</guidelines>
155+
<example>
156+
<![CDATA[
157+
# Docker health check
158+
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
159+
CMD curl -f http://localhost:8080/actuator/health || exit 1
160+
161+
# Application health endpoint (Spring Boot example)
162+
# management.endpoints.web.exposure.include=health,metrics,info
163+
# management.endpoint.health.show-details=always
164+
165+
# JVM monitoring flags
166+
ENV JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"
167+
]]>
168+
</example>
169+
</rule>
170+
171+
<rule>
172+
<title>Manage Configuration and Secrets</title>
173+
<description>
174+
Externalize configuration and handle secrets securely to support different deployment environments.
175+
</description>
176+
<guidelines>
177+
<guideline>Use environment variables for configuration</guideline>
178+
<guideline>Support configuration files mounted as volumes</guideline>
179+
<guideline>Never embed secrets in Docker images</guideline>
180+
<guideline>Use Docker secrets or external secret management</guideline>
181+
<guideline>Implement configuration validation at startup</guideline>
182+
</guidelines>
183+
<example>
184+
<![CDATA[
185+
# Environment-based configuration
186+
ENV SPRING_PROFILES_ACTIVE=production
187+
ENV SERVER_PORT=8080
188+
ENV MANAGEMENT_PORT=9090
189+
190+
# Support for external configuration
191+
VOLUME ["/app/config"]
192+
193+
# Configuration precedence: env vars > mounted files > defaults
194+
ENTRYPOINT ["java", "-Dspring.config.location=classpath:/,file:/app/config/", "-jar", "app.jar"]
195+
]]>
196+
</example>
197+
</rule>
198+
199+
<rule>
200+
<title>Optimize for Different Deployment Scenarios</title>
201+
<description>
202+
Create flexible Docker configurations that work well across development, testing, and production environments.
203+
</description>
204+
<guidelines>
205+
<guideline>Use build arguments for environment-specific customization</guideline>
206+
<guideline>Support both standalone and orchestrated deployments</guideline>
207+
<guideline>Implement graceful shutdown handling</guideline>
208+
<guideline>Configure appropriate resource limits and requests</guideline>
209+
<guideline>Use init systems for proper signal handling in containers</guideline>
210+
</guidelines>
211+
<example>
212+
<![CDATA[
213+
# Build arguments for flexibility
214+
ARG JAVA_OPTS_BUILD=""
215+
ARG APP_VERSION="latest"
216+
217+
# Graceful shutdown support
218+
ENV JAVA_OPTS="$JAVA_OPTS -Dserver.shutdown=graceful"
219+
220+
# Signal handling for proper shutdown
221+
RUN apk add --no-cache tini
222+
ENTRYPOINT ["tini", "--"]
223+
CMD ["java", "-jar", "app.jar"]
224+
225+
# Resource limits in deployment
226+
# resources:
227+
# limits:
228+
# memory: "1Gi"
229+
# cpu: "1000m"
230+
# requests:
231+
# memory: "512Mi"
232+
# cpu: "500m"
233+
]]>
234+
</example>
235+
</rule>
236+
237+
<rule>
238+
<title>Leverage Java 25 Specific Features</title>
239+
<description>
240+
Take advantage of Java 25's latest features and improvements for better container performance and developer experience.
241+
</description>
242+
<guidelines>
243+
<guideline>Use Virtual Threads for improved scalability in I/O-intensive applications</guideline>
244+
<guideline>Leverage Pattern Matching and Switch Expressions for cleaner code</guideline>
245+
<guideline>Use Record Classes for data transfer objects</guideline>
246+
<guideline>Take advantage of improved garbage collection algorithms</guideline>
247+
<guideline>Use Text Blocks for embedded configuration or SQL</guideline>
248+
</guidelines>
249+
<example>
250+
<![CDATA[
251+
# Enable Virtual Threads (if using frameworks that support them)
252+
ENV JAVA_OPTS="$JAVA_OPTS -Djdk.virtualThreadScheduler.parallelism=1"
253+
254+
# Example of Java 25 features in application code:
255+
# public record UserRequest(String name, int age) {}
256+
#
257+
# public String processUser(Object obj) {
258+
# return switch (obj) {
259+
# case UserRequest(var name, var age) when age >= 18 ->
260+
# "Adult user: " + name;
261+
# case UserRequest(var name, var age) ->
262+
# "Minor user: " + name;
263+
# default -> "Unknown type";
264+
# };
265+
# }
266+
]]>
267+
</example>
268+
</rule>
269+
270+
<rule>
271+
<title>Implement Efficient Development Workflow</title>
272+
<description>
273+
Create Docker configurations that support efficient development cycles and debugging capabilities.
274+
</description>
275+
<guidelines>
276+
<guideline>Use Docker Compose for local development environments</guideline>
277+
<guideline>Implement hot-reload capabilities for development</guideline>
278+
<guideline>Support remote debugging configurations</guideline>
279+
<guideline>Create separate profiles for development and production</guideline>
280+
<guideline>Use volume mounts for rapid iteration during development</guideline>
281+
</guidelines>
282+
<example>
283+
<![CDATA[
284+
# Development Dockerfile
285+
FROM eclipse-temurin:25-jdk-alpine AS development
286+
WORKDIR /app
287+
COPY pom.xml .
288+
RUN ./mvnw dependency:resolve
289+
VOLUME ["/app/src", "/app/target"]
290+
EXPOSE 8080 5005
291+
ENV JAVA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
292+
CMD ["./mvnw", "spring-boot:run"]
293+
294+
# docker-compose.yml for development
295+
# version: '3.8'
296+
# services:
297+
# app:
298+
# build:
299+
# context: .
300+
# target: development
301+
# ports:
302+
# - "8080:8080"
303+
# - "5005:5005"
304+
# volumes:
305+
# - ./src:/app/src
306+
# - ./target:/app/target
307+
]]>
308+
</example>
309+
</rule>
310+
</rules>
311+
312+
<anti_patterns>
313+
<anti_pattern>
314+
<title>Using Root User in Production</title>
315+
<description>Running applications as root user increases security risks</description>
316+
<example>USER root # AVOID THIS</example>
317+
</anti_pattern>
318+
319+
<anti_pattern>
320+
<title>Installing Unnecessary Packages</title>
321+
<description>Including development tools and unnecessary packages in production images</description>
322+
<example>RUN apk add --no-cache curl wget vim git # AVOID UNNECESSARY TOOLS</example>
323+
</anti_pattern>
324+
325+
<anti_pattern>
326+
<title>Hardcoding Configuration</title>
327+
<description>Embedding environment-specific configuration in Docker images</description>
328+
<example>ENV DATABASE_URL=prod.db.example.com # AVOID HARDCODING</example>
329+
</anti_pattern>
330+
331+
<anti_pattern>
332+
<title>Ignoring JVM Container Settings</title>
333+
<description>Not configuring JVM for container resource limits</description>
334+
<example>java -Xmx4g -jar app.jar # AVOID FIXED HEAP SIZES</example>
335+
</anti_pattern>
336+
337+
<anti_pattern>
338+
<title>Using Latest Tags in Production</title>
339+
<description>Using unstable or latest tags for base images in production</description>
340+
<example>FROM eclipse-temurin:latest # AVOID LATEST TAG</example>
341+
</anti_pattern>
342+
</anti_patterns>
343+
344+
<best_practices_summary>
345+
<practice>Use multi-stage builds with appropriate base images</practice>
346+
<practice>Configure JVM for container environments</practice>
347+
<practice>Implement security best practices with non-root users</practice>
348+
<practice>Optimize Docker layers and caching strategies</practice>
349+
<practice>Configure comprehensive health checks and monitoring</practice>
350+
<practice>Externalize configuration and manage secrets properly</practice>
351+
<practice>Leverage Java 25 specific features and improvements</practice>
352+
<practice>Support efficient development workflows</practice>
353+
</best_practices_summary>
354+
</cursor_rules>

0 commit comments

Comments
 (0)