我有一个带有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"]
这是我的入口点。
#!/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命令合并到一个文件中。我认为我需要ENTRYPOINT才能运行dotnet应用程序,而cmd则需要entrypoint.sh来等待数据库容器。有没有解决方案可以同时运行?
答案 0 :(得分:0)
https://docs.docker.com/compose/aspnet-mssql-compose/
泊坞窗文档列出了如何通过让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
答案 1 :(得分:0)
除了具有从外部推迟推迟启动dotnet应用程序的脚本之外,您还可以从在内部检查并等待数据库连接。
在下面,您可以了解如何将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);
}
}