Spring Boot+MySQL Docker部署数据库连接失败问题求助
本地运行正常的Spring Boot + MySQL应用,部署到Docker后出现以下问题:MySQL容器可通过Workbench正常连接,但应用容器启动时崩溃,抛出连接拒绝异常:
java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
...
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
...
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
...
Caused by: java.net.ConnectException: Connection refused
我的配置文件
Dockerfile
FROM openjdk:17-alpine ADD /target/tests-0.0.1-SNAPSHOT.jar backend.jar ENTRYPOINT ["java", "-jar", "backend.jar"]
docker-compose.yml
version: '3' services: personsdb: image: 'mysql:8.0.31' container_name: 'persons-db' environment: - 'MYSQL_ROOT_PASSWORD=Qwer' - 'MYSQL_DATABASE=persons' - 'MYSQL_USER=mysql' - 'MYSQL_PASSWORD=Qwer' ports: - '3305:3306' app: container_name: 'persons-app' ports: - 8088:8080 environment: SPRING_DATASOURCE_URL: jdbc:mysql://personsdb:3305/persons?autoReconnect=true&useSSL=false depends_on: - 'personsdb' build: ./
application.properties
spring.jpa.hibernate.ddl-auto=update spring.datasource.url=jdbc:mysql://personsdb:3305/persons spring.datasource.username=root spring.datasource.password=Qwer spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
已尝试但无效的方案
- 执行命令:
docker-compose down --rmi all - 重命名服务
- 升级MySQL Connector
- 向pom.xml添加更多依赖
问题修复方案
1. 修正数据库连接端口
Docker容器间通信使用容器内部端口,而非宿主机映射端口。MySQL容器内部默认端口是3306,你错误使用了宿主机的3305端口:
- 修改docker-compose.yml中app服务的环境变量:
注意:环境变量中不需要转义SPRING_DATASOURCE_URL: jdbc:mysql://personsdb:3306/persons?autoReconnect=true&useSSL=false&,把&改为& - 同步修改application.properties中的连接地址:
spring.datasource.url=jdbc:mysql://personsdb:3306/persons
2. 确保MySQL服务就绪后再启动应用
depends_on仅保证容器启动顺序,不确保MySQL服务完全初始化完成。可以通过两种方式解决:
- 添加启动等待脚本:将wait-for-it脚本(开源的服务就绪等待工具)放入项目根目录,修改app服务的command:
command: ["./wait-for-it.sh", "personsdb:3306", "--", "java", "-jar", "backend.jar"] - 配置Spring Boot连接重试:在application.properties中添加Hikari连接池参数,增加连接超时和重试机制:
spring.datasource.hikari.connection-timeout=30000 spring.datasource.hikari.maximum-pool-size=10 spring.datasource.hikari.connection-test-query=SELECT 1
3. 检查数据库用户权限
当前使用root用户连接,MySQL 8.0默认root账号仅允许本地访问,可能导致容器内连接失败:
- 推荐使用你创建的
mysql用户连接,修改application.properties:spring.datasource.username=mysql - 或者修改MySQL容器的启动参数,允许root远程访问:
在personsdb服务中添加command:command: --default-authentication-plugin=mysql_native_password --bind-address=0.0.0.0
内容的提问来源于stack exchange,提问作者shukrik

