Windows Docker containers

At work, I was trying to take a C++ ISAPI DLL project and see if I can get it running in a windows container. In this blog post, I will cover my findings when working with Windows Containers – for anyone who doesn’t know there is no GUI so my blog post will cover how to do some steps using PowerShell. The end goal here is to containerize a Windows IIS legacy web app and move it to AKS without re-writing it.


I had never used Docker on a real project until now so had barely used it (please bear this in mind), please note there may and probably is a better way to do some of the following, I have written this to give you a starter for 10 if you need to work with a windows container and might need to do some legacy work.

The following are some tips on how to do stuff using windows containers and what I have been learning the last 2 weeks.

You have the option to use all manner of Windows Containers, for the work I was doing I was using the following: –

FROM mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2016

SHELL ["powershell"]
COPY SetupGregor.ps1 .
RUN powershell -File .\SetupGregor.ps1
COPY Setup C:/Setup

RUN reg import .\odbcinistuff.reg
RUN Start-Process -FilePath msodbcsql.msi -ArgumentList "IACCEPTMSSQLCMDLNUTILSLICENSETERMS=YES"

RUN Set-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Services\InetInfo\Parameters'  -Name PoolThreadLimit -Value 512 -Type DWord

# Install windows features
RUN Install-WindowsFeature NET-Framework-45-ASPNET ; \
     Install-WindowsFeature Web-Asp-Net45 ; \
     Install-WindowsFeature Web-Static-Content ; \
     Install-WindowsFeature Web-Http-Errors ; \
     Install-WindowsFeature Web-Default-Doc ; \
     Install-WindowsFeature Web-ISAPI-Filter ; \
     Install-WindowsFeature Web-Stat-Compression ; \
     Install-WindowsFeature Web-ISAPI-Ext ; \
     Install-WindowsFeature Web-ISAPI-Filter 

# IIS stuff
RUN Install-WindowsFeature Web-Mgmt-Service; \
New-ItemProperty -Path HKLM:\software\microsoft\WebManagement\Server -Name EnableRemoteManagement -Value 1 -Force; \
Set-Service -Name wmsvc -StartupType automatic; 

# Add user for Remote IIS Manager Login
RUN net user iisadmin <putyourpasswordhere> /ADD; \
net localgroup administrators iisadmin /add;

COPY Setup/LogMonitor.exe c:/LogMonitor
COPY Setup/LogMonitorConfig.json c:/LogMonitor

CMD Write-Host IIS Started... ; \
    while ($true) { Start-Sleep -Seconds 3600 }

The above are just samples of whats possible, lets cover them one by one below.

  • FROM mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2016 – here I am saying use the windowsservercore-ltsc2016 windows image.
  • SHELL [“powershell”] – here since I am using a windows container I want to use the PowerShell shell.
  • COPY SetupGregor.ps1 . – here I just copy a single file into my container.
  • RUN powershell -File .\SetupGregor.ps1 – here I am running a powershell file.
  • COPY Setup C:/Setup – here I am copying a full folder into the container.
  • RUN reg import .\odbcinistuff.reg – here I exported a registry file from a test server so that I can import this into my container and use it to setup ODBC System DSN’s that I needed.
  • RUN Start-Process -FilePath msodbcsql.msi -ArgumentList “IACCEPTMSSQLCMDLNUTILSLICENSETERMS=YES” – here I am running an msi silently in my container to install ODBC sql drivers
  • RUN Set-ItemProperty -path ‘HKLM:\SYSTEM\CurrentControlSet\Services\InetInfo\Parameters’  -Name PoolThreadLimit -Value 512 -Type DWord – here is a sample on how to set a new registry key inside my windows container.
  • RUN Install-WindowsFeature NET-Framework-45-ASPNET; – yep you guessed it I’m installing windows features in my windows container.
  • RUN Install-WindowsFeature Web-Mgmt-Service; \
    New-ItemProperty -Path HKLM:\software\microsoft\WebManagement\Server -Name EnableRemoteManagement -Value 1 -Force; \ – here I am setting up the ability to connect remotely into IIS running on my container – this helps enormously when you can see the IIS settings etc from outside your windows container.
  • Set-Service -Name wmsvc -StartupType automatic; – here I make sure the service starts automatically.
  • RUN net user iisadmin <putyourpasswordhere> /ADD; \net localgroup administrators iisadmin /add; – here I create a user I can use to connect into IIS on the container – I also run the app pool using this account.
  • COPY Setup/LogMonitor.exe c:/LogMonitor
    COPY Setup/LogMonitorConfig.json c:/LogMonitor – here I am copying LogMonitor (https://github.com/microsoft/windows-container-tools/tree/master/LogMonitor) This is an opensource .exe which you can use to monitor logs like IIS and the event viewer etc, its a C++ project which I have built, in case
    you don’t have the tooling handy – you can find that here – https://github.com/gsuttie/LogMonitor
  • CMD Write-Host IIS Started… ; \
     while ($true) { Start-Sleep -Seconds 3600 } – here I keep the windows container running as long as IIS is running, if you stop IIS the container will shut down (restart the app-pool instead if you need to make changes, saves you having to restart the container.)

Buld your container using a Dockerfile like the one above:-

docker image build --tag win2016GregorsDemo .

Start your Docker image

Docker run --name remoteiisGregor -d -p 8000:80 win2016GregorsDemo 

It will start up instantly then you can get the ipaddres like so

 docker inspect --format '{{ .NetworkSettings.Networks.nat.IPAddress }}' remoteiisGregor 

Now you can connect to IIS on the container from your local desktop

Add in the IP Address and then when asked for a username and password, the username is in the Dockerfile.

Username: IISadmin
Password: ********* (whatever you add in the dockerfile)

And viola – you should now be able to connect to IIS running inside a windows container.

Now to check settings within the container you can connect to the container doing the following:-

Docker ps -a

This will give you the containerId like the following:-

Now you can grab the first 3 letters of the container id and type this

Docker exec -it 32d powershell

And now you can connect to the container with a powershell shell windows and check folders, run commands etc.

Summary
You may ask why? – Whay am I doing this, well when a customer asks if they can go to AKS with an existing solution and it needs to run on windows containers, I thought yeah let;s get it working.

This is brief blog post which doesnt go into huge detail, if you have questions please just ask, I dont have much time under my belt with Docker but I learned a lot and figure out a number of things.