EntityFramework.Docs icon indicating copy to clipboard operation
EntityFramework.Docs copied to clipboard

SQL Migration does not run in docker

Open dabagab opened this issue 6 years ago • 11 comments

Describe the bug

I have followed some articles to be able to use the aspnet core application with sql server. Unfortunately the migration command does not run.

Steps to reproduce the issue

Provide steps for us to reproduce the issue

  1. Creating a new Asp.net Core 2.2 Web (MVC) project from the official template in the Visual Studio 2019.
  2. Adding Docker-Compose support to the project.
version: '3.4'

services:
  api:
    image: ${DOCKER_REGISTRY-}api
    build:
      context: .
      dockerfile: Api/Dockerfile
    depends_on:
      - db

  db:
    image: "mcr.microsoft.com/mssql/server"
    environment:
      SA_PASSWORD: "Your_password123"
      ACCEPT_EULA: "Y"

The Docker file was generated by Visual Studio. I inserted some line to run the entrypoint.sh

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["Api/Api.csproj", "Api/"]
RUN dotnet restore "Api/Api.csproj"
COPY . .
WORKDIR "/src/Api"
RUN dotnet build "Api.csproj" -c Release -o /app

FROM build AS publish
# Inserted lines
COPY ./entrypoint.sh ./app/
RUN chmod +x ./app/entrypoint.sh
CMD /bin/bash ./app/entrypoint.sh
RUN dotnet publish "Api.csproj" -c Release -o /app

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

Entrypoint.sh is from the tutorial of docker page.

#!/bin/bash

set -e
run_cmd="dotnet run --server.urls http://*:80"

until dotnet ef database update; do
>&2 echo "SQL Server is starting up"
sleep 1
done

>&2 echo "SQL Server is up - executing command"
exec $run_cmd

Expected behavior

When I run the Docker-Compose project in VS 2019 then I expect the migration has run. But this is not happen.

Additional information

I did not find any official step-by-step tutorial.

dabagab avatar May 05 '19 12:05 dabagab

Migrations do not automatically run when your application begins. Running dotnet App.dll will only start the web server. A separate action is required to run migrations.

@ajcvickers - do you have documentation or recommendations on how to achieve migrations inside a docker workflow?

natemcmaster avatar May 29 '19 22:05 natemcmaster

short answer might be

        public static async Task Main(string[] args)
        {
            var host = CreateWebHostBuilder(args).Build();
            using (var scope = host.Services.CreateScope())
            {
                scope.ServiceProvider.GetRequiredService<AppDbContext>().Database.Migrate();
            }
            host.Run();
	}

But I wouldn't say that it's recommended

alexk8 avatar May 31 '19 03:05 alexk8

Notes from triage:

  • We don't currently have any guidance on how to do this. Putting this on the backlog to investigate what people should do here.
  • We should also consider if the web publishing support could handle this better--we need to follow up with the web tools team on this.
  • For now, a few ways to handle this are:
    • Run dotnet-ef commands in the container. This will work only if the SDK is installed into the container. @dabagab This might be what you are running into.
    • Generate a SQL script from Migrations and then use it to create/migrate the database from within the container. This will require a tool in the container that can run the SQL.
    • Use either dotnet-ef or a SQL script from outside the container using a connection to the database from outside the container.

ajcvickers avatar Jun 03 '19 16:06 ajcvickers

Assigning to @bricelam to review; may be not action here.

ajcvickers avatar Sep 17 '20 22:09 ajcvickers

@ajcvickers Any updated guidance on how to run migrations in Docker?

syedhassaanahmed avatar Nov 17 '20 00:11 syedhassaanahmed

@syedhassaanahmed No; this issue is tracking adding this guidance to the docs.

ajcvickers avatar Nov 19 '20 20:11 ajcvickers

I have resolved via option 3:

  • expose the database port to your host in docker-compose.yml
  • implement IDesignTimeDbContextFactory
public class ChassisDbContextFactory : IDesignTimeDbContextFactory<ChassisDbContext>
{
    public ChassisDbContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<ChassisDbContext>();
        optionsBuilder.UseNpgsql();

        return new ChassisDbContext(optionsBuilder.Options);
    }
}
  • cd to the project with the DbContext and provide the connection string via new --connection parameter (EF Core 5.0)
dotnet ef database update --connection "Host=localhost;Database=chassis;Username=postgres;Password=password"

My run-time connection is set up using normal appsettings.json:

services.AddDbContext<ChassisDbContext>(options =>
    options.UseNpgsql(configuration.GetConnectionString("DefaultConnection"))
);

davelowndes avatar Feb 15 '21 07:02 davelowndes

Hi, any updates ?

CyberoxiDevops avatar Mar 10 '22 22:03 CyberoxiDevops

I have the same problem. Any solution for that ?

ddatdt12 avatar Sep 03 '22 09:09 ddatdt12

I have the same problem. Any solution for that ?

xLolalilo avatar Apr 29 '24 17:04 xLolalilo

So I just resorted back into doing Update-Database manually after doing a docker compose, I guess this could somewhat be automated with a script of some kind. Thanks either way though.

xLolalilo avatar Apr 29 '24 19:04 xLolalilo