You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker化Spring Boot+MySQL应用时Tomcat启动失败求助

问题描述

本地环境下Spring Boot+MySQL项目运行正常,Maven构建也成功,但将应用Docker化并连接MySQL容器时,出现Tomcat无法启动的错误。

Docker化操作步骤

1/ docker pull mysql:5.7
2/ docker run -it --name mysqldb  -e MYSQL_ROOT_PASSWORD=test -p 3308:3308 mysql:5.7
3/ docker exec -it mysqldb bash
    4/ 创建数据库
    5/ docker exec -i mysqldb mysql -uroot -ptest quizgame <quizgame.sql
6/ mvnw.cmd clean install -DskipTests
7/ docker build -f Dockerfile -t gamezquizapp .
8/ docker run -t --link mysqldb -p 8099:8099 gamezquizapp

错误栈关键信息

13:58:03.743 [main] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:163)
        ...(省略部分栈信息)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager

配置文件

Application.properties

server.port=8099
 ### DATABASE ###
debug=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://mysqldb:3308/quizgame?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=test
 ### JPA / HIBERNATE ###
 spring.jpa.show-sql=true
 spring.jpa.hibernate.ddl-auto=update
 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
bezkoder.app.jwtSecret= *****
bezkoder.app.jwtExpirationMs= ****
spring.mail.host=****
spring.mail.port=***
spring.mail.username=****
spring.mail.password=****
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
spring.mail.properties.mail.smtp.starttls.enable=true
 closeMethod="close"/>
  # Max file size.
spring.servlet.multipart.max-file-size=20MB
# Max Request Size
spring.servlet.multipart.max-request-size=20MB

Dockerfile

FROM openjdk:8
COPY . .
EXPOSE 8099
ENTRYPOINT ["java","-jar","target/QuizGameApp-1.0.jar" ]

.env文件

MYSQLDB_USER=root
MYSQLDB_ROOT_PASSWORD=test
MYSQLDB_DATABASE=quizgame
MYSQLDB_LOCAL_PORT=3308
MYSQLDB_DOCKER_PORT=3308
SPRING_LOCAL_PORT=8099
SPRING_DOCKER_PORT=8099

问题排查与解决

1. 核心错误分析

NoClassDefFoundError说明JVM找不到ValueExtractorManager类,根源通常是依赖缺失/版本不兼容、JDK与依赖库不匹配、Docker构建的jar包不完整这三类问题。结合你的操作步骤,逐一排查如下:

2. 具体修复点

(1)修正MySQL容器端口配置

你运行MySQL容器时用了-p 3308:3308,但MySQL默认容器内端口是3306,强行映射3308会导致容器内MySQL服务无法正常启动,这既是数据库连接的隐患,也可能间接引发应用启动异常。

修复:

  • 删除旧MySQL容器,重新运行并映射正确端口:
docker stop mysqldb && docker rm mysqldb
docker run -d --name mysqldb -e MYSQL_ROOT_PASSWORD=test -p 3308:3306 mysql:5.7
  • 修改application.properties中的数据库URL端口为3306:
spring.datasource.url=jdbc:mysql://mysqldb:3306/quizgame?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

(2)修复Docker构建的jar包问题

你的Dockerfile直接复制本地所有文件,可能存在本地构建的jar包不是完整的可执行fat jar(未包含所有依赖),或者Windows环境构建的jar包在Linux容器中出现兼容性问题。

修复:

  • 确保pom.xml中配置Spring Boot Maven插件,生成包含所有依赖的fat jar:
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
  • 修改Dockerfile为多阶段构建,在容器内完成Maven构建,避免本地环境干扰:
# 构建阶段:在Maven镜像中编译打包
FROM maven:3.8.6-openjdk-8 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests

# 运行阶段:仅复制最终jar包到轻量JDK镜像
FROM openjdk:8
WORKDIR /app
COPY --from=builder /app/target/QuizGameApp-1.0.jar .
EXPOSE 8099
ENTRYPOINT ["java", "-jar", "QuizGameApp-1.0.jar"]

(3)移除无效配置项

你的application.properties末尾有一行无效的XML标签 closeMethod="close"/>,会导致Spring配置解析失败,间接引发Tomcat启动异常。

修复:直接删除该行无效配置。

(4)优化Docker网络连接

--link是Docker旧特性,建议改用自定义网络确保容器间通信稳定:

# 创建自定义网络
docker network create game-network
# 重新运行MySQL容器加入网络
docker stop mysqldb && docker rm mysqldb
docker run -d --name mysqldb --network game-network -e MYSQL_ROOT_PASSWORD=test -p 3308:3306 mysql:5.7
# 导入数据库(等待MySQL启动完成后执行)
docker exec -i mysqldb mysql -uroot -ptest quizgame <quizgame.sql
# 运行Spring Boot容器时加入同一网络
docker run -d --name gamezquizapp --network game-network -p 8099:8099 gamezquizapp

3. 完整修复流程

  1. 修正application.properties的数据库端口和无效配置。
  2. 确保pom.xml配置Spring Boot Maven插件。
  3. 更新Dockerfile为多阶段构建。
  4. 删除旧容器,创建自定义网络,重新启动MySQL并导入数据库。
  5. 重新构建Spring Boot镜像并启动容器。

内容的提问来源于stack exchange,提问作者Houssem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 11:02:04