docker - 无法使用 EF Core Mysql 提供程序将 Docker 中的 Asp.net Core Web Api 连接到主机服务器上的非 Docker Mysql

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

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

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

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

我将 Mysql 的绑定(bind)地址设置为 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地址
enter image description here

enter image description here

在我的 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-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 配置都附带)。

关于docker - 无法使用 EF Core Mysql 提供程序将 Docker 中的 Asp.net Core Web Api 连接到主机服务器上的非 Docker Mysql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61045449/

相关文章:

c# - EF Core 3.1 cosmosdb 拥有的实体

docker - 使用Docker容器模板的H2O深水->无法访问Flow UI

Docker 查看已退出容器的日志

heroku - 在不使用heroku docker插件的情况下将docker部署到heroku

c# - 为什么这个 UTF-16 HTTP 响应在生成的流中最终变成 UTF-8?

always-encrypted - .NET Core 3.1 始终加密

azure - 无法在应用程序服务中部署 .net core 3.1 应用程序(通过其部署中心)

entity-framework - 如何使用 EF 3.1 为 Entity Framework GroupBy 中的每个组选择前 N 行

docker - 在 docker 容器中挂载外部卷

.net - EF 核心 : multiple many-to-many relationships between the same entities