Habitat ASP.NET Full Framework sample application

This is a sample ASP.NET MVC Full Framework IIS based application with accompanying Habitat plan, hooks, and configuration (see the habitat directory). The application itself is the exact same application generated by File/New/Project and choosing the C# ASP.NET MVC application inside of Visual Studio 2015 Community Edition.

Our run hook will sleep

Typically having a Hook sleep is an anti-pattern but in the case of an IIS app it makes sense. Our run hooks will simply make sure that our IIS application pool and web sites are present and running. Then it will sleep until the application becomes unresponsive or the service is stopped.

Building the plan

The Habitat plan includes build time dependencies on core/nuget and core/visual-build-tools-2019 which puts Nuget.exe and MSBuild.exe on the path and allows the build to find dependencies and compile the application binaries.

Running the web site

Loading the built service into the Habitat Supervisor will configure IIS to run the application on the configured port. Note that this applicationi includes runtime dependencies on several plans that include install hooks which will ensure that the .Net runtime is installed, and the IIS and ASP.NET Windows features are enabled.

The application's run hook will use DSC to configure the IIS application pool, site and app.

Load balancing multiple application instances

This repository includes an nginx-proxy plan that can be built and used to load balance several application instances running on separate Supervisors. One way to do this is to export both the hab-sln web application and the nginx-proxy plans to a Docker image and run miltiple hab-sln containers and then bind a nginx-proxy container to those web app containers. There is a docker-compose.yml file in the root of the repo that can launch such a container environment. You will need to replace its mwrock origin reference to the origin you used to build the plans. Assuming you want to run two web application nodes, run the following docker-compose command:

docker-compose up --scale dotnet=2

After you see the web application has come up on both web containers (you will know when you see the output http://<IP_ADDRESS>:8099/hab_app is running), run Invoke-Webrequest http://localhost/hab_app. This should return output beginning with the following text:

StatusCode        : 200
StatusDescription : OK
Content           : <!DOCTYPE html>
                    <html>
                    <head>
                        <meta charset="utf-8" />
                        <meta name="viewport" content="width=device-width, initial-scale=1.0">
                        <title>Home Page - My ASP.NET Application</title>
                        <l...
RawContent        : HTTP/1.1 200 OK
                    Connection: keep-alive
                    X-AspNetMvc-Version: 5.2
                    X-Upstream: 172.24.34.97:8099
                    Content-Length: 3191
                    Cache-Control: private
                    Content-Type: text/html; charset=utf-8
                    Date: Wed, 13 No...

Note that the X-Upstream header will have the origin IP of the hab-sln container that served the request. If you rerun the Invoke-WebRequest command, it should round robin through all containers in the hab-sln service group.

Also note that the above localhost URL only works on Windows Server 2019 and newer builds of Windows 10. If you are on server 2016 or an older Windows 10 build, you must use the IP of the nginx container.