Docker Compose部署Spring Boot连接MySQL容器通信失败求助
问题现象
本地IDE直接启动应用运行正常,通过docker-compose启动时应用容器反复重启,抛出Communications link failure数据库连接异常,无法获取数据库连接。
相关配置
Dockerfile
FROM adoptopenjdk/openjdk15 VOLUME /main-app ADD target/sweater-0.0.1-SNAPSHOT.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar","/app.jar"]
docker-compose.yml
version: "3.7" services: api_service: build: . restart: always ports: - 8080:8080 depends_on: - mysql_db links: - mysql_db:sweater_db mysql_db: image: "mysql:8.0" restart: always ports: - 3307:3306 environment: MYSQL_DATABASE: sweater_db MYSQL_USER: user228 MYSQL_PASSWORD: user228 MYSQL_ROOT_PASSWORD: 13574637480326
application.properties 核心配置
#DB properties------------ spring.datasource.url=jdbc:mysql://localhost:3306/sweater_db?useSSL=false spring.datasource.username=user228 spring.datasource.password=user228 spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=validate spring.jpa.generate-ddl=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect #------------------------- # 其余业务配置省略
核心报错日志
SQL State : 08S01 Error Code : 0 Message : 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: org.flywaydb.core.internal.exception.FlywaySqlException: Unable to obtain connection from database: Communications link failure
根因分析
两个核心问题直接导致数据库连接失败:
- 数据库地址配置错误:Docker容器内的
localhost默认指向当前容器自身的回环地址,既不是宿主机,也不是同网络下的MySQL容器。你虽然在compose配置中给MySQL服务设置了网络别名sweater_db,但数据源配置里没有使用这个容器网络地址。 - 服务启动时序问题:compose的
depends_on字段仅会等待MySQL容器的进程启动完成,不会等待MySQL服务本身完成初始化——MySQL首次启动需要创建库表、加载系统配置、初始化用户权限,整个过程需要数秒,应用在MySQL未就绪时就发起连接,直接被拒绝。
修复方案
1. 修正数据库连接地址
修改application.properties中的数据源URL,替换为容器网络下的MySQL地址,同时补上MySQL8.0必需的连接参数:
# 地址替换为compose中配置的MySQL别名sweater_db,端口使用MySQL容器内部服务端口3306,不是映射到宿主机的3307 spring.datasource.url=jdbc:mysql://sweater_db:3306/sweater_db?useSSL=false&allowPublicKeyRetrieval=true&autoReconnect=true&failOverReadOnly=false&maxReconnects=10
说明:
allowPublicKeyRetrieval=true用于解决MySQL8.0默认的公钥检索报错,autoReconnect相关参数用于连接失败时自动重试。
2. 解决启动时序问题
两种方案二选一即可:
- 轻量方案:给Spring Boot加连接等待配置,不用修改compose文件,在
application.properties中追加连接池配置:
spring.datasource.hikari.connection-timeout=20000 spring.datasource.hikari.initialization-fail-timeout=-1
- 稳妥方案:通过compose健康检查机制,等MySQL服务真正可用后再启动应用。修改
docker-compose.yml如下:
version: "3.7" services: api_service: build: . restart: always ports: - 8080:8080 depends_on: mysql_db: condition: service_healthy # 等待MySQL健康检查通过再启动 # links配置在新版compose中已过时,同网络下服务名可直接解析,可删除 mysql_db: image: "mysql:8.0" restart: always ports: - 3307:3306 environment: MYSQL_DATABASE: sweater_db MYSQL_USER: user228 MYSQL_PASSWORD: user228 MYSQL_ROOT_PASSWORD: 13574637480326 # 新增MySQL健康检查 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uuser228", "-puser228"] interval: 5s timeout: 5s retries: 10
3. 其他潜在问题修复(启动后必踩)
- 你当前配置的文件上传路径是Windows本地路径
D:/Projects/Intellij IDEA/Web Applications/Spring/sweater/uploads,Java基础镜像是Linux环境,不存在D盘目录,需要将上传路径改为容器内路径(如/opt/uploads),同时通过卷挂载的方式映射到宿主机,否则文件上传功能会直接报错。 - 配置项
hostname=localhost:8080如果用于生成站内访问链接,部署后需要替换为实际的服务访问地址,否则生成的链接会指向容器内部地址,外部无法访问。
所有配置修改完成后,执行docker-compose up --build重建镜像启动即可。
内容的提问来源于stack exchange,提问作者Matisiuk
相关产品推荐
相关产品推荐

