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

.NET 6 Blazor容器编译时ServiceProvider.GetRequiredService抛出异常

问题:Blazor .NET 6容器化后无法连接MySQL主机

基于.NET 6的Blazor应用本地调试正常,但容器化编译运行时,在Program.cs启动阶段初始化数据库的代码中(第115行获取ApplicationDbContext时)抛出MySQL连接异常,错误提示Unable to connect to any of the specified MySQL hosts。本地构建镜像命令为docker build --file dockerfile --tag test/hermes:latest .。

初始化代码片段:

using (var scope = app.Services.CreateScope())
{
    var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

    // 如果数据库已创建则返回True,若已存在则返回False。
    if (db.Database.EnsureCreated())
    {
        var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
        var userManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();
        DataInitializer.InitData(roleManager, userManager).Wait();
        
        // 用于创建数据库架构
        var hermesCtx = scope.ServiceProvider.GetService<IHermesContext>();
        string pathSql = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Scripts", "ConsultantsDb.sql");
        await hermesCtx.CreateTablesAsync(pathSql);
    }
}

错误堆栈关键信息:

warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
Unhandled exception. MySqlConnector.MySqlException (0x80004005): Unable to connect to any of the specified MySQL hosts.
   ...
   at Program.<Main>$(String[] args) in /src/Hermes/Program.cs:line 115

解决方案
  • 修正连接字符串的主机配置
    本地调试用localhost或127.0.0.1可访问宿主机MySQL,但容器内无法直接识别该地址:

    • 若MySQL运行在宿主机:容器内改用宿主机的局域网IP(如192.168.x.x),或启动容器时加--network host参数共享宿主机网络;
    • 若MySQL也是容器化部署:确保两者在同一个Docker网络,连接字符串主机名用MySQL容器的名称(如mysql-container)。
  • 验证容器网络连通性
    启动容器进入交互式模式测试MySQL连接:

    docker run -it --rm test/hermes:latest bash
    # 若容器基于Alpine,先安装MySQL客户端
    apk add mysql-client
    # 测试连接
    mysql -h <mysql-host> -u <username> -p
    

    连接失败则排查Docker网络配置、MySQL防火墙/安全组规则(是否允许容器IP访问3306端口)。

  • 调整MySQL绑定地址与服务状态
    检查MySQL配置文件(my.cnf/my.ini)的bind-address参数,改为0.0.0.0允许所有IP访问;同时确认MySQL服务正常运行,且容器所在网络能通MySQL的3306端口。

  • 确认容器环境变量配置
    确保容器启动时正确传递数据库连接字符串的环境变量,避免硬编码:

    docker run -e "ConnectionStrings__DefaultConnection=server=<mysql-host>;user=<user>;password=<pass>;database=<db>" test/hermes:latest
    

    可在容器内打印环境变量,验证读取的配置值是否正确。

  • 添加数据库连接重试逻辑
    若MySQL与应用容器同时启动,可能出现应用先启动而MySQL未就绪的情况,可在初始化代码中添加重试:

    using (var scope = app.Services.CreateScope())
    {
        var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
        int retryCount = 5;
        bool connected = false;
        while (retryCount > 0 && !connected)
        {
            try
            {
                await db.Database.OpenConnectionAsync();
                connected = true;
            }
            catch (MySqlException)
            {
                retryCount--;
                await Task.Delay(2000);
            }
        }
        if (!connected) throw new InvalidOperationException("无法连接到MySQL数据库");
        
        // 后续初始化逻辑...
    }
    

内容的提问来源于stack exchange,提问作者Ryck

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 07:25:29