当前位置: 首页 > news >正文

【Docker实战】Spring Boot应用容器化

Docker实战:Spring Boot应用容器化

以"Spring Boot + MySQL"为例,详细讲解容器化部署的关键步骤,重点关注多阶段构建、环境配置与网络通信等核心要点。适用于企业级应用部署参考。

1. 项目结构

springboot-demo/
├── Dockerfile       # 多阶段构建脚本(定义镜像构建流程,包含编译和运行阶段)
├── pom.xml          # Maven依赖配置(管理Java项目第三方库及版本)
├── src/             # 业务代码(包含Controller、Service、Entity等核心逻辑)
├── application.yml  # 应用配置(基础参数设置,支持通过环境变量动态覆盖)
└── entrypoint.sh    # 启动脚本(检查MySQL依赖就绪状态并注入环境变量)

2. 多阶段Dockerfile构建

# 阶段1:代码编译(使用maven镜像编译代码并提取分层依赖)
FROM maven:3.8.6-openjdk-11 AS builder
WORKDIR /app# 缓存依赖(当pom.xml不变时复用缓存,避免重复下载)
COPY pom.xml .
RUN mvn dependency:go-offline# 复制源代码并编译打包
COPY src ./src
RUN mvn package -DskipTests && \# 提取Spring Boot分层文件(优化镜像层缓存,仅更新变动层)java -Djarmode=layertools -jar target/*.jar extract# 阶段2:运行环境(仅包含运行时必需组件,大幅减小镜像体积)
FROM openjdk:11-jre-slim
WORKDIR /app# 按变更频率排序复制分层文件,优化缓存利用率
COPY --from=builder /app/dependencies/ ./
COPY --from=builder /app/spring-boot-loader/ ./
COPY --from=builder /app/snapshot-dependencies/ ./
COPY --from=builder /app/application/ ./# 配置启动脚本
COPY entrypoint.sh .
RUN chmod +x entrypoint.sh# 声明应用端口
EXPOSE 8080# 容器启动入口
ENTRYPOINT ["./entrypoint.sh"]

3. 启动脚本(依赖检查)

#!/bin/bash
set -e  # 脚本执行出错时立即退出# 等待MySQL服务就绪(避免应用启动时数据库未初始化完成)
echo "等待MySQL服务: $MYSQL_HOST:$MYSQL_PORT"
while ! nc -z $MYSQL_HOST $MYSQL_PORT; dosleep 1  # 每1秒检查一次连接
done
echo "MySQL服务已就绪,启动应用..."# 启动Spring Boot应用(通过环境变量注入数据库配置)
exec java org.springframework.boot.loader.JarLauncher \--spring.datasource.url=jdbc:mysql://$MYSQL_HOST:$MYSQL_PORT/$MYSQL_DATABASE?useSSL=false&serverTimezone=UTC \--spring.datasource.username=$MYSQL_USER \--spring.datasource.password=$MYSQL_PASSWORD

4. 应用配置(环境变量覆盖)

server:port: 8080  # 应用监听端口spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driver# 数据库默认配置(可被环境变量覆盖)url: jdbc:mysql://localhost:3306/defaultdb?useSSL=false&serverTimezone=UTCusername: rootpassword: passwordjpa:hibernate:ddl-auto: update  # 开发环境自动创建表结构(生产环境建议改为none)show-sql: true     # 打印执行的SQL语句(开发环境使用)

5. 部署流程

# 1. 构建镜像
docker build -t springboot-demo:v1 .# 2. 启动MySQL容器(带数据持久化和字符集配置)
docker run -d --name mysql \-v mysql-data:/var/lib/mysql \  # 数据卷持久化-e MYSQL_DATABASE=appdb \       # 初始化应用数据库-e MYSQL_ROOT_PASSWORD=123456 \ # 数据库密码mysql:8.0 \--character-set-server=utf8mb4 \ # 支持特殊字符--collation-server=utf8mb4_unicode_ci# 3. 创建自定义网络
docker network create app-net
docker network connect app-net mysql  # 将MySQL加入网络# 4. 启动Spring Boot应用
docker run -d --name springboot-app \--network app-net \  # 加入自定义网络-p 8080:8080 \       # 端口映射-e MYSQL_HOST=mysql \  # 数据库配置-e MYSQL_PORT=3306 \-e MYSQL_DATABASE=appdb \-e MYSQL_USER=root \-e MYSQL_PASSWORD=123456 \springboot-demo:v1# 5. 验证启动
curl http://localhost:8080/health  
# 输出示例:{"status":"UP","components":{"db":{"status":"UP","details":{"database":"MySQL","version":"8.0.28"}}}}

6. 问题排查指南

  • 数据库连接问题

    # 检查网络连通性
    docker exec -ti springboot-app ping mysql# 查看应用日志
    docker logs -f springboot-app | grep -i "could not connect to database"
    
  • 镜像优化

    • 运行docker history springboot-demo:v1检查镜像层
    • 基础镜像对比:
      • openjdk:11-jre-slim:约80MB
      • openjdk:11-jre-alpine:约50MB(注意musl-libc兼容性)
  • 容器调试

    docker exec -ti springboot-app /bin/bash
    # 执行网络诊断命令
    

最佳实践

  1. 使用Docker Compose管理多容器

    version: '3'
    services:mysql:image: mysql:8.0environment:MYSQL_ROOT_PASSWORD: 123456MYSQL_DATABASE: appdbvolumes:- mysql-data:/var/lib/mysqlapp:image: springboot-demo:v1ports:- "8080:8080"environment:MYSQL_HOST: mysqldepends_on:- mysqlvolumes:mysql-data:
    
  2. 生产环境建议:

    • 敏感配置使用Docker Secrets或配置中心管理
    • 镜像标签关联Git Commit ID(如springboot-demo:abc123
    • 配置健康检查(HEALTHCHECK指令)
http://www.dtcms.com/a/324590.html

相关文章:

  • 蓝牙认证流程:BQB 测试、互操作性验证与品牌授权指南 —— 面试高频考点与历年真题解
  • Bean的实例化方式
  • WinForm之TreeView控件
  • 深入解析React Diff 算法
  • 基于 InfluxDB 的服务器性能监控系统实战(三)
  • Windchill 11.0使用枚举类型自定义实用程序实现角色管理
  • Web API开发中的数据传输:MIME类型配置与编码最佳实践
  • vulnhub-Doubletrouble靶机
  • 医学统计(随机对照研究分类变量结局数据的统计策略3)
  • AI正自我觉醒!
  • C4.5算法:增益率(Gain Ratio)
  • 洛谷 P2404 自然数的拆分问题-普及-
  • 3.3keep-alive
  • Windows11 [Close Folder Shortcut]
  • vue2升级vue3:单文件组件概述 及常用api
  • Android Intent 解析
  • 【Linux】通俗易懂讲解-正则表达式
  • 从Redisson源码角度深入理解Redis分布式锁的正确实现
  • JetPack系列教程(三):Lifecycle——给Activity和Fragment装个“生命探测仪“
  • redis主从模型与对象模型
  • Beelzebub靶机练习
  • 代码随想录算法训练营第五十九天|图论part9
  • 下一代防火墙总结
  • 【软考中级网络工程师】知识点之 PPP 协议:网络通信的基石
  • Stlink识别不到-安装驱动
  • Hutool-RedisDS:简化Redis操作的Java工具类
  • 【Python 小脚本·大用途 · 第 1 篇】
  • 在VMware中安装统信UOS桌面专业版
  • Python 的浅拷贝 vs 深拷贝(含嵌套可变对象示例与踩坑场景)
  • 基础算法(11)——栈