I am trying to run a .net core 1.0.0 console application inside a docker container.
When I run dotnet run
command from inside the Demo folder on my machine, it works fine; But when run using docker run -d --name demo Demo
, the container exits immediately.
I tried docker logs demo
to check the logs and it just shows the text from the Console.WriteLine:
Demo app running...
and nothing else.
I have uploaded the project at https://github.com/learningdockerandnetcore/Demo
The project contains Programs.cs
, Dockerfile
used to create Demo image, and project.json
file.
You can use:
Thread.Sleep(Timeout.Infinite);
See this answer:
Is Thread.Sleep(Timeout.Infinite); more efficient than while(true){}?
The only way I could get Docker/Linux to keep my .NET Core application alive was to spoof ASP.NET into hosting it for me... This is such an ugly hack!!
Doing it this way will run in Docker using the
docker run -d
option, so you don't have to have a live connection to keep the STDIN stream alive.I Created a .NET Core console application (not an ASP.NET app) and my Program class looks like this:
The Startup class:
The ConsoleAppRunner class
The only nice thing about it is that you get to use DI in your application (if you want to) - so in my use case, I am using the ILoggingFactory to handle my logging.
Edit 30th Oct 2018 This post still seems to be popular - I'd like to just point out to anyone reading my old post that it is now pretty ancient. I was basing it on .NET core 1.1 (which was new at the time). It is likely that if you are using a newer version of.NET core (2.0 / 2.1 or greater) that there is probably a much better way of solving this problem now. Please take time to look at some of the other posts on this thread which may not be as highly ranked as this one, but may be newer and more up-to-date.
Using
Console.ReadLine
instead seems to work.C#:
F#:
one more "dirty way" is to start your program in screen using
I am not sure why
Console.ReadLine();
doesn't block the main thread when running a dotnet core console app in a detached docker container, but the best solution is to register aConsoleCancelEventHandler
with theConsole.CancelKeyPress
event.Then you can instead block the main thread with a type of Threading
WaitHandle
and signal the release of the main thread whenConsole.CancelKeyPress
is fired.A good example code can be found here: https://gist.github.com/kuznero/73acdadd8328383ea7d5
If you switch your app to target .net core 2.0, then you can use Microsoft.Extensions.Hosting pacakge to host a .net core console application by using the HostBuilder API to start/stop your application. Its ConsoleLifetime class would process the general aplication start/stop method.
In order to run your app, you should implement your own
IHostedService
interface or inherit from theBackgroundService
class, then add it to host context withinConfigureServices
.Here's a sample hosted service:
Then creating the HostBuilder and adding the service and other componments (logging, configuration).