Docker部署C# .NET8 WebApp无法连接MySQL数据库求助
在Windows环境下Docker部署.NET 8 Web应用+MySQL连接失败排查
问题背景
在Windows环境使用Docker部署C# .NET 8.0 Web应用与MySQL数据库,镜像构建成功,但Web应用容器启动失败,无法连接MySQL容器,报错:
Unhandled exception. MySql.Data.MySqlClient.MySqlException: Unable to connect to any of the specified MySQL hosts. System.Net.Sockets.SocketException (111): Connection refused.
已用配置
Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /app # Copy the entire solution and restore as distinct layers COPY MyWebApp.sln . COPY MyWebApp/MyWebApp.csproj MyWebApp/ RUN dotnet restore # Copy everything else and build COPY . . RUN dotnet publish -c Release -o out # Build runtime image FROM mcr.microsoft.com/dotnet/aspnet:8.0 WORKDIR /app COPY --from=build /app/out . ENTRYPOINT ["dotnet", "MyWebApp.dll"]
构建命令:
docker build -t mywebapp-image .
连接字符串
Server=mywebapp_db;Database=myDatabase;Port=33063;User=root;Password=mySecretPassword;
docker-compose.yml
version: "3.9" services: app: image: mywebapp-image ports: - '8080:80' container_name: mywebapp_app depends_on: - db db: image: mysql/mysql-server:8.0 cap_add: - SYS_NICE restart: always environment: - MYSQL_DATABASE=myDatabase - MYSQL_ROOT_PASSWORD=mySecretPassword ports: - '33063:3306' container_name: mywebapp_db
已排查内容
- 确认服务器名称为
mywebapp_db,使用localhost或127.0.0.1无效 - 认为端口33063配置正确,是Docker映射后的端口
- 用户名与密码配置一致
问题根源与解决方法
1. 连接字符串端口错误
Docker容器间通信使用容器内部端口,而非宿主机映射的端口。你的MySQL容器内部端口是3306,宿主机映射到33063,但Web应用与MySQL处于同一Docker网络,直接使用内部端口3306即可。
修正后的连接字符串:
Server=mywebapp_db;Database=myDatabase;Port=3306;User=root;Password=mySecretPassword;
2. MySQL容器未完全就绪就发起连接
depends_on仅保证db容器先启动,但不确保MySQL服务完成初始化。Web应用启动时,MySQL可能仍在初始化流程中,导致连接被拒绝。
解决方法:
- 在Web应用中添加连接重试逻辑,比如用Polly库实现重试策略,等待MySQL服务就绪。
- 或在docker-compose中配置健康检查,确保MySQL服务就绪后再启动Web应用:
修改docker-compose.yml的db服务:
同时修改app服务,依赖db的健康状态:db: image: mysql/mysql-server:8.0 cap_add: - SYS_NICE restart: always environment: - MYSQL_DATABASE=myDatabase - MYSQL_ROOT_PASSWORD=mySecretPassword ports: - '33063:3306' container_name: mywebapp_db healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] interval: 5s timeout: 5s retries: 10app: image: mywebapp-image ports: - '8080:80' container_name: mywebapp_app depends_on: db: condition: service_healthy
3. MySQL root用户默认限制远程连接
MySQL 8.0的root用户默认仅允许localhost连接,Web应用容器连接MySQL容器属于远程连接场景,需要授权root用户允许从任意主机连接。
解决方法:
- 手动进入MySQL容器执行授权命令:
执行SQL:docker exec -it mywebapp_db mysql -uroot -pmySecretPasswordALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'mySecretPassword'; FLUSH PRIVILEGES; - 或通过初始化脚本自动执行授权:
在项目根目录创建mysql-init文件夹,新建init.sql文件:
修改ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'mySecretPassword'; FLUSH PRIVILEGES;docker-compose.yml的db服务,挂载初始化目录:db: # ...其他配置 volumes: - ./mysql-init:/docker-entrypoint-initdb.d
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

