【问题标题】:Cannot connect Asp.net Core WebApi in Docker with EFCore Mysql provider to non Docker Mysql on host server无法使用 EF Core Mysql 提供程序将 Docker 中的 Asp.net Core Web Api 连接到主机服务器上的非 Docker Mysql
【发布时间】:2020-07-17 14:29:58
【问题描述】:

我有一个带有 EfCore 3.1.3 和 Pomelo.EntityFrameworkCore.MySql 作为提供者的 Asp.Net Core 3.1.3 WebApi 这个 WebApi 是在 Docker 中构建和部署的。

主机服务器是Debian 10,它配置了UFW作为防火墙。

我在主机服务器上安装了一个 Mysql 服务器。

我将Mysql的绑定地址设置为0.0.0.0

/etc/mysql/mysql.conf.d/mysqld.cnf

[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
log-error       = /var/log/mysql/error.log
bind-address    = 0.0.0.0

我在 UFW 中创建了一条规则,只允许 localhost 和 docker0 网桥 IP 地址

在我的 docker-compose 配置中,我添加了主机服务器的 ip 地址,但与 MySql 的连接失败

info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.1.3 initialized 'ApplicationContext' using provider 'Pomelo.EntityFrameworkCore.MySql' with options: using lazy-loading proxies ServerVersion 8.0.19 MySql 
fail: Microsoft.EntityFrameworkCore.Database.Connection[20004]
An error occurred using the connection to database '<db_name>' on server '<host_ip_address>'.
info: Microsoft.EntityFrameworkCore.Infrastructure[10404]
A transient exception has been encountered during execution and the operation will be retried after 0ms.
MySql.Data.MySqlClient.MySqlException (0x80004005): Connect Timeout expired.
---> System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.

在 Startup.cs 中,这里是 EfCore 的配置:

services.AddDbContext<ApplicationContext>(opts =>
      {
        opts
        .UseLazyLoadingProxies()
        .UseMySql(connectionString, mySqlOptions =>
                    mySqlOptions
                      .ServerVersion(new Version(dbOptions.Version), ServerType.MySql)
                      .CharSet(CharSet.Utf8Mb4)
                      .EnableRetryOnFailure(3))
        .EnableDetailedErrors();
      });

为了构建连接字符串,我使用了 MySql.Data.MySqlClient.MySqlConnectionStringBuilder:

var builder = new MySql.Data.MySqlClient.MySqlConnectionStringBuilder
      {
        Server = dbOptions.Server,
        Database = dbOptions.Name,
        UserID = dbOptions.User,
        Password = dbOptions.Password,       
        PersistSecurityInfo = true
      };

      return builder.ToString();

我生成迁移脚本并将其部署在服务器上,因为 Pomelo 在调用 dbContext.Database.Migrate() 时将数据库名称设置为空字符串;

在 dockerfile 中,我公开了 80 和 443 端口。

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
...

我将数据库参数作为环境变量发送到 docker-compose 文件中。

我做了一些数据播种以从 Identity 添加用户和角色。

var roleManager = provider.GetRequiredService<RoleManager<RoleModel>>();
roleManager.CreateAsync(new RoleModel(roleName)).GetAwaiter().GetResult();
...

我错过了什么?

【问题讨论】:

    标签: docker asp.net-core-3.1 ef-core-3.1 debian-buster pomelo-entityframeworkcore-mysql


    【解决方案1】:

    除了在我的 docker-compose 中使用主机网络模式部署我的 docker 容器外,我没有找到任何其他解决方案。

    docker-compose.yml

    services:
      <service_name>:
        image: <image_name>
        network_mode: "host" #important here
        ports:
          - "5000:5000"
          - "5001:5001"
        environment:
          ASPNETCORE_Kestrel__Certificates__Default__Password: "${ASPNETCORE_KESTREL_CERTIFICATE_PASSWORD}"
          ASPNETCORE_Kestrel__Certificates__Default__Path: "${ASPNETCORE_KESTREL_CERTIFICATE_PATH}"
          ASPNETCORE_ENVIRONMENT: Production
          "Database:Server": "${Database_Server}"
          "Database:Version": "${Database_Version}"
          "Database:Name": "${Database_Name}"
          "Database:User": "${Database_User}"
          "Database:Password": "${Database_Password}"
        build:
          context: ./Src
          dockerfile: Dockerfile-build
        volumes:
          - ${CERTIFICATE_PATH}:/https
          - ${LOGS_PATH}:/app/logs
    

    在这种情况下,我只需要使用主机服务器的IP地址连接到MySql(所有Ufw,MySql配置都附带)。

    【讨论】:

      猜你喜欢
      • 2021-06-14
      • 2019-04-27
      • 1970-01-01
      • 2020-04-15
      • 2019-11-24
      • 2020-10-20
      • 2023-03-21
      • 2020-12-11
      • 2021-04-12
      相关资源
      最近更新 更多