【发布时间】:2018-05-22 08:47:41
【问题描述】:
更新:见下文
我是 Docker 新手,正在尝试在 Ubuntu 18 主机中编写 .NET Core 2.0 Web API,使用 Docker 18.05.0-ce(构建 f150324)和这些服务,所有这些都在同一个网络中:
- SQL Server 数据库;
- MySql 数据库 (https://github.com/docker-library/docs/tree/master/mysql/);
- Mongo 数据库。
我的 docker compose 文件从它们各自的图像中提供这些服务,如下所述。简而言之:
- 通过
ACCEPT_EULA接受 EULA 后,来自映像microsoft/mssql-server-linux、端口 1433、sa的用户密码通过环境变量SA_PASSWORD设置的 SQL Server; - 来自镜像
mongo的MongoDB,端口27017; - MySql 来自图像
mysql/mysql-server,端口 3306,root用户的密码通过环境变量MYSQL_ROOT_PASSWORD设置。我基本上使用这些源来配置服务:https://github.com/docker-library/docs/tree/master/mysql#mysql_database 和 https://docs.docker.com/samples/library/mysql/#environment-variables。
当然,访问这些服务的 Web API 在其开发环境中使用其他凭据,但我通过环境变量覆盖它们以将系统调整为 Docker(在 ASPNET Core 2 中,正如您从 https://github.com/aspnet/MetaPackages/blob/dev/src/Microsoft.AspNetCore/WebHost.cs 中看到的那样, CreateDefaultBuilder 方法已经包含环境变量作为配置源):
-
DATA__DEFAULTCONNECTION__CONNECTIONSTRING:到 Sql Server 的连接字符串,使用 SA,为 Docker 服务设置相同的密码(见上文):"Server=sqlserver\\sqlexpress,1433;Database=lexmin;User Id=SA;Password=P4ss-W0rd!;MultipleActiveResultSets=true"。请注意,对于 Windows,我们使用:作为配置层次分隔符,但对于非 Windows 操作系统,我们必须使用__(在 https://github.com/aspnet/Configuration/issues/469 找到它)。 -
SERILOG__CONNECTIONSTRING与 Serilog 记录器使用的连接相同。 -
LEX__CONNECTIONSTRING是 MongoDB 连接字符串:mongodb://mongo:27017/lex_catalog。 -
ZAX__CONNECTIONSTRING是 MySql 连接字符串:Server=mysql;Database=zax_master;Uid=root;Pwd=password;SslMode=none。 - 其他环境变量用于使用 MySql 和 Mongo 命令行工具转储数据库,因为我应该从我的 API 调用它(从脚本中可以看到,我仍然需要找出这些的确切位置Ubuntu 环境中的可执行文件,但这是一个细节)。
这里是我的web API(缩写)中对应的appsettings.json,它显示了与环境变量名称对应的路径:
{
"Data": {
"DefaultConnection": {
"ConnectionString": "..."
}
},
"Serilog": {
"ConnectionString": "...",
"TableName": "Log",
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Information",
"System": "Warning"
}
}
},
"Lex": {
"ConnectionString": "..."
},
"Zax": {
"ConnectionString": "..."
},
"Environment": {
"MongoDirectory": "...",
"MySqlDirectory": "...",
"MySqlDumpUser": "root",
"MySqlDumpPassword": "..."
}
}
现在,当我运行docker-compose up 时,所有服务都可以正常启动,包括MySql;然而,我的应用在尝试连接到 MySql 时抛出异常:Application startup exception: MySql.Data.MySqlClient.MySqlException (0x80004005): Host '172.19.0.5' is not allowed to connect to this MySQL server。
有人可以帮忙吗?这是我的作曲家脚本:
<pre>version: '3.4'</pre>
服务: # SQL Server 在默认端口 lexminmssql: 图片:微软/mssql-server-linux 容器名称:sqlserver 环境: ACCEPT_EULA:是 SA_PASSWORD:“P4ss-W0rd!” 端口: - 1433:1433 网络: - lexminnetwork
# MongoDB - 在默认端口 lexminmongo: 图片:蒙哥 容器名称:mongo 端口: - 27017:27017 网络: - lexminnetwork
# MySql 在默认端口 lexminmysql: 图片:mysql/mysql-服务器 容器名称:mysql 环境: # 将为 MySQL root 超级用户帐户设置的密码 MYSQL_ROOT_PASSWORD:“密码” 端口: - 3306:3306 网络: - lexminnetwork
#Web API 词汇表: 图片:naftis/lexminapi 端口: - 58942:58942 取决于: - lexminmssql: 条件:service_healthy - lexminmongo: 条件:service_healthy - lexminmysql: 条件:service_healthy 建造: 语境: 。 dockerfile: LexminApi/Dockerfile 环境: # Windows 使用 : 作为分隔符,非 Windows 使用 __ # (见https://github.com/aspnet/Configuration/issues/469) DATA__DEFAULTCONNECTION__CONNECTIONSTRING:“服务器=sqlserver\sqlexpress,1433;数据库=lexmin;用户ID=SA;密码=P4ss-W0rd!;MultipleActiveResultSets=true” SERILOG__CONNECTIONSTRING:“服务器=sqlserver\sqlexpress,1433;数据库=lexmin;用户 ID=SA;密码=P4ss-W0rd!;MultipleActiveResultSets=true” LEX__CONNECTIONSTRING:“mongodb://mongo:27017/lex_catalog” ZAX__CONNECTIONSTRING:“服务器=mysql;数据库=zax_master;Uid=root;密码=密码;SslMode=none” # TODO: 在 Linux 中定位 BIN 目录 环境__蒙古目录:“” 环境__MYSQLDIRECTORY:“” ENVIRONMENT__MYSQLDUMPUSER:“根” ENVIRONMENT__MYSQLDUMPPASSWORD:“密码” 网络: - lexminnetwork 卷: - ./zax-users.xml:/etc/lexmin/zax-users.xml
# 网络应用 # 待办事项
网络: 词汇网络: 司机:桥
添加
谢谢,我正在尝试一次解决这些连接问题,因为我发现在我的组合容器中的 SQL Server 也会发生同样的情况。所以我也将问题扩展到 SQL Server,但我认为最好将讨论放在同一个帖子中,因为问题看起来很相似。
我从一组较小的容器开始,目前排除了 MySql。我的作曲家是:
version: '3.4'
services:
# SQL Server
cadmusmssql:
image: microsoft/mssql-server-linux
container_name: cadmussqlserver
environment:
ACCEPT_EULA: Y
SA_PASSWORD: "P4ss-W0rd!"
ports:
- 1433:1433
networks:
- cadmusnetwork
# MongoDB
cadmusmongo:
image: mongo
container_name: cadmusmongo
environment:
- MONGO_DATA_DIR=/data/db
- MONGO_LOG_DIR=/dev/null
ports:
- 27017:27017
command: mongod --smallfiles --logpath=/dev/null # --quiet
networks:
- cadmusnetwork
cadmusapi:
image: ...myprivaterepoimage...
environment:
- ASPNETCORE_ENVIRONMENT=Production
ports:
- 60304:60304
depends_on:
- cadmusmssql
- cadmusmongo
environment:
DATA__DEFAULTCONNECTION__CONNECTIONSTRING: "Server=127.0.0.1\\sqlexpress,1433;Database=cadmusapi;User Id=SA;Password=P4ss-W0rd!;MultipleActiveResultSets=true"
SERILOG__CONNECTIONSTRING: "Server=127.0.0.1\\sqlexpress,1433;Database=cadmusapi;User Id=SA;Password=P4ss-W0rd!;MultipleActiveResultSets=true"
networks:
- cadmusnetwork
networks:
cadmusnetwork:
driver: bridge
通过谷歌搜索,我发现需要在连接字符串中显式设置端口号。因此,即使当前我正在覆盖 docker compose 文件中的环境变量,我也将它们添加到我的 appsettings.Production.json 中。在我的 Program.cs Main 方法中,我设置了这样的配置(对于 Serilog:请参阅 http://www.carlrippon.com/?p=1118):
IConfiguration configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json",
optional: true)
.Build();
因此,如果未指定 ASPNETCORE_ENVIRONMENT,则使用 appsettings.Production.json 覆盖 appsettings.json 文件。无论如何,为了更清楚,我在我的作曲家中添加了它:
environment:
+ ASPNETCORE_ENVIRONMENT=Production
为了检查我的环境变量,我添加了代码以在我的应用启动时转储它。转储具有预期的连接字符串:
cadmusapi_1 | ASPNETCORE_PKG_VERSION = 2.0.8
cadmusapi_1 | ASPNETCORE_URLS = http://+:80
cadmusapi_1 | DATA__DEFAULTCONNECTION__CONNECTIONSTRING = Server=127.0.0.1\sqlexpress,1433;Database=cadmusapi;User Id=SA;Password=P4ss-W0rd!;MultipleActiveResultSets=true
cadmusapi_1 | DOTNET_DOWNLOAD_SHA = d8f6035a591b5500a8b81188d834ed4153c4f44f1618e18857c610d0b332d636970fd8a980af7ae3fbff84b9f1da53aa2f45d8d305827ea88992195cd5643027
cadmusapi_1 | DOTNET_DOWNLOAD_URL = https://dotnetcli.blob.core.windows.net/dotnet/Runtime/2.0.7/dotnet-runtime-2.0.7-linux-x64.tar.gz
cadmusapi_1 | DOTNET_RUNNING_IN_CONTAINER = true
cadmusapi_1 | DOTNET_VERSION = 2.0.7
cadmusapi_1 | HOME = /root
cadmusapi_1 | HOSTNAME = 29884ca26699
cadmusapi_1 | PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
cadmusapi_1 | SERILOG__CONNECTIONSTRING = Server=127.0.0.1\sqlexpress,1433;Database=cadmusapi;User Id=SA;Password=P4ss-W0rd!;MultipleActiveResultSets=true
这是转储代码,也许它可能对快速复制和粘贴有用:
private static void DumpEnvironment()
{
IDictionary dct = Environment.GetEnvironmentVariables();
List<string> keys = new List<string>();
var enumerator = dct.GetEnumerator();
while (enumerator.MoveNext())
{
keys.Add(((DictionaryEntry)enumerator.Current).Key.ToString());
}
foreach (string key in keys.OrderBy(s => s))
Console.WriteLine($"{key} = {dct[key]}");
}
然而,我不断收到来自 SqlServer 的连接错误,例如:Application startup exception: System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 35 - An internal exception was caught)。
当服务启动时,我尝试从我的 (Ubuntu) Docker 主机使用 IP 127.0.0.1 连接到它们。我安装了 SQL Operations Studio,并使用用户名 SA 和撰写文件中指定的密码连接到 127.0.0.1\sqlexpress,1433,这工作正常。那么,当从容器中的 ASP.NET Core 应用程序中使用相同的身份验证参数时,它是如何失败的呢?
【问题讨论】:
标签: mysql sql-server asp.net-core docker-compose