I am new to Docker, and I would like to know if it is possible to “Dockerize” a Windows Service created in .NET. I have not been able to find a good tutorial on this, or an article that would somehow show me the step by step process on how to do it. I have several windows services I created, and I would like them to be in Docker-Container. Is this possible? Thanks in advance, guys!
Thank you very much. Yes, I have heard of .NET Core, but I haven’t tried it yet. From your own experience, have you tried “converting” classic windows services so that it will be .NET Core-capable? Been wanting to have my windows services run in Docker-Container. Thank you very much in advance!
Windows containers are only available in insiders build.
So if your .NET service cannot run on Linux it’s not yet possible.
As soon as windows containers will be installed by default we’ll support it (by the end of the year).
Hi @ebriney, thanks for your inputs. Yes, basically .NET windows services cannot run on linux, since they aren’t built to run for that OS. I hope there will be a solution for .NET windows services for Dockers in the near future. Thanks for your reply.
I’m going to try and revive this thread because I’m pretty sure it’s possible now and I’m also interested in that answer.
I’m new to docker but from what I understand, in principle, you can now pull a Windows server/nanoserver image and build on top of it.
You can install your service using power shell and start it (or even plain old command line maybe)
I’m not sure how to send the stop signal to the service when the container stops.
Then I think you can really reuse your service as is and you don’t even need to migrate it to .net core, but you have to run the image on docker for Windows which requires Windows 10 pro or server 2016, to my knowledge.
If you want to be able to run your image on Linux, you’ll need to rewrite your code a bit to migrate to .net core, and build on top of the .net core image.
I haven’t tried it yet but I will when I find some time.
Docker requires the primary process of the container (the CMD or ENTRYPOINT, in Dockerfile terms) to be a normal executable, not a service. There are three things special about this process.
The container stays up as long as this process is running.
Environment variables for this process can be set by the docker engine, for example via -e switches of the docker create or docker run commands.
The standard output and standard error of this process goes to the docker log.
Windows services are run under the control of the Windows Service Control Manager, which manages their lifetime. Therefore, they cannot be used as the primary process. However, Docker for Windows does allow you to install and run services in docker containers, as long as there is a primary process which keeps the container alive.
In the official Microsoft images microsoft/iis and microsoft/aspnet, a program called ServiceMonitor.exe is used as the primary process. This monitors the IIS service (w3svc) and stops itself (and therefore the container) when the service stops. In this way, it fulfils the first criterion in the list above. It also injects its own environment variables into the IIS process, thus fulfilling the second criterion. It does not try to fulfil the third. You can find the source code here. You can possibly adapt this.
However, this is not the perfect solution. Why do we create a Windows service? Probably because we want it to start without manual intervention, run as a different user, and sit in the background listening for requests. We can do all three using a container. But the container requires a regular executable.
So, I would probably begin by refactoring the actual functionality of your service into a separate class. Then, I would keep your Windows Service project (which should now have a Service class that uses your functionality class) for non-container use. And I would create a new console application, which uses the same functionality class, and use this console application as the ENTRYPOINT of a container.
The following Dockerfile works well for me in building a Windows Service into a docker image. All your service files need to be in the ‘Installs’ folder of the docker context, plus a copy of the InstallUtils.exe file (from .NET / Visual Studio).
# escape=\
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.7.2-windowsservercore-1709
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
COPY ["Installs/", "/Service/"]
WORKDIR "C:/Service/"
RUN "C:/Service/InstallUtil.exe" /LogToConsole=true /ShowCallStack SmartFormsToWorkInjuryReportingService.exe; \
Set-Service -Name "\"My Windows Service Name\"" -StartupType Automatic; \
Set-ItemProperty "\"Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\My Windows Service Name\"" -Name AllowRemoteConnection -Value 1
ENTRYPOINT ["powershell"]
CMD Start-Service \""My Windows Service Name\""; \
Get-EventLog -LogName System -After (Get-Date).AddHours(-1) | Format-List ;\
$idx = (get-eventlog -LogName System -Newest 1).Index; \
while ($true) \
{; \
start-sleep -Seconds 1; \
$idx2 = (Get-EventLog -LogName System -newest 1).index; \
get-eventlog -logname system -newest ($idx2 - $idx) | sort index | Format-List; \
$idx = $idx2; \
}
FYI, you can then run the service by:
docker run --rm --net=MyNet --platform=windows -p 80:80 --name MyWindowsServiceContainer mywindowsserviceimage
HI All,
I am using .net framework 4.7 . I created GRPC server using console application. but it does not run on container . i f i run it manually its working .
So how can i run it with container on kubarnetes window server?
Please help me!