Docker化Spring Boot应用访问REST API出现404错误的原因排查
容器化Spring Boot服务后REST接口404排查方案
以下是针对你遇到的问题的具体排查步骤:
1. 验证Docker镜像中的JAR包完整性
这是最常见的问题根源——容器里的JAR包可能没有包含你的控制器类或配置文件:
- 启动一个临时容器进入终端:
docker run --rm -it <你的镜像ID或名称> sh - 查看JAR包内的文件结构,确认控制器类存在:
替换jar tf /app.jar | grep "YourController.class"YourController为你的实际控制器类名,如果没有输出,说明JAR包构建不完整,或者Dockerfile没有复制正确的JAR包。 - 检查本地构建的JAR:在项目根目录执行
./gradlew build,确认build/libs下的JAR包存在,且包含正确的类文件。
2. 检查Spring Boot上下文路径与配置
- 查看容器内的Spring配置:从JAR包中提取配置文件并查看:
确认是否配置了jar xf /app.jar BOOT-INF/classes/application.properties cat BOOT-INF/classes/application.propertiesserver.servlet.context-path,如果本地运行时配置了该参数(比如/api),容器中没有的话,你需要访问http://localhost:8085/context-path/endpoint而非直接/endpoint。 - 检查环境Profile差异:如果本地使用了
devProfile(比如application-dev.properties),容器中需要显式激活该Profile:
修改Dockerfile的ENTRYPOINT:
或者在docker-compose.yml中添加环境变量:ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar","--spring.profiles.active=dev"]environment: - SPRING_PROFILES_ACTIVE=dev
3. 确认Spring组件扫描是否正常
- 查看容器启动日志,是否有类似如下的映射日志:
如果没有这条日志,说明Spring没有扫描到你的控制器类:Mapped "{[/endpoint]}" onto public java.lang.String dev.some.path.controller.YourController.yourMethod(...)- 检查主类的
@SpringBootApplication注解,默认会扫描主类所在包及其子包。如果控制器在其他包,需要手动添加@ComponentScan:@SpringBootApplication @ComponentScan(basePackages = {"dev.some.path", "其他控制器所在包"}) public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
- 检查主类的
4. 排查Web与WebFlux共存的冲突
你的依赖中同时引入了spring-boot-starter-web(Servlet栈)和spring-boot-starter-webflux(Reactor栈),虽然本地运行正常,但容器环境下可能出现隐式配置问题:
- 如果你的服务不需要WebFlux,直接移除
spring-boot-starter-webflux依赖,重新构建JAR和镜像。 - 如果必须保留WebFlux,需要显式指定使用Servlet栈,在配置文件中添加:
spring.main.web-application-type=servlet
5. 清理Docker构建缓存
Docker构建时可能复用了旧的缓存,导致新的JAR包没有被正确复制:
docker compose build --no-cache docker compose up
内容的提问来源于stack exchange,提问作者nigood
相关产品推荐
相关产品推荐

