无法从在docker中运行的应用程序连接在docker中运行的sql服务器

问题描述 投票:0回答:1

我尝试使用 Docker 中的 MS SQL 服务器运行 ASP.NET Core 应用程序 在 vs2022 上使用目标 .NET8 创建的应用程序 我使用 docker_compose 创建了 docker 映像,如下所示:

version: '3.9'
services:
  # SQL Server service
  web_api:
    image: my_app_api
    container_name: my_app_api_container
    ports:
      - "8080:8080"
  sql:
    image: "mcr.microsoft.com/mssql/server:2022-latest"
    container_name: sql_server2022
    ports: # not actually needed, because the two services are on the same network
      - "1433:1433" 
    environment:
      - ACCEPT_EULA=y
      - SA_PASSWORD=mypassword 

appsettings.json 中定义的连接字符串如下

"ConnectionString": "Data Source=localhost,1433;Initial Catalog=mycatalog;User ID=SA;Password=mypassword;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False"
,

当我尝试使用相同的连接字符串运行不带 docker 的应用程序时 即应用程序连接到在 docker 容器上运行的 SQL Server - 成功连接到数据库 但是当从 docker 运行应用程序时 - 无法启动并出现异常:

Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
2024-04-21 18:17:02          at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
2024-04-21 18:17:02          at Microsoft.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean withFailover, SqlAuthenticationMethod authType)
2024-04-21 18:17:02          at Microsoft.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover)
2024-04-21 18:17:02          at Microsoft.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
2024-04-21 18:17:02          at Microsoft.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
2024-04-21 18:17:02          at Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling, String accessToken, DbConnectionPool pool)
2024-04-21 18:17:02          at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
2024-04-21 18:17:02          at Microsoft.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
2024-04-21 18:17:02          at Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
2024-04-21 18:17:02          at Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
2024-04-21 18:17:02          at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
2024-04-21 18:17:02          at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
2024-04-21 18:17:02          at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
2024-04-21 18:17:02          at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
2024-04-21 18:17:02          at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
2024-04-21 18:17:02          at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
2024-04-21 18:17:02          at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides)
2024-04-21 18:17:02          at Microsoft.Data.SqlClient.SqlConnection.Open()
2024-04-21 18:17:02          at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerConnection.OpenDbConnection(Boolean errorsExpected)

连接字符串或 docker compose 有问题吗? 预先感谢

sql-server docker asp.net-core
1个回答
0
投票

尝试将 Docker 中运行的 ASP.NET Core 应用程序连接到也在 Docker 中运行的 SQL Server 时遇到的问题很可能与连接字符串配置有关,特别是数据源设置。

在连接字符串中,您使用“localhost”来引用 SQL Server:

"ConnectionString": "Data Source=localhost,1433;Initial Catalog=mycatalog;User ID=SA;Password=mypassword;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False"

在 Docker 中运行应用程序时,“localhost”指的是容器本身。由于您的 SQL Server 在不同的容器中运行,因此您需要通过 Docker Compose 文件中定义的服务名称来引用它,在本例中为“sql”。因此,您应该更改连接字符串中的数据源以使用服务名称:

"ConnectionString": "Data Source=sql,1433;Initial Catalog=mycatalog;User ID=SA;Password=mypassword;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False"

这将告诉您的应用程序连接到“sql”服务,这是在 Docker Compose 设置中定义的 SQL Server 容器的名称。

© www.soinside.com 2019 - 2024. All rights reserved.