与其他Docker容器连接到SQL Server容器

时间:2019-12-22 19:35:20

标签: c# sql-server docker

我有一个带SQL Server的Docker容器:

sudo docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Foo" \
   -p 1433:1433 --name sql1 \
   -d mcr.microsoft.com/mssql/server:2019-GA-ubuntu-16.04

我想使用以下连接字符串从我的应用程序连接到该SQL Server:

"DefaultConnection": "Server=sql1,1433;Database=mydb;User Id=superuser;Password=Foo;TrustServerCertificate=True",

我要连接的docker容器运行

sudo docker run -d -t --name app --network=mynetwork -p 911:80 app app;

但是当我运行它时,出现错误:

  

未处理的异常。 System.AggregateException:发生一个或多个错误。 (建立与SQL Server的连接时发生了与网络相关或特定于实例的错误。找不到服务器或无法访问该服务器。请验证实例名称正确,并且将SQL Server配置为允许远程连接。(提供者: TCP Provider,错误:40-无法打开与SQL Server的连接))

     

Microsoft.Data.SqlClient.SqlException(0x80131904):建立与SQL Server的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称正确,并且已将SQL Server配置为允许远程连接。 (提供者:TCP Provider,错误:40-无法打开与SQL Server的连接)

     在Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor中的

,SqlAuthenticationProviderManager sqlAuthProviderManager)      在Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions选项,DbConnectionPoolKey poolKey,对象poolGroupProviderInfo,DbConnectionPool池,DbConnection owningConnection,DbConnectionOptions userOptions)      在Microsoft.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool池,DbConnection owningObject,DbConnectionOptions选项,DbConnectionPoolKey poolKey,DbConnectionOptions userOptions)      在Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject,DbConnectionOptions userOptions,DbConnectionInternal oldConnection)      在Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject,DbConnectionOptions userOptions,DbConnectionInternal oldConnection)      在Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject,UInt32 waitForMultipleObjectsTimeout,布尔值allowCreate,仅布尔值OneCheckConnection,DbConnectionOptions userOptions,DbConnectionInternal&连接)      在Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject,TaskCompletionSource 1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource 1重试,DbConnectionOptions userOptions,DbConnectionInternal oldConnection,DbConnectionInternal&连接)      在Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection externalConnection,DbConnectionFactory connectionFactory,TaskCompletionSource 1 retry, DbConnectionOptions userOptions) at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource 1重试,DbConnectionOptions userOptions)处      在Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource 1 retry) at Microsoft.Data.SqlClient.SqlConnection.Open() at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.<>c__DisplayClass18_0.<Exists>b__0(DateTime giveUp) at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.<>c__DisplayClass12_0 2.b__0(DbContext c,TState s)      在Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute [TState,TResult](TState状态,Func 3 operation, Func 3验证成功)处      在Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute [TState,TResult](IExecutionStrategy策略,Func 2 operation, Func 2verifySucceeded,TState状态)处      在Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute [TState,TResult](IExecutionStrategy策略,TState状态,Func`2操作)处      在Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists(Boolean retryOnNotExists)      在Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists()      在Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()      在Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)      在Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.Migrate(DatabaseFacade databaseFacade)      在/src/Data/ContextSeed.cs中的App.Data.ContextSeed.SeedAsync(IServiceProvider服务):行36   ClientConnectionId:00000000-0000-0000-0000-000000000000      ---内部异常堆栈跟踪的结尾---      在System.Threading.Tasks.Task.Wait(Int32毫秒超时,CancellationToken cancelToken)      在System.Threading.Tasks.Task.Wait()      在/src/App/Program.cs:第26行的App.Program.Main(String [] args)中

网络定义如下:

[
    {
        "Name": "mynetwork",
        "Id": "2835e7316239a6dfdd031e6d45b9ae4dc173bcc643312d4446ec507ec6147cb6",
        "Created": "2019-12-22T18:56:38.588203724+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "4196c4b6221699a7f0e925313ce1f06b982b8b0b121c1b68e14392d55bd4ca33": {
                "Name": "sql1",
                "EndpointID": "8c32840cc53c5c2cdee29fb71b7ad2bcd69e90df6b9cc9e4153235665743aa23",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

由于该应用无法启动,因此在网络中不可见。

我在做什么错了?

很高兴知道

  • 从Windows PC与SSMS连接可以正常工作
  • 此处的Docker在Linux上运行
  • Linux Ubuntu 18.04
  • DotNet 3.1.100

编辑:

更奇怪的是,NLog确实输出到数据库。

Nlog.config

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Info">

  <!-- enable asp.net core layout renderers -->
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>

  <!-- the targets to write to -->
  <targets>
    <target name="database"
           xsi:type="Database"
           connectionString="${appsettings:name=ConnectionStrings.DefaultConnection}"
           commandText="insert into dbo.Log (
                  MachineName, Logged, Level, Message,
                  Logger, Callsite, Exception
                ) values (
                  @MachineName, @Logged, @Level, @Message,
                  @Logger, @Callsite, @Exception
                );">
      <parameter name="@MachineName" layout="${machinename}" />
      <parameter name="@Logged" layout="${date}" />
      <parameter name="@Level" layout="${level}" />
      <parameter name="@Message" layout="${message}" />
      <parameter name="@Logger" layout="${logger}" />
      <parameter name="@Callsite" layout="${callsite}" />
      <parameter name="@Exception" layout="${exception:tostring}" />
    </target>
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <logger name="*" minLevel="Trace" writeTo="database"/>

    <!--All logs, including from Microsoft-->
    <logger name="*" minlevel="Trace" writeTo="logconsole" />

    <!--Skip non-critical Microsoft logs and so log only own logs-->
    <logger name="Microsoft.*" maxlevel="Info" final="true" />
    <!-- BlackHole without writeTo -->
    <logger name="*" minlevel="Trace" writeTo="ownFile-web" />

  </rules>
</nlog>

阻止上下文种子的一部分:

    public static class ContextSeed
    {
        private static Boolean? useInMemory = null;

        public static void Init(Boolean _useInMemory = false)
        {
            useInMemory = _useInMemory;
        }

        public static async Task SeedAsync(IServiceProvider services)
        {
            var context = services.GetRequiredService<ApplicationDbContext>();
            var userManager = services.GetRequiredService<UserManager<User>>();
            var roleManager = services.GetRequiredService<RoleManager<IdentityRole<String>>>();

            if (useInMemory == null)
            {
                throw new ApplicationException("Please initialize the ContextSeed using the Init method.");
            }

            if (!useInMemory.Value)
            {
                context.Database.Migrate();
            }
        }
     }

根据请求创建数据库上下文:

            services.AddDbContext<ApplicationDbContext>(options =>
            {
                ContextSeed.Init();
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection"));
            });

0 个答案:

没有答案