Lea*_*ker 17 c# docker .net-core dockerfile asp.net-core
我试图在docker容器中运行.net核心1.0.0控制台应用程序.
当我dotnet run从我的机器上的Demo文件夹中运行命令时,它工作正常; 但是当使用时docker run -d --name demo Demo,容器会立即退出.
我试图docker logs demo检查日志,它只显示Console.WriteLine中的文本:
演示应用运行...
没有别的.
我已经在https://github.com/learningdockerandnetcore/Demo上传了该项目
该项目包含Programs.cs,Dockerfile用于创建Demo图像和project.json文件.
Fei*_*hou 15
如果将应用程序切换到目标.net core 2.0,则可以使用Microsoft.Extensions.Hosting pacakge通过使用HostBuilder API来启动/停止应用程序来托管.net核心控制台应用程序.其ConsoleLifetime类将处理常规应用程序启动/停止方法.
为了运行您的应用程序,您应该实现自己的IHostedService接口或从BackgroundService类继承,然后将其添加到主机上下文中ConfigureServices.
namespace Microsoft.Extensions.Hosting
{
//
// Summary:
// Defines methods for objects that are managed by the host.
public interface IHostedService
{
// Summary:
// Triggered when the application host is ready to start the service.
Task StartAsync(CancellationToken cancellationToken);
// Summary:
// Triggered when the application host is performing a graceful shutdown.
Task StopAsync(CancellationToken cancellationToken);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个示例托管服务:
public class TimedHostedService : IHostedService, IDisposable
{
private readonly ILogger _logger;
private Timer _timer;
public TimedHostedService(ILogger<TimedHostedService> logger)
{
_logger = logger;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Timed Background Service is starting.");
_timer = new Timer(DoWork, null, TimeSpan.Zero,
TimeSpan.FromSeconds(5));
return Task.CompletedTask;
}
private void DoWork(object state)
{
_logger.LogInformation("Timed Background Service is working.");
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Timed Background Service is stopping.");
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose()
{
_timer?.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
然后创建HostBuilder并添加服务和其他组件(日志记录,配置).
public class Program
{
public static async Task Main(string[] args)
{
var hostBuilder = new HostBuilder()
// Add configuration, logging, ...
.ConfigureServices((hostContext, services) =>
{
// Add your services with depedency injection.
});
await hostBuilder.RunConsoleAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
小智 10
您应该在交互模式下运行容器(带-i选项).但请注意,当您运行容器时,后台进程将立即关闭,因此请确保您的脚本在前台运行,否则它将无法正常工作.
Jay*_*Jay 10
我可以让Docker/Linux保持我的.NET Core应用程序活着的唯一方法就是欺骗ASP.NET为我托管它...这是一个如此丑陋的黑客!
这样做将使用该docker run -d选项在Docker中运行,因此您不必具有实时连接以保持STDIN流存活.
我创建了一个.NET Core控制台应用程序(不是ASP.NET应用程序),我的Program类看起来像这样:
public class Program
{
public static ManualResetEventSlim Done = new ManualResetEventSlim(false);
public static void Main(string[] args)
{
//This is unbelievably complex because .NET Core Console.ReadLine() does not block in a docker container...!
var host = new WebHostBuilder().UseStartup(typeof(Startup)).Build();
using (CancellationTokenSource cts = new CancellationTokenSource())
{
Action shutdown = () =>
{
if (!cts.IsCancellationRequested)
{
Console.WriteLine("Application is shutting down...");
cts.Cancel();
}
Done.Wait();
};
Console.CancelKeyPress += (sender, eventArgs) =>
{
shutdown();
// Don't terminate the process immediately, wait for the Main thread to exit gracefully.
eventArgs.Cancel = true;
};
host.Run(cts.Token);
Done.Set();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Startup类:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IServer, ConsoleAppRunner>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
}
}
Run Code Online (Sandbox Code Playgroud)
ConsoleAppRunner类
public class ConsoleAppRunner : IServer
{
/// <summary>A collection of HTTP features of the server.</summary>
public IFeatureCollection Features { get; }
public ConsoleAppRunner(ILoggerFactory loggerFactory)
{
Features = new FeatureCollection();
}
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
public void Dispose()
{
}
/// <summary>Start the server with an application.</summary>
/// <param name="application">An instance of <see cref="T:Microsoft.AspNetCore.Hosting.Server.IHttpApplication`1" />.</param>
/// <typeparam name="TContext">The context associated with the application.</typeparam>
public void Start<TContext>(IHttpApplication<TContext> application)
{
//Actual program code starts here...
Console.WriteLine("Demo app running...");
Program.Done.Wait(); // <-- Keeps the program running - The Done property is a ManualResetEventSlim instance which gets set if someone terminates the program.
}
}
Run Code Online (Sandbox Code Playgroud)
关于它的唯一好处是你可以在你的应用程序中使用DI(如果你愿意) - 所以在我的用例中,我使用ILoggingFactory来处理我的日志记录.
编辑2018年10月30日 这篇文章似乎仍然很受欢迎 - 我只想指出任何阅读我的旧帖子的人现在都很古老了.我的基础是.NET核心1.1(当时是新的).如果你使用更新版本的.NET核心(2.0/2.1或更高版本),那么现在可能有更好的方法来解决这个问题.请花些时间查看此主题上的其他一些帖子,这些帖子可能不如此排名高,但可能更新,更新.
您可以使用:
Thread.Sleep(Timeout.Infinite);
Run Code Online (Sandbox Code Playgroud)
看到这个答案:
是 Thread.Sleep(Timeout.Infinite); 比 while(true){} 更有效率?
| 归档时间: |
|
| 查看次数: |
10102 次 |
| 最近记录: |