Docker Spring Boot – hello world 最佳实践 🐳☕

从零开始将一个Spring Boot应用容器化并成功部署的完整实践记录

🎯 项目概述

这是一个完整的Spring Boot容器化实践项目,涵盖了从代码开发到Docker部署的全流程。项目成功实现了:

  • ✅ Spring Boot Web应用开发
  • ✅ Docker容器化打包
  • ✅ JVM参数优化配置
  • ✅ 生产级健康检查
  • ✅ 内存监控接口

📋 项目结构

SpringBootForDocker/
├── Dockerfile                    # 多阶段构建配置
├── pom.xml                      # Maven依赖管理
├── src/
│   └── main/
│       ├── java/prj/
│       │   ├── SpringBootApp.java     # 主启动类
│       │   └── Controller.java        # REST控制器
│       └── resources/
│           ├── application.yaml       # 应用配置
└── target/                      # 构建输出目录

🚀 核心功能实现

1. 基础REST接口

@RestController
public class Controller {
    @RequestMapping("/sayHello")
    public String sayHello(){
        return "Say Hello By Docker.";
    }
}

2. 内存监控接口

@GetMapping("/memory")
public Map<String, Object> memoryInfo() {
    Map<String, Object> info = new HashMap<>();

    // 堆内存信息
    MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
    info.put("heap.used", heapUsage.getUsed() / 1024 / 1024 + "MB");
    info.put("heap.max", heapUsage.getMax() / 1024 / 1024 + "MB");

    // 非堆内存信息
    MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();
    info.put("nonHeap.used", nonHeapUsage.getUsed() / 1024 / 1024 + "MB");

    return info;
}

🐳 Docker容器化配置

多阶段构建优化

# 构建阶段
FROM maven:3.8.6-openjdk-11-slim AS build
WORKDIR /app
COPY pom.xml .
# 利用层缓存优化依赖下载
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn package -DskipTests

# 运行阶段 - 使用Eclipse Temurin + Ubuntu 22.04
FROM eclipse-temurin:11-jre-jammy
WORKDIR /app

# 安全加固:非root用户运行
RUN groupadd -r appuser && useradd -r -g appuser appuser
COPY --from=build /app/target/SpringBootForDocker-1.0-SNAPSHOT.jar app.jar
RUN chown appuser:appuser app.jar
USER appuser

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 
  CMD curl -f http://localhost:8080/actuator/health || exit 1

EXPOSE 8080

JVM生产级参数优化

ENTRYPOINT ["java", 
    "-XX:+UseContainerSupport",           # 容器感知
    "-XX:MaxRAMPercentage=60.0",         # 动态内存分配
    "-XX:InitialRAMPercentage=50.0",     # 初始堆内存
    "-XX:ThreadStackSize=256k",          # 线程栈优化
    "-XX:MaxMetaspaceSize=256m",         # 元空间限制
    "-XX:ReservedCodeCacheSize=128m",    # 代码缓存限制
    "-Djava.security.egd=file:/dev/./urandom",   # 非阻塞随机数
    "-jar", "app.jar"]

📊 内存分配策略

假设容器内存限制为2GB时的分配情况:

容器总内存: 2048MB
├── 堆内存 (60%): 1228MB
│   ├── 年轻代: ~400MB
│   └── 老年代: ~800MB
├── 非堆内存: ~600MB
│   ├── 元空间: ~150MB (最大256MB)
│   ├── 代码缓存: ~80MB (最大128MB)
│   ├── 线程栈: ~250MB (1000线程×256KB)
│   └── GC/其他: ~120MB
└── 系统保留: ~220MB

🏗️ 构建和部署流程

1. Docker镜像构建

docker build -t springboot-docker-app .

2. 容器运行

docker run -d -p 8080:8080 --memory=2g --name springboot-app springboot-docker-app

3. 接口测试

# 基础接口测试
curl http://localhost:8080/sayHello
# 返回: Say Hello By Docker.

# 内存监控接口
curl http://localhost:8080/memory
# 返回: {"heap.used":"45MB", "heap.max":"1200MB", "nonHeap.used":"25MB"}

🔍 关键技术要点

1. 基础镜像选择策略

  • 构建阶段: maven:3.8.6-openjdk-11-slim – 提供Maven构建环境
  • 运行阶段: eclipse-temurin:11-jre-jammy – Ubuntu 22.04 LTS,工具齐全且稳定

2. 安全最佳实践

  • 使用非root用户运行应用
  • 最小权限原则
  • 健康检查端点暴露

3. 性能优化要点

  • 容器感知的JVM参数配置
  • 合理的内存分配比例
  • 线程栈大小优化
  • 非阻塞随机数生成器

4. 构建优化技巧

  • 多阶段构建减少镜像体积
  • 层缓存利用避免重复下载依赖
  • 基础镜像版本锁定确保一致性

📈 项目成果

镜像大小: ~200MB (优化后)
启动时间: < 3秒
内存效率: 60%堆内存利用率
安全等级: 生产级安全加固
监控能力: 实时内存监控接口

🎯 经验总结

这个项目成功展示了Spring Boot应用容器化的完整流程,重点解决了:

  1. 构建效率: 通过层缓存优化避免重复依赖下载
  2. 资源优化: 合理的JVM内存分配策略
  3. 安全加固: 非root用户和最小权限原则
  4. 可观测性: 内置健康检查和监控接口
  5. 生产就绪: 完整的错误处理和恢复机制

这个项目为后续微服务架构和云原生部署奠定了坚实基础!


技术栈: Spring Boot 2.6.6 + Docker + Eclipse Temurin + Ubuntu 22.04

项目特点: 轻量级 + 高可用 + 易监控 + 生产就绪

留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注