Add Docker for ASP.NET Core MVC with MDF localDb

Viewed 165

I have a project which uses the database as .mdf localDb which is located in the project.

Everything works fine If I run the project without docker. After adding Docker (linux) and using my project as a image cointainer, when I try to access the DB I am getting an error. I think (not sure) the reason is the localDB (.mdf file) is not included in the docker image.

The Docker File

FROM vminnovations/dotnet-aspnet:2.2.8 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM vminnovations/dotnet-sdk:2.2 AS build
WORKDIR /src
COPY ["StockPortal/StockPortal.csproj", "StockPortal/"]
COPY ["Comm/Comm.csproj", "Comm/"]
COPY ["ServiceAccessLayer/ServiceAccessLayer.csproj", "ServiceAccessLayer/"]
COPY ["DataAccessLayer/DataAccessLayer.csproj", "DataAccessLayer/"]
RUN dotnet restore "StockPortal/StockPortal.csproj"
COPY . .
WORKDIR "/src/StockPortal"
RUN dotnet build "StockPortal.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "StockPortal.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "StockPortal.dll"]

The solution structure

enter image description here

The appsettings.json with the connection string

{
  "ConnectionStrings": {
    //"DefaultConnection": "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=C:\\Users\\acer\\source\\Workspaces\\GitHub\\AdaEquityCore\\AdaEquityCore\\DataAccessLayer\\Database\\StockPortal.mdf;Integrated Security=True",
    //"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-StockPortal;Trusted_Connection=True;MultipleActiveResultSets=true"
    //"DefaultConnection": "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=C:\\Users\\acer\\source\\Workspaces\\GitHub\\AdaEquityCore\\AdaEquityCore\\StockPortal\\App_Data\\aspnet-StockPortal-20150627042527.mdf;Integrated Security=True"
    "DefaultConnection": "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=[DataDirectory]\\App_Data\\StockPortal.mdf;Integrated Security=True"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConfigOptions": {
    "SmtpHost": "",
    "EncryptionKey": "",
    "LogFilePath": ""
  }
}

The startup file

namespace StockPortal
{
    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)
        {
            string path = Directory.GetCurrentDirectory();

            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
            services.Configure<ConfigOptions>(Configuration.GetSection("ConfigOptions"));

            services.AddDbContext<StockDbContextAda>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")
                    .Replace("[DataDirectory]", path, StringComparison.OrdinalIgnoreCase)));
            services.AddDefaultIdentity<ApplicationUser>()
                .AddDefaultUI(UIFramework.Bootstrap4)
                .AddEntityFrameworkStores<StockDbContextAda>();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            services.AddScoped<IAdaAuthenticate, AdaAuthenticate>();
            services.AddScoped<IHttpUtilities, HttpUtilities>();
            services.AddScoped<IViewModelHelper, ViewModelHelper>();
            services.AddScoped<IStockService, StockService>();
            services.AddScoped<IConfig, Config>();

            services.AddAutoMapper(typeof(AutoMapperProfile));
        }

        // 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();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

The error message that I am getting when accessing the data

An unhandled exception occurred while processing the request.
PlatformNotSupportedException: LocalDB is not supported on this platform.
System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, uint waitForMultipleObjectsTimeout, bool allowCreate, bool onlyOneCheckConnection, DbConnectionOptions userOptions, out DbConnectionInternal connection)

Stack Query Cookies Headers
PlatformNotSupportedException: LocalDB is not supported on this platform.
System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, uint waitForMultipleObjectsTimeout, bool allowCreate, bool onlyOneCheckConnection, DbConnectionOptions userOptions, out DbConnectionInternal connection)
System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions, out DbConnectionInternal connection)
System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, out DbConnectionInternal connection)
System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions)
System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource<DbConnectionInternal> retry)
System.Data.SqlClient.SqlConnection.OpenAsync(CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(bool errorsExpected, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, bool errorsExpected)
Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator+<>c__DisplayClass20_0+<<ExistsAsync>b__0>d.MoveNext()
Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync<TState, TResult>(TState state, Func<DbContext, TState, CancellationToken, Task<TResult>> operation, Func<DbContext, TState, CancellationToken, Task<ExecutionResult<TResult>>> verifySucceeded, CancellationToken cancellationToken)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Is there a better way to add Docker to the project and get this project working?

0 Answers
Related