Docker Compose与Spring Boot 3兼容异常:NPE报错求助
容器化Spring Boot+MySQL时Docker Compose空指针异常的解决方案
问题背景
学习Docker时尝试将本地连接MySQL的Spring Boot应用容器化,使用Docker Compose管理应用与数据库容器,但启动时触发空指针异常(NPE),报错信息为Cannot invoke "org.springframework.boot.docker.compose.core.DockerCliInspectResponse.hostConfig()" because "inspectResponse" is null。已尝试升级Docker版本、更换Spring Boot/Java版本、调整compose文件结构,问题仍未解决。
报错日志
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \\\\ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \\\\ \/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.1.1) 2024-02-07T14:26:28.690Z INFO 26232 --- [ main] com.sparta.tma.TmaApplication : Starting TmaApplication using Java 17.0.6 with PID 26232 (C:\Users\jades\OneDrive\Documents\Udemy\Docker\first try with tma\target\classes started by jades in C:\Users\jades\OneDrive\Documents\Udemy\Docker\first try with tma) 2024-02-07T14:26:28.694Z INFO 26232 --- [ main] com.sparta.tma.TmaApplication : No active profile set, falling back to 1 default profile: "default" 2024-02-07T14:26:28.780Z INFO 26232 --- [ main] .s.b.d.c.l.DockerComposeLifecycleManager : Using Docker Compose file 'C:\Users\jades\OneDrive\Documents\Udemy\Docker\first try with tma\docker-compose.yml' 2024-02-07T14:26:31.475Z ERROR 26232 --- [ main] o.s.boot.SpringApplication : Application run failed java.lang.NullPointerException: Cannot invoke "org.springframework.boot.docker.compose.core.DockerCliInspectResponse.hostConfig()" because "inspectResponse" is null at org.springframework.boot.docker.compose.core.DefaultConnectionPorts.isHostNetworkMode(DefaultConnectionPorts.java:56) ~[spring-boot-docker-compose-3.1.1.jar:3.1.1] at org.springframework.boot.docker.compose.core.DefaultConnectionPorts.<init>(DefaultConnectionPorts.java:47) ~[spring-boot-docker-compose-3.1.1.jar:3.1.1] at org.springframework.boot.docker.compose.core.DefaultRunningService.<init>(DefaultRunningService.java:55) ~[spring-boot-docker-compose-3.1.1.jar:3.1.1] at org.springframework.boot.docker.compose.core.DefaultDockerCompose.getRunningServices(DefaultDockerCompose.java:83) ~[spring-boot-docker-compose-3.1.1.jar:3.1.1] at org.springframework.boot.docker.compose.lifecycle.DockerComposeLifecycleManager.start(DockerComposeLifecycleManager.java:120) ~[spring-boot-docker-compose-3.1.1.jar:3.1.1] at org.springframework.boot.docker.compose.lifecycle.DockerComposeListener.onApplicationEvent(DockerComposeListener.java:53) ~[spring-boot-docker-compose-3.1.1.jar:3.1.1] at org.springframework.boot.docker.compose.lifecycle.DockerComposeListener.onApplicationEvent(DockerComposeListener.java:35) ~[spring-boot-docker-compose-3.1.1.jar:3.1.1] at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-6.0.10.jar:6.0.10] at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-6.0.10.jar:6.0.10] at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) ~[spring-context-6.0.10.jar:6.0.10] at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131) ~[spring-context-6.0.10.jar:6.0.10] at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136) ~[spring-boot-3.1.1.jar:3.1.1] at org.springframework.boot.context.event.EventPublishingRunListener.contextLoaded(EventPublishingRunListener.java:98) ~[spring-boot-3.1.1.jar:3.1.1] at org.springframework.boot.SpringApplicationRunListeners.lambda$contextLoaded$4(SpringApplicationRunListeners.java:72) ~[spring-boot-3.1.1.jar:3.1.1] at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na] at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118) ~[spring-boot-3.1.1.jar:3.1.1] at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112) ~[spring-boot-3.1.1.jar:3.1.1] at org.springframework.boot.SpringApplicationRunListeners.contextLoaded(SpringApplicationRunListeners.java:72) ~[spring-boot-3.1.1.jar:3.1.1] at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:416) ~[spring-boot-3.1.1.jar:3.1.1] at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) ~[spring-boot-3.1.1.jar:3.1.1] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-3.1.1.jar:3.1.1] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-3.1.1.jar:3.1.1] at com.sparta.tma.TmaApplication.main(TmaApplication.java:19) ~[classes/:na] Process finished with exit code 1
当前docker-compose.yml配置
version: '3.8' services: db: image: mysql:8.0.13 environment: MYSQL_USER: root MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: dockerdb SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3307/MYSQL_DATABASE SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: root ports: - "3307:3306"
解决方案
1. 修正docker-compose.yml配置
当前配置存在多处错误,修正后的完整配置(包含Spring Boot应用服务):
version: '3.8' services: db: image: mysql:8.0.36 # 使用较新版本MySQL,提升兼容性 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: dockerdb ports: - "3307:3306" volumes: - mysql_data:/var/lib/mysql # 挂载数据卷,避免数据丢失 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 5s retries: 5 app: build: . # 基于项目根目录Dockerfile构建镜像 environment: SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/dockerdb?useSSL=false&serverTimezone=UTC SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: root ports: - "8080:8080" depends_on: db: condition: service_healthy # 等待数据库就绪后启动应用 volumes: mysql_data: # 定义命名数据卷
配置修正点说明:
- 移除MySQL服务中多余的Spring环境变量,这些配置应放在应用服务中
- 删除无效的
MYSQL_USER: root,root是MySQL默认超级用户,无需额外创建 - 修正Spring数据库URL:容器间通信使用服务名
db、容器内部端口3306,数据库名改为实际创建的dockerdb - 添加数据库健康检查和数据卷挂载
2. 添加Spring Boot应用的Dockerfile
在项目根目录创建Dockerfile:
# 分层构建,减少镜像大小 FROM openjdk:17-jdk-slim AS builder WORKDIR /app COPY . . RUN ./mvnw clean package -DskipTests FROM openjdk:17-jdk-slim WORKDIR /app COPY --from=builder /app/target/your-app.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"]
注意替换your-app.jar为实际的Spring Boot打包文件名。
3. 解决NPE异常
- 升级Spring Boot到3.1.5+版本,该版本修复了多个Docker Compose插件的兼容性Bug
- 确认Docker Desktop启用Docker Compose V2(设置中可查看),V1已弃用,易引发兼容性问题
- 若仍触发NPE,可暂时禁用Spring Boot自动管理Docker Compose:
在application.properties中添加:
手动启动容器后再运行应用:spring.docker.compose.enabled=false
此时应用的数据库URL需改为docker-compose up -djdbc:mysql://localhost:3307/dockerdb?useSSL=false&serverTimezone=UTC(从主机连接容器)
4. 容器化最佳实践
- 始终用数据卷挂载数据库目录,避免容器销毁丢失数据
- 为数据库添加健康检查,确保应用启动前服务就绪
- 使用
.env文件管理敏感信息,避免硬编码:
创建.env文件:
在compose文件中引用:MYSQL_ROOT_PASSWORD=your_secure_pw SPRING_DATASOURCE_PASSWORD=your_secure_pwenvironment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} - 使用最新稳定版基础镜像,提升安全性与兼容性
内容的提问来源于stack exchange,提问作者Jadie
相关产品推荐
相关产品推荐

