4

I have a console application written in C# using servicestack that has the following form:

static void Main(string[] args)
        {
            //Some service setup code here

            Console.ReadKey();
        }

This code works fine when run on windows as a console. The implementation is almost exactly https://github.com/ServiceStack/ServiceStack/wiki/Self-hosting as this is a test project

I then compile this project using mono on linux and build into a docker file.

I have no problems running up a container based on this image if it is interactive

docker run -it --name bob -p 1337:1337 <myservice>

The container runs in the foreground

However, if I omit the -it switch, the container exits straight away - I assume because there is no STDIN stream, so the Console.ReadKey() doesn't work.

I am trying to get the service hosted in a swarm, so there is no notion of detached. I can spin up a loop within my main method to keep the console service alive, but this seems hacky to me...

Is there a good way of keeping my service alive in the situation where I want to run my container detatched (docker run -d...)

Jay
  • 9,561
  • 7
  • 51
  • 72
  • This answer seems like it could work? http://stackoverflow.com/a/34099238/1318694 – Matt Aug 31 '16 at 10:35
  • Wait.Set() should run on a SIGINT and SIGTERM... however that would work in C#/mono. – Matt Aug 31 '16 at 10:37
  • Hmmm... I'll give that a try... – Jay Aug 31 '16 at 10:37
  • Yep - doing it that way works - add an answer and I'll mark it as correct... thanks! Also found this which had a similar example... http://stackoverflow.com/q/2586612/685341 – Jay Aug 31 '16 at 10:43
  • Cool. Feel free to edit in the signal code. – Matt Aug 31 '16 at 10:51
  • Of note to anybody viewing this question, spin up a loop within main method does consume CPU resources, i've found it uses a single core on my comp. You dont really want to `while(true) ;` and use other alternatives to not waste CPU time on looping indefinitely. Console.ReadKey actually uses internal Windows to wait for messagepump signals of keyboard interactions, which doesnt consume CPU resources. WaitOne answer also doesnt consume CPU – enorl76 Apr 27 '22 at 17:25

1 Answers1

7

Stealing from this answer for keeping .NET apps alive, you can wait without using Console which means you don't need to keep stdin open in Docker (docke run -i) :

private ManualResetEvent Wait = new ManualResetEvent(false);
Wait.WaitOne();

Docker will send a SIGTERM on docker stop and a ctrl-c will send a SIGINT so those signals should be trapped and then you let the program end with

Wait.Set();
Matt
  • 68,711
  • 7
  • 155
  • 158