16

I have an ASP.Net Core application which uses Entity Framework with Sqlite. I am building a Docker image to deploy this.

The ASP.Net Core application runs fine when debugging with VS Code, but when running in a Docker container I receive an error:

SqliteException: SQLite Error 1: 'no such table: MyTable'.

I figured this is because I need to run the Entity Framework migrations when I build the Docker image. I have added dotnet ef database update to my Dockerfile, which looks like:

FROM microsoft/dotnet:sdk AS build-env
WORKDIR /app

COPY *.csproj ./
RUN dotnet restore

COPY . ./
RUN dotnet publish -c Release -o out

RUN dotnet ef database update

FROM microsoft/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "MyApplication.dll"]

The image builds without errors. However, when I create a container and look at the database, it is empty with no tables.

What is the correct way to set up a database with Entity Framework when building a Docker image?

4 Answers 4

22

For anyone on .net 6 I used this to apply migrations at startup just before app.Run() in Program.cs file

using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;

    var context = services.GetRequiredService<ApplicationDbContext>();
    if (context.Database.GetPendingMigrations().Any())
    {
        context.Database.Migrate();
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Running migrations from a web server is generally not a good idea - if you have more than one node running (e.g. you're running a load-balanced configuration) then it's possible each node will attempt to run the migrations on start-up. It's probably okay to do this in dev environments, but you really don't want to be doing this in production.
Simple enough, thank you.
9

Regardless of your deployment type, you can Apply migrations at runtime on your Startup class at the very end of your Configure method, e.g. calling the following method:

public void ApplyMigrations(ApplicationDbContext context) {
    if (context.Database.GetPendingMigrations().Any()) {
        context.Database.Migrate();
    }
}

1 Comment

This should only be used on small deployments (max 1 instance) to make sure the migration is not executed in parallel by more than one process
4

A couple of things:

1) A RUN command in a Dockerfile is an instruction executed during the build of the container image - so it will run once (and probably fail because there's no database) where you are building the image rather than when you later run the image.

2) I would recommend separating performing migrations from the deployment of a new version of your container. You may only be running a single copy of the container at the moment, but if you ever ran 2 or more then you would have multiple containers all checking to see if they should run migrations and that could cause issues. There's also the problem that you have deployed code that depends upon the migration, but you don't yet know that the migration will work - better to run the migrations first, and if they fail, don't deploy the new container.

Comments

0

For using Entity Framework in ASP.Net Core using Docker, we have to write the Dockerfile as -

FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /app
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o out
RUN dotnet tool install --global dotnet-ef --version 3.1
ENV PATH="$PATH:/root/.dotnet/tools"
RUN dotnet ef migrations add InitialCreate
RUN dotnet ef database update

FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS runtime
WORKDIR /app
COPY --from=build /app/out .
EXPOSE 80
ENTRYPOINT ["dotnet", "YourProjectName.dll"]

Note  -  Before building image using this Dockerfile, ensure that you have the database server running.

For setting up Sql Server Database, you can run the docker command 
as -
 
docker run --name sqlserver -e ACCEPT_EULA=Y -e SA_PASSWORD=password -p 1433:1433 -d mcr.microsoft.com/mssql/server

Here Username will is 'sa' and Password is password.

 

2 Comments

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
Also note that your command attempts to create a new migration on every run. This will fail after the first run. The migration should be created during development and let dotnet decide which should be applied

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.