The only source of knowledge is experience

Deploying ASP.NET 4.5 to Docker on Windows

At the moment of this writing you can search the internet on ASP.NET and docker and all you will find is how to deploy ASP.NET Core applications to a Linux docker container. Although I love the initiative of ASP.NET core, I do believe that ASP.NET 4.5 is something many of you know and love already and nobody talks about how we can leverage docker on windows to run this full version of ASP.NET

To get you started we need to have a Windows version that is capable of natively running docker. With natively running docker I mean that docker is build into the OS. So no use of docker for windows tools, since we don’t want Linux containers, we want to run windows containers! At this moment you can use Windows 10 Anniversary edition and Windows Server 2016 Technical Preview 5 to go through the steps that I describe here to get your ASP.NET 4.5 website running in a docker on windows container.

What do we need to rollout an ASP.NET website to a windows docker container?

When you run an ASP.NET 4.5 website then you need the following things:

  • The Operating system with IIS installed
  • ASP.NET 4.5 installed
  • Webdeploy installed

I personally love to use web deploy to deploy the website after build, so it can be done exactly the same way as you would deploy to Azure App Services or your local IIS Server on any server you already know and love.

Building the container with IIS, ASP.NET and Webdeploy

Here are the steps you need to take to create a docker container that has all these required ingredients:

Fist we need a basic operating system image from docker hub. For this you can run the following command from the command line:

now we have the image in our images gallery, you can check this with the following command:

This should output something similar to the following screenshot:



Now we can start adding the first layer and that is installing IIS. For this you can use the dism command on windows and pass it in the arguments to install the IIS webserver role to windows server core. You can do this at an interactive prompt or use the docker build command. I prefer the later and for this we create a dockerfile that contains the following statements:

After saving the file under the name dockerfile without any extensions you run a command line to build the image:

The command tells docker to build an image, give it the tag windowsserveriis and use the current folder (denoted with the dot) as the context to build the image. this means that everything stated in the dockerfile is relative to that context. Note that you are only allowed to use lowercase characters for the tagename.

After running the command you now have a new docker image with the name windowsserveriis

If you now run the command:

you will see the new image available


We can take the next step and that is to install ASP.NET 4.5

We can do this in a similar way, by creating a docker file with the following commands:

and again after saving the file you can run the command line to build the image:

Now we have an image that is capable of running an ASP.NET application. The next step is that we need webdepoy to be installed in the container. For this we need to download the installer for webdeploy and then issue an command that will install and wait for the installation to finish. We first download the installer in the same folder as the dockerfile and then we will add it to the image. In the following steps I assume you already downloaded the MSI (WebDeploy_2_10_amd64_en-US.msi) and have it in the same folder as the dockerfile. When installing the msi we will use msiexec and need to start a process that we can wait on to be done. If we would only run msiexec, then this command returns and runs in the background, making the container to exit, leaving us in an undefined state.

When you create the following dockerfile, you install webdeploy:

Note that we are using powershell start-process with the –wait option, so we wait for the installation to finish, before we commit the new layer.

Now run the docker command again to build the image using the new dockerfile:

Now we have an image that is capable to host our website in IIS and use webdeploy to install our website.

Doing it all in one dockerfile

In the previous steps we created a new docker file for each step. But it is probably better to do this in one file, batching all commands together leaving you with the same endstate. We can also optimize the process a bit, since Microsoft already provides an image called microsoft/iis that has the iis feature enabled. This means we can use that image as the base layer and skip the install of IIS.

The simplified docker file looks as follows:

Now again we run the docker build command to get the docker image capable of running our website and use the webdeploy packages that can be produced by a standard ASP.NET build procedure.

The final step is to deploy your webdeploy package to the image.

Getting the webdeploy package

Now before we can deploy our website we need to get the webdeploy package.

I assume you have a standard ASP.NET web project in Visual Studio. In this case you can very easily create the deploy package inside Visual Studio (in the next post I show you how to do this using VSTS/TFS builds)

When you right click the Visual Studio project you can select the publish option:


After selecting publish you will see the following dialog:


In order to just create a package in stead of deploying to a server or Azure, I select Custom


then you give the profile a name, in my case dockerdeploydemo


then we select web deploy package from the dropdown and provide the required information, package location and the name of the website


next you can setup any database connections if you have any, in my case I have no database


next, click publish and you will find the resulting deployment package and accompanying deployment files in the c:\temp folder


Now that we have the webdeploy package and the accompanying deployment artifacts, we can again create a docker file that will then upload the package to the container and install the website in the container. This will then leave you with a complete docker image that runs your website.

Publish the website in the docker container

The dockerfile to deploy your website looks as follows:

We build the container again using the docker build command:

This now finally results in our web application in a container that we can then run on any windows server that has windows containers enabled.

Running the website in the container

