Modernizing .NET Framework Apps with Docker - p-patel/software-engineer-knowledge-base GitHub Wiki

See other Elton Stoneman courses!

Packaging ASP.NET Apps for Docker

Introducing App Modernization with Docker on Windows

  • Containerise ASP.NET apps using Docker (Windows containers)
  • Modernise .NET Framework monolith in stages: .NET Framework app in Docker unchanged, then break app into parts which are containerised separately and using Docker to plumb them together, end up with a distributed application with a single way to build, distribute, deploy, manage and monitoring every part of the app
  • Will use every part of Docker: Dockerfiles, images, containers, registries, swarms

Principles of Modernizing .NET Framework Apps

  • Modernisation is a spectrum: from run legacy apps as-is in Docker to re-architecture as event-driven micro services
  • Mix containers with existing services: (run some parts in Docker connecting to other components outside of Docker as external services)
  • Container-first design: add features by using registries of packaged apps (minimise writing custom code) e.g. async messaging, self-service reporting and self-service content management and only write business-domain specific code.
  • Environmental consistency: processes and tools to deploy, manage and monitor app are the same across dev, test and prod environments

How the Demo WebForms App Will Evolve in the Course

  • A web app to register for a webinar
  • Options to run the web app in a container
  • Run the SQL Server db in a container
  • Breaking out features from monolith into separate containers: a message queue, document db, cms, moinitoring, then structure the app using Docker Compose (defines a distributed system) which can be used from local laptop to multi-node clusters and finally deploy app to cloud using the same artifacts used during dev using Docker Swarm
  • Starting point: ASP.NET Web app and Setup project that produces an MSI installer
  • Define all deployment steps by creating a Dockerfile
  • Initially using existing MSI

Packaging .NET Apps in Docker Using MSIs

  • Core project: logging
  • Model project: entity models
  • Web project: MVC web app
  • Setup project: Uses WXS to generate the MSI
  • Build uses WXS to produce MSI which deploys all directories, files and IIS website for the app. MSI will be used in Docker file
  • Docker is a text file that specifies steps to package an app
  • FROM microsoft/aspnet:windowservercore - specifies a Docker image with Windows Server Core, IIS and ASP.NET already configured
  • COPY output/SignUp.msi . - copies local file to Docker instance
  • RUN powershell Start-Process .\Signup.msi - Wait - runs MSI installer and waits for completion before Docker moves on
  • Docker will package the app from this file, packaging it called 'building an image'

Running ASP.NET Web Apps in Windows Containers

  • docker image build --tag webinar-app:v1 . - generates an image with a tag and using the input files in the current dir
  • a Docker image is a portable unit that is sharable (need Windows Server or Windows 10 with Docker to run Windows containers)
  • docker container run --detach --publish 80 webinar-app:v1 runs a container in the background as a service routing traffic from the host's specified port to the container using the specified docker image
  • docker container ls lists all running containers
  • docker container inspect 415 displays information about the specified container with id beginning '415'
  • browse to container's ip address to view the web app

Limitations Using MSIs to Build Docker Images

  • Installation and configuration is opaque, hidden within the MSI file (e.g. port the app listens on, the path it is installed to etc.)
  • Alternative is to use a container to build and package the app from source using XCOPY:
  1. Use a container to compile & publish the app from source
  2. Deploy the published app to create a docker image
  • Produces a more comprehensive Docker file that describes how to build and package the app

Compiling .NET Apps from Source in Docker Containers

Module Summary

  • Image2Docker for apps in 'maintenance mode', an open-source Powershell module (requires no app source code!)

Running SQL Server Databases in Containers

Introducing SQL Server Containers on Windows

  • Database is often a bottleneck in app development - updates and deployments are often handled outside of the usual app build and deployment processes
  • SQL Server can be containerised to spin up dev dbs and to deploy production dbs
  • To persist data, Docker is configured with volumes for persistance so that short-lived SQL containers still persist db data
  • A SQL Server dockerfile can be used to produce an image to deploy a consistent, reproducible db using a consistent process

Packaging Database Schemas into Docker Images

  • Using mssql-server-windows-express image which comes with a production licence

