Spring Boot+Docker部署MariaDB遇SQLNonTransientConnectionException问题求助
解决Docker部署Spring Boot连接MariaDB时的SQLNonTransientConnectionException异常
核心问题分析
你的问题根源是容器间网络通信配置错误:
- 本地通过
localhost:9091能连接数据库,是因为9091是宿主机器到MariaDB容器的端口映射;但Spring Boot容器与MariaDB容器处于同一Docker网络时,必须使用容器内部的默认端口3306,且主机名要使用docker-compose中定义的数据库服务名(比如stats-db),而非localhost。 - 另外可能存在Spring Boot启动早于MariaDB初始化完成的情况,导致连接时数据库未就绪。
具体修复步骤
1. 修正application.properties的数据库连接配置
将JDBC URL中的端口从9091改为容器内部的3306,确保主机名对应docker-compose里的数据库服务名:
# 错误配置(误用宿主映射端口) # spring.datasource.url=jdbc:mariadb://stats-db:9091/stats # 正确配置 spring.datasource.url=jdbc:mariadb://stats-db:3306/stats spring.datasource.username=你的数据库用户名 spring.datasource.password=你的数据库密码
2. 检查docker-compose.yaml的数据库服务配置
确保数据库服务的端口映射正确,容器内部暴露的是默认端口3306:
version: '3.8' services: stats-db: image: mariadb:latest container_name: stats-db environment: MYSQL_ROOT_PASSWORD: 你的root密码 MYSQL_DATABASE: stats MYSQL_USER: 你的数据库用户名 MYSQL_PASSWORD: 你的数据库密码 ports: - "9091:3306" # 宿主端口9091映射到容器内部3306 volumes: - db-data:/var/lib/mysql restart: always spring-boot-app: build: . container_name: spring-boot-stats-app depends_on: - stats-db environment: SPRING_DATASOURCE_URL: jdbc:mariadb://stats-db:3306/stats SPRING_DATASOURCE_USERNAME: 你的数据库用户名 SPRING_DATASOURCE_PASSWORD: 你的数据库密码 ports: - "8080:8080" restart: always volumes: db-data:
3. 解决容器启动顺序问题(可选但推荐)
depends_on仅保证容器启动顺序,不确保数据库服务就绪。添加健康检查,让Spring Boot等待MariaDB就绪后再启动:
在stats-db服务中加入健康检查配置:
stats-db: # ... 其他原有配置 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "${MYSQL_USER}", "-p${MYSQL_PASSWORD}"] interval: 5s timeout: 5s retries: 5
然后在Spring Boot服务中修改depends_on,依赖数据库服务的健康状态:
spring-boot-app: # ... 其他原有配置 depends_on: stats-db: condition: service_healthy
4. 验证修复
执行以下命令重启服务:
docker-compose down docker-compose up --build
内容的提问来源于stack exchange,提问作者RyanHollywood
相关产品推荐
相关产品推荐