In order to test if we succeeded we now issue the docker run command and then map the container port 80 to a port on our host. This can be done by using the –p option, where you specify a source and destination port. We also need to specify a command that ensures the container keeps running. For this we now use e.g. a command like ping –t which will result in an endless ping loop, that is enough to keep the container running. so to test the container we now run the following command:

Now we can browse to the website. Be aware that you can only reach the container from the outside, so if you would browse to localhost, which results in the you will not see any results. You need to address your machine on its actual hostname or outside IP address.


To summarize what we have done, we first created a docker image capable of running IIS, then we added ASP.NET 4.5, then we added webdeploy and finally we deployed our website to the container using webdeploy and the package generated by Visual Studio.

In the next post I will show you how we can use this image in build and release management using VSTS and then deploy the container to a server so we can run automated tests as a stage in the delivery pipeline.


  1. Temu

    I was stuck at the “docker pull microsoft/iis” step for a while because it kept timing out saying “unknown blob”. The problem was resolved by getting docker 1.13 using this link. I thought this would be helpful for someone.

  2. Temu

    Forgot to mention, this guide is very helpful and exactly what I was looking for. Great job! Thank a lot

  3. Julian Perrott

    Thanks for this guide. I tried it on Windows Server 2016.

    I needed to use “Default Web Site/dockerdeploydemo” as my site name when publishing otherwise web deploy gives me Error Code: ERROR_SITE_DOES_NOT_EXIST.

    Once past this web deploy adds all the files to the site then I get this error:
    “Info: Adding ACL’s for path (Default Web Site\dockerdeploydemo)
    Error: This access control list is not in canonical form and therefore cannot be modified.
    Error count: 1.”
    Is this important ?

  4. Patrice

    Hello Marcel,

    Like in your post, I see a lot of blog posts about Docker on Windows where authors are using microsoft/windowsservercore image instead of using microsoft/aspnet image

    Is there any reason for this choice ?


    • Marcel

      Good point, no I did not have a specific reason. I have not tried it, but I assume you could then skip at least the first steps and only do the steps where you add webdeploy

  5. Shyam

    Hi Marcle,
    Very good article.
    I have one query while run below command
    “docker build –t mycontainerizedwebsite .”
    it gives me error like (unauthorized: authentication required)

    So what can be the resolution?


    • Marcel

      Are you running the command prompt in admin mode?

  6. Kasper Joergensen

    I am trying to follow along, but I am getting a weird error… I installed the windowsserveriis image, and I get to the ASP.NET installation. I should add that I created a folder in my directory for each Dockerfile. After I navigate to the local directory of ‘new’ dockerfile and run the command:
    docker build –t windowsserveriisaspnet .
    I get an error with the following message: docker : “docker build” requires exactly 1 argument(s)
    This initially I just thought I missed the dot on the end, but this is not the case. I have also tried changing the name of the dockerfile, and pointing to it with the command:
    docker build -windowsserveriisaspnet –file=”newdockerfile”

    Any helpful insight?

    • Bojan

      Type in command manually, do not copy-paste it.

  7. natasa

    was this Error Code: ERROR_SITE_DOES_NOT_EXIST resolved?
    Thank you.

  8. Vinod Panday

    Step 7/10 : ADD WebDeploy_2_10_amd64_en-US.msi /install/WebDeploy_2_10_amd64_en-US.msi
    GetFileAttributesEx WebDeploy_2_10_amd64_en-US.msi: The system cannot find the file specified.

    Showing error while building.

    • Kiran


  9. Sankar

    Hi Marcel,

    Based on the provided instruction I have executed and come up with the followings, but when I browse the website getting page cannot be display error..Please advice

    PS C:\sn\docker> docker images
    mycontainerizedwebsite latest 618780c33fa5 17 hours ago 10.5 GB
    windowsserveriisaspnetwebdeploy latest 11ef09e0921f 19 hours ago 10.5 GB
    windowsserveriisaspnet latest 7629b393ce2d 19 hours ago 10.4 GB
    windowsserveriis latest 53e22883f55b 20 hours ago 10.4 GB
    vsnarayanan19/windows-test-image latest ec49af2c98ee 7 days ago 10.1 GB
    2f205c8f37ab 9 days ago 10.4 GB
    vsnarayanan19/windows-test-image 10ae366718f8 10 days ago 10.1 GB
    microsoft/dotnet sdk-nanoserver 92c1b8f1151d 10 days ago 1.63 GB
    microsoft/dotnet-samples dotnetapp-nanoserver 57e39c23e9ff 10 days ago 1.11 GB
    microsoft/iis latest 9e66ceefdc5a 3 weeks ago 10.4 GB
    microsoft/windowsservercore latest 590c0c2590e4 3 weeks ago 10.1 GB

    Link-local IPv6 Address . . . . . : fe80::50a2:54ae:46d0:c483%36
    IPv4 Address. . . . . . . . . . . :
    Subnet Mask . . . . . . . . . . . :
    Default Gateway . . . . . . . . . :

    Thanks, Sankar

    • Sankar

      Hi Marcel, I have identified the issue, I was used wrong IP address…now I’m able to see IIS home page..

      docker inspect will show the IP address which is assigned to the container.

      Thanks, Sankar

  10. Bilal

    Hello Marcel,
    Thanks for the article.

    I am new to Docker.

    Would it be possible to run ASP.NET 4.5 or 5 on a Windows Container where the Docker Host is Mac?

    • Marcel

      nope, your docker container must match the operating system, since a container is operating system virtualization. that means the kernel is shared with the host and therefore you can not run windows containers on unix/Linux/mac systems. At the moment you also can’t run Linux based containers on windows, although Microsoft has announced to support Linux containers on their platform using hyper-v containers.
      Hope that helps

  11. Bhagirath

    somebody said here to use “Default Web Site” instead of webapplication because it fails with “SITE_DOES_NOT_EXIST” Error but with “Default Web Site” (with escapte sequence), it still fails with InventoryService.deploy.cmd is not regonized as an internal or external command, operatble program or batch file. I followed exact steps in your post. Again “Default Web Site” does not work as somebody mentioned without doing following
    FROM windowsserveriisaspnetwebdeploy
    RUN mkdir c:\webapplication
    WORKDIR /webapplication
    ADD /Default\Web\Site/
    ADD InventoryService.deploy.cmd /Default\Web\Site/InventoryService.deploy.cmd
    ADD InventoryService.SetParameters.xml /Default\Web\Site/InventoryService.SetParameters.xml
    RUN InventoryService.deploy.cmd, /Y

    but again it failed with unrecognized command. Can you please or anybody here help? Thank you guys. By the way really awesome that you took time writing something for Docker and .Net 4.5. So thank you.

  12. Ken Han

    Hi Marcel,
    I am using Windows 10, with Docker version 17.09.0-ce-win33 (13620).

    I couldn’t get the fix for ACL working. After the first ACL error, the build exited with return code equals 1. So, the fix ACL.ps1 couldn’t be executed.

    I have modified the DockerFile to create the folder and apply the fixacl.ps1 first as follow:

    FROM microsoft/windowsservercore
    RUN dism /online /enable-feature /all /featurename:iis-webserver /NoRestart
    RUN mkdir c:\install
    ADD WebDeploy_amd64_en-US.msi /install/WebDeploy_amd64_en-US.msi
    WORKDIR /install
    RUN powershell start-Process msiexec.exe -ArgumentList ‘/i c:\install\WebDeploy_amd64_en-US.msi /qn’ -Wait
    RUN mkdir c:\webapplication
    WORKDIR /webapplication
    ADD fixAcls.ps1 ./fixAcls.ps1
    ADD /webapplication/
    ADD dockerdeploydemo.deploy.cmd /webapplication/dockerdeploydemo.deploy.cmd
    ADD dockerdeploydemo.SetParameters.xml /webapplication/dockerdeploydemo.SetParameters.xml
    RUN mkdir C:\inetpub\wwwroot\dockerdeploydemo
    RUN powershell.exe -executionpolicy bypass .\fixAcls.ps1
    RUN dockerdeploydemo.deploy.cmd, /Y

    $path = “C:\inetpub\wwwroot\dockerdeploydemo”
    $acl = Get-Acl $path
    Set-Acl $path $acl

    The docker file was able to build successfully. Then I start the container as docker run -p 80:80 test01 ping localhost -t

    docker inspect the instance return:
    “Networks”: {
    “nat”: {
    “IPAMConfig”: null,
    “Links”: null,
    “Aliases”: null,
    “NetworkID”: “6a21d55c5065bc00ec62e639d833c2d55e7a28d15ce02fdddec99338849ca072”,
    “EndpointID”: “cdc7ed514d9d4c87114c6258dacd71920917d9c92192c3bcfba97d4fc04642ee”,
    “Gateway”: “”,
    “IPAddress”: “”,
    “IPPrefixLen”: 24,
    “IPv6Gateway”: “”,
    “GlobalIPv6Address”: “”,
    “GlobalIPv6PrefixLen”: 0,
    “MacAddress”: “00:15:5d:05:6d:71”,
    “DriverOpts”: null

    So far so good. But when I browse to from the local machine, the chrome browser returned “This site can’t be reached”.

    Do you know if I have missed any step?



  13. Alex Martinez

    I am new to Docker. Where should I store the Dockerfile? Do I run the Dockerfile in PowerShell?

  14. PP

    Based on this article I was trying to deploy ASP.NET 4.5 application using Docker for Windows.

    I have done everthing and I have checked container IP using docker inspect Container_ID. I’ve put this IP to my browser and it opens only default IIS page.

    So it seems that IIS server works, but how am I suppouse to open my application? and – both of them displaying default IIS site.

    • Marcel

      Perhaps you deploy to a sub folder and you need to add that to the url?

Leave a Reply

Your email address will not be published. Required fields are marked *

© 2024 Fluentbytes

Theme by Anders NorenUp ↑