Building SQL Server Data Tools Projects in Containers

  • Db project contains schema objects and post-deployment scripts
  • Project is configured to build a DACPAC with version 1.0.0.0
  • Create a db folder in the src code's docker folder db containing a Dockerfile
# escape=`
FROM sixeyed/msbuild:netfx-4.5.2-ssdt AS builder

WORKDIR C:\src\Signup.Database
COPY src\SignUp.Database .
RUN msbuild SignUp.Database.sqlproj `
    /p:SQLDBExtensionsRefPath="C:\Microsoft.Data.Tools.Msbuild.10.0.61025\...
    /p:SqlServerRedistPath="C:\Microsoft.Data.Tools.Msbuild.10.0.61025\lib\...
  • docker image build -t webinar-db:v1 -f .\docker\db\Dockerfile . - builds Docker image, finishing with the generated DACPAC

Packaging SQL Server DACPACs with multi-stage Builds

  • Packaging the DACPAC in the Docker image enables both disposable dbs and persistent dbs with schema upgrades

TODO: ...

Adding Self-service Analytics with Elasticsearch and Kibana

TODO: ...

Building the Document Index Message Handler

  • Console app that will subscribe to existing customer signup event and add save data as documents in Elasticsearch
  • methods created to create the Elasticsearch index and to add documents to this index
  • view model created to define the 'Viewer' document object
  • queue group enables support for multiple Docker instances of the message handler

Packaging the Index Message Handler as a Docker Image

  • Dockerfile: Build Image:
  • nuget restore step
  • build console app project App Image:
  • create app image based on microsoft/windowsservercore image
  • configure NAT address and elasticsearch address as ENV variables
  • set CMD command to execute console app
  • copy the console app to the deployment folder
  • Build Docker image
  • PowerShell script created to run all required containers in the correct order to launch the system (better approaches will be covered later)
  • ports only published for containers that need to be accessed outside of Docker, all other containers can only be accessed from within the Docker environment as a Docker security feature
  • Configure the 'viewers' elasticsearch index in Kibana to query the Viewer documents
  • Creating a rich Kibana dashboard will be covered later

Running the Analytics Components in Containers

  • A container-based architecture means individual components can be scaled up/down as required in response to demand
  • Introducing an async, message based system allows the introduction a new feature such as the Index handler to publish documents to elasticsearch to be compoleted with zero-downtime of the existing system as it only requires the new containers that subscribe to the existing message to be spun up. It also requires no regression testing of the existing system as it remains unchanged, just test and deploy the new feature to production!
  • Docker can be used for fast, automated end-to-end testing of a system (to be covered next)

End-to-end Testing with SpecFlow in a Container

  • see PS course 'Executable Specifications: End-to-End Acceptance Testing with SpecFlow' by Elton Stoneman
  • Created a test project using SpecFlow that tests the behaviour of a customer completing the signup form
  • The Specflow tests run a headless browser in a console app to run the tests against the containerised system (using NUnit)
  • The E2E tests are built using the process established for other projects previously (build and output Docker images)
  • Kibana dashboards can be created and saved using visualisations that query documents in the elasticsearch index (this would be done against the prod elasticsearch instance!)

Module Summary

  • No official Docker images for Elasticsearch or Kibana that run on Windows, so Dockerfiles were created to build our own images, deploying from the public downloads of these apps (inc. verifying SHAs of downloads!)
  • Given the custom apps, offical Docker images for systems (e.g. NATs, SQL Server) and self-packaged app Docker images (e.g. elasticsearch, Kibana) we still have a consistent process for how all the apps are build and run!
  • Container also provides an easy way to run automated E2E testing of the system in isolation. E2E testing used to require effort to set up all the required components and ensure the required data was in the right initial state, but this is now all automated (run all the required containers and a new db container instance always starts up with the defined seed data
  • Previous modernisations covered two types of feature: performance and reporting. Next will cover third type: a UI features
  • UI feature allows PO's to quickly test changes to the UI without requiring development effort and a full release of the web app. This is expensive if the web app release requires manual testing.
  • Next module will extract the Home page UI from the system and replace with a containerised CMS system

Providing Self-service Content Management with Umbraco

TODO: ...