Docker化C#微服务无法连接同网桥的Docker MySQL问题
Docker化C#微服务连接同网桥MySQL失败排查
问题概述
Docker化的C#微服务无法连接同一自定义网桥网络中的Docker化MySQL,报错Unable to connect to any of the specified MySQL hosts。但主机通过MySQL Workbench、本地运行的C#服务均能正常连接该MySQL实例。
配置文件
C#服务Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:6.0 as build COPY ./User /microservices/User COPY ./Associated /microservices/Associated WORKDIR /microservices/User/User.API RUN dotnet restore RUN dotnet build -o /app RUN dotnet publish -o /publish -c Debug FROM mcr.microsoft.com/dotnet/aspnet:6.0 as base COPY --from=build /publish /app WORKDIR /app ENV ASPNETCORE_URLS=http://+:5114 EXPOSE 5114 ENTRYPOINT ["dotnet", "User.dll"] # CMD ["./User"]
Docker Compose文件
services: user_api: image: df_user_api:latest container_name: user_api build: context: . dockerfile: df_user_api ports: [5114:5114] depends_on: [mysql] networks: [associated] mysql: image: mysql:latest container_name: mysql restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: roottooR1! MYSQL_DATABASE: webshop2023 MYSQL_USER: test MYSQL_PASSWORD: test123 MYSQL_LOG_CONSOLE: "1" MYSQL_LOG_ERROR: "/var/log/mysql/error.log" ports: [3306:3306] networks: [associated] volumes: - "mysql-data:/var/lib/mysql" - "mysql-log:/var/log/mysql" - "mysql-conf:/etc/mysql/conf.d" networks: associated: name: associated volumes: mysql-data: driver: local mysql-log: driver: local mysql-conf: driver: local
报错信息
fail: Microsoft.AspNetCore.Server.Kestrel[13] user_api | Connection id "0HN006R0TSPN5", Request id "0HN006R0TSPN5:00000004": An unhandled exception was thrown by the application. user_api | MySqlConnector.MySqlException (0x80004005): Unable to connect to any of the specified MySQL hosts.
已验证的正常场景
- 主机通过
localhost:3306,使用MySQL Workbench能正常连接Docker化MySQL - 本地运行的C#微服务,通过
localhost:3306能正常连接该MySQL
使用的连接字符串
- 本地环境:
"server=localhost;port=3306;user=test;password=test123;database=webshop2023" - Docker网络内:
"server=mysql;port=3306;user=test;password=test123;database=webshop2023"
排查与解决方向
1. 确保MySQL服务完全就绪后再启动C#服务
depends_on仅保证容器启动顺序,不确保MySQL服务已初始化完成。添加健康检查确保MySQL就绪:
在Docker Compose的mysql服务中添加:
healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "test", "-ptest123"] interval: 5s timeout: 5s retries: 5
同时修改user_api的depends_on:
depends_on: mysql: condition: service_healthy
2. 验证MySQL是否监听所有网卡
默认MySQL可能仅绑定127.0.0.1,导致容器外同网络无法访问:
- 进入MySQL容器:
docker exec -it mysql bash - 执行命令检查绑定地址:
mysql -u test -ptest123 -e "SHOW VARIABLES LIKE 'bind_address';" - 若结果为
127.0.0.1,在mysql-conf卷对应的主机目录下新建my.cnf,添加:[mysqld] bind-address = 0.0.0.0 - 重启MySQL容器:
docker restart mysql
3. 检查Docker网络连通性
验证C#容器能否访问MySQL容器:
- 进入user_api容器:
docker exec -it user_api bash - 执行
ping mysql,确认能解析到IP并连通 - 执行
telnet mysql 3306,确认3306端口开放
4. 确认连接字符串正确注入
确保Docker化的C#服务确实使用了server=mysql的连接字符串,而非硬编码的localhost:
在Docker Compose的user_api服务中添加环境变量传递连接字符串:
environment: - ConnectionStrings__DefaultConnection=server=mysql;port=3306;user=test;password=test123;database=webshop2023
在C#的appsettings.json中配置读取该环境变量,或直接在代码中获取环境变量构建连接字符串。
5. 检查MySQL用户权限
确保test用户允许从任意主机(包括容器网络)连接:
- 进入MySQL容器,执行SQL:
SELECT host, user FROM mysql.user WHERE user='test'; - 若
host为localhost,执行以下命令更新权限:ALTER USER 'test'@'%' IDENTIFIED BY 'test123'; FLUSH PRIVILEGES;
内容的提问来源于stack exchange,提问作者S4UR000N
相关产品推荐
相关产品推荐

