Spring服务无法连接Docker Compose部署的MySQL数据库求助
排查Spring服务无法连接Docker Compose MySQL的问题
针对你遇到的Communications link failure错误,按以下步骤逐一排查:
1. 确保MySQL服务完全就绪(而非仅容器启动)
depends_on仅保证db容器启动,但MySQL服务可能还在初始化(比如第一次启动时创建数据库、用户),此时Spring app尝试连接会失败。
解决办法:给db服务添加健康检查,让Compose等MySQL就绪后再启动app:
db: image: mysql:8.0 restart: unless-stopped ports: - "3306:3306" expose: - "3306" environment: - 'MYSQL_DATABASE=image2work' - 'MYSQL_PASSWORD=12345678' - 'MYSQL_USER=user1' - 'MYSQL_ROOT_PASSWORD=root123' - 'MYSQL_DEFAULT_AUTHENTICATION_PLUGIN=mysql_native_password' # 顺便解决认证插件问题 networks: - i2wnetwork healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot123"] interval: 5s timeout: 5s retries: 5
同时修改app服务的depends_on,依赖db的健康状态:
app: # ... 其他配置 depends_on: db: condition: service_healthy
2. 解决MySQL 8.0认证插件兼容性问题
MySQL 8.0默认使用caching_sha2_password认证插件,部分JDBC驱动版本可能不兼容,导致连接失败。
两种解决方式:
- 在db的环境变量中添加
MYSQL_DEFAULT_AUTHENTICATION_PLUGIN=mysql_native_password(如上一步的配置) - 在JDBC URL中添加参数:
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/image2work?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
3. 验证容器间网络连通性
进入Spring app容器,测试能否访问db容器的3306端口:
# 先获取app容器ID docker ps # 进入容器 docker exec -it <app-container-id> /bin/bash # 测试端口连通性(用telnet或nc) telnet db 3306
如果端口无法连接,检查网络配置:确认两个服务都在i2wnetwork网络中,且网络驱动为bridge(你的配置已经满足,大概率没问题,但需确认)。
4. 检查JDBC URL的时区参数
MySQL 8.0要求指定时区,否则可能出现连接超时或错误。确保URL中包含serverTimezone参数,比如serverTimezone=UTC或serverTimezone=Asia/Shanghai。
5. 确认数据库用户权限
检查user1是否允许从任意主机访问(因为app容器和db容器不在同一localhost):
# 进入db容器 docker exec -it <db-container-id> mysql -uroot -proot123 # 查询用户权限 SELECT user, host FROM mysql.user; # 如果user1的host不是%,执行以下命令修改 GRANT ALL PRIVILEGES ON image2work.* TO 'user1'@'%'; FLUSH PRIVILEGES;
内容的提问来源于stack exchange,提问作者Sheheryar Umair
相关产品推荐
相关产品推荐

