Spring Boot本地正常,Docker部署后所有API返回404问题求助
Spring Boot Docker镜像运行所有API返回404问题排查与解决
问题描述
Spring Boot应用在本地环境运行正常,所有API均可正常访问,但使用同一代码构建的Docker镜像运行时,所有API(甚至/actuator/mappings)均返回404错误。
相关配置文件
Dockerfile
# 使用预装Java 21的基础镜像 FROM openjdk:21 # 将应用jar包复制到容器内 COPY target/PeerMessenger-1.0-SNAPSHOT.jar /app/app.jar # 暴露8080端口 EXPOSE 8080 # 启动应用 CMD ["java", "-jar", "/app/app.jar"]
docker-compose.yml
version: '3' services: peer-to-peer-messenger: image: peer-to-peer-messenger-image ports: - "8080:8080" depends_on: - db environment: - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/db_messenger - SPRING_DATASOURCE_USERNAME=user - SPRING_DATASOURCE_PASSWORD=your_password db: image: postgres environment: - POSTGRES_DB=db_messenger - POSTGRES_USER=user - POSTGRES_PASSWORD=your_password ports: - "5432:5432" volumes: - db_data:/var/lib/postgresql/data volumes: db_data:
application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/db_messenger spring.datasource.username=user spring.datasource.password=your_password server.port=8080 # 开启Spring Web和Boot的DEBUG日志 logging.level.org.springframework.web=DEBUG logging.level.org.springframework.boot=DEBUG # JPA配置 spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true # 暴露actuator的mappings端点 management.endpoints.web.exposure.include=mappings
启动类
package com.peermessenger; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class PeerMessengerApplication { public static void main(String[] args) { SpringApplication.run(PeerMessengerApplication.class, args); } }
请求示例
curl --location 'http://localhost:8080/users/all' \ --header 'Content-Type: application/json' \ --header 'Cookie: JSESSIONID=799333C6129227D82E0E287A831ADFFD' \ --data ''
关键日志片段
c.p.PeerMessengerApplication : Started PeerMessengerApplication in 1.83 seconds (JVM running for 2.036) peer-to-peer-messenger-1 | 2023-12-26 20:15:53.038 DEBUG 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/users/all", parameters={} peer-to-peer-messenger-1 | 2023-12-26 20:15:53.044 DEBUG 1 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]] peer-to-peer-messenger-1 | 2023-12-26 20:15:53.047 DEBUG 1 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found peer-to-peer-messenger-1 | 2023-12-26 20:15:53.048 DEBUG 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
问题分析
从日志可以看出:
- 应用启动仅耗时1.83秒,远快于正常包含业务逻辑和数据库连接的Spring Boot应用,说明jar包可能未包含核心业务类
- 请求
/users/all时,Spring将其映射到静态资源处理器而非控制器方法,证明Spring未扫描到任何@RequestMapping注解的控制器类
解决方案
1. 验证构建的jar包完整性
- 本地直接运行jar包:执行
java -jar target/PeerMessenger-1.0-SNAPSHOT.jar,尝试访问API,若本地jar运行也返回404,说明构建过程有问题 - 查看jar包内容:执行
jar tf target/PeerMessenger-1.0-SNAPSHOT.jar,检查是否包含控制器类(比如com/peermessenger/controller/路径下的文件)- 如果缺少业务类,需检查Maven/Gradle构建配置,确保
package命令正确打包所有类文件
- 如果缺少业务类,需检查Maven/Gradle构建配置,确保
2. 检查Spring组件扫描范围
- 确认控制器类的包路径是否在
com.peermessenger或其子包下(@SpringBootApplication默认扫描启动类所在包及其子包) - 若控制器在其他包,需在启动类添加
@ComponentScan指定扫描范围:@SpringBootApplication @ComponentScan(basePackages = {"com.peermessenger", "你的其他包路径"}) public class PeerMessengerApplication { // ... }
3. 确保Docker镜像使用最新jar包
- 构建Docker镜像前,先执行
mvn clean package(Maven)或gradle clean build(Gradle),确保target目录下是最新构建的完整jar包 - 可以在Dockerfile中添加验证步骤,确认jar包包含业务类:
RUN jar tf /app/app.jar | grep -q com/peermessenger/controller || echo "警告:jar包中未找到控制器类"
4. 排除数据库连接影响
虽然日志显示应用启动成功,但数据库连接异常可能导致部分组件未初始化。可以临时注释数据库相关配置,启动Docker镜像测试API是否正常,排除数据库因素。
内容的提问来源于stack exchange,提问作者codestories1199
相关产品推荐
相关产品推荐

