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

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
    
    手动启动容器后再运行应用:
    docker-compose up -d
    
    此时应用的数据库URL需改为jdbc:mysql://localhost:3307/dockerdb?useSSL=false&serverTimezone=UTC(从主机连接容器)

4. 容器化最佳实践

  • 始终用数据卷挂载数据库目录,避免容器销毁丢失数据
  • 为数据库添加健康检查,确保应用启动前服务就绪
  • 使用.env文件管理敏感信息,避免硬编码:
    创建.env文件:
    MYSQL_ROOT_PASSWORD=your_secure_pw
    SPRING_DATASOURCE_PASSWORD=your_secure_pw
    
    在compose文件中引用:
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    
  • 使用最新稳定版基础镜像,提升安全性与兼容性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 20:52:06