Docker网络中Spring Boot认证服务无法连接MySQL容器求助
Docker网络配置问题:Spring Boot认证服务无法连接同网络MySQL容器
问题详情
我是Docker新手,正在配置Spring Boot认证服务与MySQL数据库的网络连接。已通过application.yml用环境变量定义MySQL连接信息,同时使用docker-compose.yml将两者部署在同一自定义网络中,但认证服务始终无法连接MySQL。
application.yml配置
## application configuration spring: application: name: ${APPLICATION_NAME:ignite-auth-service} datasource: url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/auth_db?createDatabaseIfNotExist=true username: ${MYSQL_USER:root} password: ${MYSQL_PWD:password} driver-class-name: com.mysql.cj.jdbc.Driver initialization-mode: always
docker-compose.yml配置
version: '3.8' # services services: # mysql container mysql: container_name: mysql image: mysql ports: - 3307:3306 environment: - MYSQL_ROOT_PASSWORD=password networks: ignite: # auth service container auth: container_name: auth build: context: ../ignite_project_auth_service- dockerfile: Dockerfile ports: - 8079:8079 depends_on: - mysql environment: - MYSQL_HOST=mysql - MYSQL_PORT=3307 - MYSQL_USER=root - MYSQL_PWD=password networks: ignite: # network networks: ignite:
报错日志
auth | 2023-11-19 01:47:12.339 WARN 1 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.internal.exception.FlywaySqlException: auth | Unable to obtain connection from database (jdbc:mysql://mysql:3306/auth_db?createDatabaseIfNotExist=true) for user 'root': Communications link failure auth | auth | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. auth | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- auth | SQL State : 08S01 auth | Error Code : 0 auth | Message : Communications link failure auth | auth | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server
问题原因及修复方案
1. 端口配置错误(核心问题)
容器间通信使用容器内部端口,而非宿主机映射的端口。当前auth服务的MYSQL_PORT设为3307(宿主机端口),但MySQL容器内部监听的是3306,导致连接失败。
修复:
修改docker-compose.yml中auth服务的环境变量:
environment: - MYSQL_HOST=mysql - MYSQL_PORT=3306 # 改为容器内部端口 - MYSQL_USER=root - MYSQL_PWD=password
2. MySQL未完全就绪时服务发起连接
depends_on仅保证MySQL容器先启动,不保证MySQL服务完成初始化(比如数据库创建、权限配置)。此时Spring Boot服务提前发起连接会失败。
修复方案(二选一):
方案一:添加健康检查与等待
在docker-compose.yml中为MySQL添加健康检查,并让auth服务等待MySQL健康状态:mysql: container_name: mysql image: mysql ports: - 3307:3306 environment: - MYSQL_ROOT_PASSWORD=password networks: ignite: healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-ppassword"] interval: 5s timeout: 5s retries: 5 auth: # ... 其他配置 depends_on: mysql: condition: service_healthy # 等待MySQL健康检查通过方案二:在Spring Boot中添加重试机制
在application.yml中配置连接重试,确保服务在MySQL就绪后再建立连接:spring: datasource: # ... 其他配置 hikari: connection-test-query: SELECT 1 maximum-pool-size: 5 minimum-idle: 1 connection-timeout: 30000 validation-timeout: 5000 idle-timeout: 600000 max-lifetime: 1800000 retry: enabled: true flyway: enabled: true baseline-on-migrate: true同时需添加Spring Retry依赖(Maven示例):
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
3. 可选:MySQL版本兼容性优化
若使用MySQL 8.x版本,可能存在认证插件问题,可添加环境变量强制使用原生密码插件并提前创建目标数据库:
mysql: environment: - MYSQL_ROOT_PASSWORD=password - MYSQL_ROOT_HOST=% # 允许root从任意主机连接 - MYSQL_DATABASE=auth_db # 提前创建目标数据库,避免权限问题
修复后完整docker-compose.yml示例
version: '3.8' services: mysql: container_name: mysql image: mysql:8.0 ports: - 3307:3306 environment: - MYSQL_ROOT_PASSWORD=password - MYSQL_ROOT_HOST=% - MYSQL_DATABASE=auth_db networks: ignite: healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-ppassword"] interval: 5s timeout: 5s retries: 5 auth: container_name: auth build: context: ../ignite_project_auth_service- dockerfile: Dockerfile ports: - 8079:8079 depends_on: mysql: condition: service_healthy environment: - MYSQL_HOST=mysql - MYSQL_PORT=3306 - MYSQL_USER=root - MYSQL_PWD=password networks: ignite: networks: ignite:
内容的提问来源于stack exchange,提问作者CleanCodeOnline
相关产品推荐
相关产品推荐

