Fluent Bytes

"The only source of knowledge is experience" - Albert Einstein-

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:

image

 

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

image

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:

image

After selecting publish you will see the following dialog:

image

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

image

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

image

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

image

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

image

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

image

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 127.0.0.0 you will not see any results. You need to address your machine on its actual hostname or outside IP address.

Summary

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.

CTO at Xpirit, Microsoft Regional Director, Visual studio ALM MVP, Speaker, Pluralsight Author and IT Architect Consultant

19 Comments

  1. 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. https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/quick_start_windows_10

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

  3. 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. 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 ?

    Thanks

    • 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. 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?

    Regards,
    Shyam

  6. Kasper Joergensen

    December 20, 2016 at 2:04 pm

    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?

  7. was this Error Code: ERROR_SITE_DOES_NOT_EXIST resolved?
    Thank you.

  8. 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.

  9. 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
    REPOSITORY TAG IMAGE ID CREATED SIZE
    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. . . . . . . . . . . : 10.37.44.229
    Subnet Mask . . . . . . . . . . . : 255.255.254.0
    Default Gateway . . . . . . . . . : 10.37.44.1

    Thanks, 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. 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?

    • 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

Leave a Reply

Your email address will not be published.

*

© 2017 Fluent Bytes

Theme by Anders NorenUp ↑