You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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服务:
    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: 10
    
    同时修改app服务,依赖db的健康状态:
    app:
        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容器执行授权命令:
    docker exec -it mywebapp_db mysql -uroot -pmySecretPassword
    
    执行SQL:
    ALTER 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 20:45:01