Tối ưu Docker cho Java
Phân tích các kỹ thuật tối ưu Dockerfile từ Dockerfile Contest 2025 cho ứng dụng Java Spring Boot.
Dockerfile Contest 2025 – Java tối ưu extreme
Dockerfile Contest 2025 thúc đẩy cộng đồng DevOps Việt Nam đánh giá lại cách viết Dockerfile để đạt bảo mật, tối ưu, tường minh. Bài viết này tổng hợp riêng cho hạng mục Java Spring Boot, nơi các tác giả tập trung tối ưu JRE, giảm kích thước image và chuẩn hóa quy trình build.
I. Hạng mục JAVA (Spring Boot Service)
Hạng mục Java tập trung vào các ý tưởng:
- Tối ưu JRE: dùng
jlinkvàjdepsđể tạo custom JRE chỉ chứa module cần thiết. - Tối ưu security & dependency: tự động cập nhật dependency an toàn, giảm CVE.
- Multi-stage build: tách rõ stage build và runtime, dùng distroless hoặc base image tối ưu.
- Healthcheck rõ ràng: dùng
wgethoặc Java native healthcheck để giám sát container.
Dockerfile TOP 1 (Java) – Spring Boot Template + Distroless
| Kỹ thuật | Giải thích theo tác giả | Nguồn tham khảo |
|---|---|---|
| Custom JRE bằng jlink | Dùng jdeps phân tích fat JAR để lấy danh sách module, sau đó jlink tạo JRE chỉ chứa module cần, giảm đáng kể kích thước runtime. | |
| Multi-stage build rõ ràng | Stage build dùng eclipse-temurin:21-jdk để build Gradle; stage runtime dùng gcr.io/distroless/base-debian12 chỉ chạy JRE. | |
| Phân tách Healthcheck Stage | Tạo stage healthcheck dùng BusyBox, copy wget vào runtime để healthcheck mà không phải cài thêm full curl/wget từ package manager. | |
| Distroless Runtime | Dùng distroless base để giảm attack surface (không shell, không package manager), image gọn và an toàn hơn. | |
| Pin nguồn & license | Thêm LABEL org.opencontainers.image.source, version, licenses để dễ truy vết source code và tuân thủ license. |
Dockerfile TOP 1 (JAVA)
| |
Dockerfile TOP 2 (Java) – Gradle Auto Dependency Update + Custom Healthcheck
| Kỹ thuật | Giải thích theo tác giả | Nguồn tham khảo |
|---|---|---|
| Gradle Dependency Updates | Dùng plugin dependencyUpdates để sinh report, sau đó script shell parse report và tự động update version plugin/ext/dependency trong build.gradle. | |
| Force Dependency Upgrade | Biến DEPENDENCIES_FORCE_UPDATE cho phép chỉ định group:name:version để ép cập nhật những dependency quan trọng, thường là những lib dính CVE. | |
| Native Java Healthcheck | Viết class HealthCheck.java dùng HttpURLConnection gọi /health, giúp healthcheck không phụ thuộc curl/wget. | |
| Distroless Base Java | Runtime dùng hmctspublic.azurecr.io/base/java:21-distroless, image Java 21 tối ưu sẵn cho production. | |
| Cache Gradle | Mount cache /root/.gradle để tăng tốc ./gradlew trong stage build. |
Dockerfile TOP 2 (JAVA)
| |
Dockerfile TOP (Java) – Dung Cao (Alpine JDK/JRE tối ưu)
| Kỹ thuật | Giải thích theo tác giả | Nguồn tham khảo |
|---|---|---|
| Tách riêng JDK/JRE bằng ARG | Dùng ARG BUILD_JDK_IMAGE và RUNTIME_IMAGE để dễ đổi base image (JDK cho build, JRE cho runtime), vẫn giữ Dockerfile đơn giản. | |
| Gradle cache với BuildKit | Dùng --mount=type=cache,target=/cache/.gradle cho các lệnh ./gradlew để tối ưu thời gian build lặp lại. | |
| Không chạy test trong build image | bootJar -x test giúp build nhanh hơn cho môi trường CI/CD và Docker contest (ưu tiên ra artifact). | |
| Non-root user + chown | Tạo user/group app, --chown=app:app khi copy JAR đảm bảo runtime an toàn, tuân CIS Docker Benchmark. | |
| Healthcheck với curl | Cài curl (apk add –no-cache) rồi dùng curl -fsS tới /health cho healthcheck rõ ràng, dễ debug. | |
| JVM tuning cho container | JAVA_OPTS bật UseContainerSupport, MaxRAMPercentage=75, G1GC, ExitOnOutOfMemoryError, heap dump path… giúp JVM hiểu giới hạn container và fail-fast khi OOM. |
Dockerfile TOP (JAVA) – Dung Cao
| |
Dockerfile TOP (tham khảo – Java) – HMCTS Spring Boot Template (Layered + jlink)
| Kỹ thuật | Giải thích theo tác giả | Nguồn tham khảo |
|---|---|---|
| Gradle cache + tách layer | Dùng BuildKit cache id=gradle-cache cho Gradle, sau đó dùng jarmode=layertools để extract các lớp dependencies, spring-boot-loader, snapshot-dependencies, application giúp cache Docker layer tối đa. | |
| Custom JRE với jlink | Chạy jlink với danh sách module Java chọn tay để tạo JRE tối thiểu (/jre-minimal), giảm hơn 100MB so với JDK full. | |
| Alpine runtime tối thiểu | Runtime base alpine:3.21 chỉ cài ca-certificates, tzdata, tini, curl, sau đó chạy với non-root appuser. | |
| JAVA_TOOL_OPTIONS cho container | Tối ưu JVM: UseContainerSupport, MaxRAMPercentage, UseG1GC, UseStringDeduplication, ExitOnOutOfMemoryError,… để tối ưu memory & GC trong container. | |
| OCI labels rất đầy đủ | Ghi rõ vendor, authors, source, version, revision, base.name, base.digest, com.hmcts.*… giúp traceability cho tổ chức. | |
| Healthcheck dùng curl | Healthcheck /health qua curl -f, retry có cấu hình hợp lý cho Spring Boot khởi động. |
Dockerfile TOP (tham khảo – JAVA) – HMCTS Spring Boot Template
| |
Ghi chú triển khai
- Khi áp dụng cho dự án Java của bạn, hãy giữ nguyên các nguyên tắc chính mà các Dockerfile trên thể hiện:
- Multi-stage build rõ ràng (builder + runtime).
- Tối ưu JRE (dùng
jdeps+jlink, base image Java distroless hoặc JRE-only image). - Healthcheck rõ ràng (native Java hoặc wget/curl).
- Tối ưu dependency (tự động hoặc thủ công) để giảm CVE.
- Khi copy template về dự án riêng, bạn nên:
- Cập nhật lại
LABEL org.opencontainers.image.sourcecho đúng repository của bạn. - Điều chỉnh endpoint healthcheck (
/health,/actuator/health…) cho trùng với app thực tế. - Thử build và scan image với các tool như Trivy để kiểm tra security sau khi tối ưu.
- Cập nhật lại
THẢO LUẬN & BÌNH LUẬN
