首页 文章

docker asp.net核心容器在mysql容器之后启动

提问于
浏览
1

我有一个带有asp.net核心的docker容器和一个带有mysql的容器 . 现在我需要等待asp.net核心容器,因为mysql容器已经准备就绪(两个容器都是通过docker-compose.yml启动的) .

https://github.com/jwilder/dockerize,wait-for-it.sh或wait-for似乎不适用于asp.net核心容器 .

有人知道如何解决问题?

UPDATE

这是我的dockerfile:

FROM microsoft/aspnetcore-build:2.0 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore test.csproj

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out test.csproj



# Build runtime image
FROM microsoft/aspnetcore:2.0
WORKDIR /app
COPY ./entrypoint.sh ./app/
RUN chmod +x ./app/entrypoint.sh
CMD /bin/bash ./app/entrypoint.sh

COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "test.dll"]

这是我的entrypoint.sh:

#!/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

如果我用docker-compose启动容器我得到错误消息:

Unhandled Exception: System.FormatException: Value for switch '/app/entrypoint.sh' is missing.
test          |    at Microsoft.Extensions.Configuration.CommandLine.CommandLineConfigurationProvider.Load()
test          |    at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
test          |    at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
test          |    at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
test          |    at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
test          |    at test.Program.Main(String[] args) in /app/Program.cs:line 19

如何将ENTRYPOINT和CMD / bin / bash ./app/entrypoint.sh命令合并到一个文件中 . 我认为我需要运行dotnet应用程序的ENTRYPOINT和entrypoint.sh的cmd来等待数据库容器 . 是否有解决方案可以运行?

2 回答

  • 0

    https://docs.docker.com/compose/aspnet-mssql-compose/

    docker docs列出了如何通过对数据库连接进行entrypoint.sh轮询来让ASP.net容器等待它的数据库 .

    #!/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
    
  • 0

    您可以检查并等待来自 within 您的dotnet应用程序的数据库连接,而不是让脚本延迟您的dotnet应用程序 from outside 的启动 .

    在下文中,您可以看到 host.Run() 如何推迟到 waitForDb() 返回 .

    在下面的示例中,我将逻辑用于检查SQL DB(在docker容器中运行)是否已经在名为 DbHealthChecker 的服务中启动(实际上,整个方法 waitForDb 可以在专用服务中) . 此运行状况检查程序使用this stackoverflow thread中描述的技术之一来检查数据库是否正在运行 .

    public class Program
    {
      public static void Main(string[] args)
      {
        var host = CreateWebHostBuilder(args).Build();
    
        Task.Run(async () => {
          using (var scope = host.Services.CreateScope())
          {
            var services = scope.ServiceProvider;
    
            await waitForDb(services);
    
            // ... other initializations, e.g. seeding db ...
          }
        }).Wait();
    
        host.Run();
      }
    
      private static async Task waitForDb(IServiceProvider services)
      {
        // create your own connection checker here
        // see https://stackoverflow.com/questions/19211082/testing-an-entity-framework-database-connection
    
        var healthChecker = services.GetRequiredService<DbHealthChecker>();
        var maxAttemps = 12;
        var delay = 5000;
    
        for (int i = 0; i < maxAttemps; i++) {
          if (healthChecker.isConnected()) {
            return;
          }
          await Task.Delay(delay);
        }
    
        // after a few attemps we give up
        throw new HttpException(503);
      }
    }
    

相关问题