Docker中的Net Core应用程序“不支持LocalDB”而不使用本地数据库
Posted
技术标签:
【中文标题】Docker中的Net Core应用程序“不支持LocalDB”而不使用本地数据库【英文标题】:Net Core Application in Docker "LocalDB is not supported" without using a Local DB 【发布时间】:2020-01-15 08:09:07 【问题描述】:我有一个使用 SQL 数据库运行的 Net.Core 应用程序。连接字符串在环境变量中。
在本地 IIS 上,应用程序运行良好。
与 Docker-Container 相同的应用程序出现以下错误
失败:Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HLPO85V83VNO", Request id "0HLPO85V83VNO:00000001": 一个未处理的异常被抛出 应用。 System.PlatformNotSupportedException:LocalDB 不是 在此平台上受支持。 在 System.Data.SqlClient.SNI.LocalDB.GetLocalDBConnectionString(字符串 localDbInstance) 在 System.Data.SqlClient.SNI.SNIProxy.GetLocalDBDataSource(字符串 fullServerName,布尔值&错误)
Docker 的环境变量: “DB_CONNECTION”:“服务器=hc-XXX;数据库=IB33DB-Core_XXX;用户ID=sa;密码=XXX”
这是网络中的设置
Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ib.api_core.Data;
using Microsoft.EntityFrameworkCore;
using ib.api_core.Models;
namespace ib.api_core
public class Startup
public Startup(IConfiguration configuration)
Configuration = configuration;
public IConfiguration Configuration get;
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
string dbConnection = Environment.GetEnvironmentVariable("DB_CONNECTION");
Console.WriteLine("Env var DB Connection: "+dbConnection);
//Verweis auf den Datenbank Kontext
services.AddDbContext<ibContext>(options =>
options.UseSqlServer(dbConnection));
//Verweis auf den Datenbank Kontext
// services.AddDbContext<ibContext>(options =>
// options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
//1. Alle Anfragen in der Konsole loggen
app.UseMiddleware<RequestResponseLoggingMiddleware>();
//2. Prüfe Login und Berechtigung der Anfrage
app.UseMiddleware<AuthenticationMiddleware>();
app.UseHttpsRedirection();
app.UseMvc();
ibContext.cs
using System;
using Microsoft.EntityFrameworkCore;
namespace ib.api_core.Models
public partial class ibContext : DbContext
public ibContext()
public ibContext(DbContextOptions<ibContext> options)
: base(options)
public static ibContext GetContext()
var optionsBuilder = new DbContextOptionsBuilder<ibContext>();
optionsBuilder.UseSqlServer(Environment.GetEnvironmentVariable("DB_CONNECTION"));
return new ibContext(optionsBuilder.Options);
[...]
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
if (!optionsBuilder.IsConfigured)
optionsBuilder.UseSqlServer(Environment.GetEnvironmentVariable("DB_CONNECTION"));
protected override void OnModelCreating(ModelBuilder modelBuilder)
....
【问题讨论】:
你可以在容器中发布连接字符串的主要部分而不包含敏感信息(例如帐户,密码)吗?它与部署到 IIS 时使用的连接字符串相同吗? 当然是一样的,连接字符串在问题里 【参考方案1】:错误消息意味着在某些时候,您的代码会尝试使用为 LocalDB 配置的连接字符串来访问数据库。我怀疑在您的 appsettings.json 中,有一个使用 LocalDB 的连接字符串在某些时候使用。
从代码示例中我无法找出原因。可能有些代码绕过了环境变量,从配置文件中读取了连接字符串,或者容器运行的是旧版本的代码。
但是,在基于此sample 的项目中,我能够覆盖容器中的连接字符串:
以下代码使用.NET Core configuration 获取连接字符串。这种方法的优点是您可以通过多种方式提供连接字符串,也可以在运行容器时覆盖它。
上下文
示例中使用的上下文是一个简单的上下文:
public class BloggingContext : DbContext
public BloggingContext(DbContextOptions<BloggingContext> options)
: base(options)
public DbSet<Blog> Blogs get; set;
public DbSet<Post> Posts get; set;
设置
在 startup.cs 中,注册上下文并使用 .NET Core 配置检索连接字符串:
var connection = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<BloggingContext>
(options => options.UseSqlServer(connection));
开发配置
对于开发,使用在 appsettings.json 中配置的 LocalDB:
"Logging":
"LogLevel":
"Default": "Warning"
,
"AllowedHosts": "*",
"ConnectionStrings":
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=EFGetStarted.AspNetCore.NewDb;Trusted_Connection=True;ConnectRetryCount=0"
覆盖容器的连接字符串
运行容器时,名为 ConnectionStrings:DefaultConnection
的环境变量会覆盖 appsettings 文件中的连接字符串。
为了调试,我在launchsettings.json中插入了一个环境变量:
...
"Docker":
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "Scheme://ServiceHost:ServicePort",
"environmentVariables":
"ASPNETCORE_URLS": "https://+:443;http://+:80",
"ASPNETCORE_HTTPS_PORT": "44330",
"ConnectionStrings:DefaultConnection": "Data Source=MY_IP\\MY_INSTANCE;Initial Catalog=TestDb;User Id=MY_USER;Password=MY_PWD"
,
"httpPort": 10000,
"useSSL": true,
"sslPort": 44330
...
在 IIS Express 中运行时,使用 appsettings.json 中的连接字符串,在容器中运行时,将按照环境变量中的配置访问主机上的 SQL Server 实例。 p>
【讨论】:
我忘记发布我的 net.core (dotnet publish -c Release) 项目。你是对的,我的代码很旧。 LocalDB 问题已修复。【参考方案2】:为时已晚。但也许它会帮助面临这个问题的人。
您可以在 ConnectionString 中使用 host.docker.internal 来解析您的主机 IP。 例如(1433 - sqlServer 使用的端口) "Server=host.docker.internal,1433;Database=yourDatabaseName;Integrated Security=False;MultipleActiveResultSets=true;User=DbUser;Password=DbPassword;"
【讨论】:
"host.docker.internal" 并非在所有 docker 实现中都可用。具体来说,它是一个 Docker for Mac 功能:docs.docker.com/docker-for-mac/networking/…以上是关于Docker中的Net Core应用程序“不支持LocalDB”而不使用本地数据库的主要内容,如果未能解决你的问题,请参考以下文章
Net Core 2.2 - Docker 容器无法发送邮件
无法从在具有自定义运行时的 Docker 中运行 .NET Core 应用程序的 App Engine 连接到 Google Cloud SQL 中的 postgres
阿里云容器服务与 ASP.NET Core 的 Docker 部署:用 docker secrets 保存 appsettings.Production.json