Modernization Hub

Modernization and Improvement
Modernizing .NET Apps for IT Pros Part 2

Modernizing .NET Apps for IT Pros Part 2

Hey, how you doing? I’m Elton and this is
the second part of the Docker MTA series: Modernizing .NET Apps for IT pros. In part
one I covered what MTA looks like for .NET applications. You’ve seen the
benefits in portability, security and efficiency you get when you move your
apps to Docker, and in this video I’m going to show you how to do it. I’m going
to take a .NET 3.5 application, currently running on Windows Server 2003, move it to docker using a PowerShell tool, and then run it in a container. Here’s the app I want to modernize. It’s
called SignUp.Web and it’s a simple ASP.NET WebForms site which uses a
SQL Server database. It’s a newsletter sign-up application which stores users’
contact details, and these drop-down values come from reference data in the
database. Right now the app runs on Windows Server
2003. My test environment uses a single VM for the website and the database. The
easiest way to move a .NET application into Docker is with Image2Docker – a
free open-source tool. It’s a PowerShell module hosted on the gallery, so back on
my Windows 10 client machine I’ll install the module and then import it so
it’s ready to use. The ConvertTo-Dockerfile file cmdlet extracts applications
into Dockerfiles. It can Dockerize apps on the local machine, or on a remote
machine, or from a virtual machine disk. I’ll use the VHD for my test server and
we’ll write the output to my C drive. Image2Docker can work with different
application types, which it calls artifacts. This is a web application so I
want to look at IIS on the VM. If I run the command now, Image2Docker will pull
all of the web apps out of the VM into one Docker image. But it’s better to run
a single application in each Docker container, so I’ll pass a parameter to
extract just one website – SignUp.Web Now Image2Docker mounts to VHD and
extracts the ASP.NET application. The output from Image2Docker is a Dockerfile which is how you package applications in Docker, and all the
content for the app copied out from the VHD. The Dockerfile is straightforward –
less than a dozen instructions – and this is all you need
to move a traditional app into Docker. It starts from Microsoft’s ASP.NET 3.5
image that image uses Windows Server Core and it comes with IIS, .NET 3.5
and ASP.NET already configured. Image2Docker found that the source website on
VM used ASP.NET 3.5 and it’s chosen this as the most appropriate Docker image as
the base. The SHELL instruction switches to PowerShell for running commands in
the rest of the Dockerfile. Even if the Dockerfile syntax is new to you, the
majority of the work is done in PowerShell and it’s pretty clear what’s
happening. This line sets a Registry entry to turn off the DNS cache in
Windows. You need to do that to make sure the container always checks the DNS
server in Docker when it’s looking for services. That way it always gets the
current address for other containers. Next, remove the default website from is
and create a new directory and website for the application. The website name, the
path for the content, and the port are all brought across from the original VM.
Docker containers are locked down unless you explicitly allow network traffic
into them and that’s what the EXPOSE instruction does. It’s like a firewall
opening traffic to the website port. Now copy the website content from the local
machine where Image2Docker extracted it from the VM. The last section sets the
ownership of the web directory to the IIS user group, so that the app can write
files to that directory. I don’t need to change anything in the Dockerfile that
the tool generated, this is all ready to package in Docker. Packaging the app in
Docker means building a Docker image. I’ll change to the directory where my
Dockerfile and the website content are, and run `docker image build`. The tag is
the identifier for the image which I’m calling `newsletter/signup-app:v1`. Docker
executes each of the commands in the Dockerfile and the final output is an
image. The image is actually built up of many layers which Docker will cache to
speed up the build and distribution. Each instruction in the Dockerfile creates
an image layer, and these are the layer IDs. And if the instructions don’t change
between builds, Docker reuses cached layers. The image is the
portable unit so I can share this on a public or private registry, and anyone
with access can download the image and run the application. To run the app in a
container, I use `docker container run`. `-detach` means the container will run in
the background and `-publish` publishes the port, so Docker routes traffic into the
container. The output is the container ID and I can check the container is running
with `docker container ls` to list all running containers. Each container has a
virtual IP address which I can use to access it from the host. `docker
container inspect` gives me all the information about a container including
that IP address. I’ll browse the port 8090 on the container and I’ll see my
application. So this is my .NET 3.5 app, extracted from a Windows Server 2003
machine now running in Docker. I’ve actually got an error screen so
something isn’t working right, but Docker isn’t a black box. I can
connect to the container and see what’s happening. In the website content there’s
a config file which has a logging section. Any errors should get logged to
the signup.log file in AppData so that’s where I can look in the container.
`docker container exec` runs a command inside a container and with the
interactive and terminal flags I can connect to a PowerShell session. This is
PowerShell running inside the container now, and I can read the log file with `Get-Content`. The error is that the app has failed to connect to SQL Server. Back
in the web config file, here’s the connection string for the database and
it’s expecting to find SQL Server on the local machine. The container doesn’t
have SQL Server so that’s why the app is failing. I’m going to run the database
in another Docker container, so I’ll change the connection string. The data
source will just be the container name. At the moment the config file is baked
into the docker image, so I need to rebuild the image to package the new
configuration. There are better ways of configuring
apps in Docker but this is an easy approach when you’re getting started.
I’ll make a change to the Dockerfile too, so that I can read the logs without
having to connect to the container. These instructions change how Docker starts a
container from the image. The entry point command is going to run PowerShell, start
the IIS Windows Service, browse to the local site – which starts the worker
process running – and then watch the application log file. That means log
entries get relayed back to Docker and they can be read from the docker command
line, and from any of the plugins for logging that the Docker platform
supports. I’ll build a new version of the image, tagged v2, and you’ll see a lot of
the image layers come from the cache, because the Dockerfile instructions
haven’t changed since the last build. Only the last few instructions are
executed and the output is a new image with my new database configuration and
logging set up. Running SQL Server in a container is perfect for test
environments. I already have an image with my database schema deployed which
runs on top of the SQL Server Express image from Microsoft. I’ll run
a detached container from that database image, and make sure the container name
matches the server name from the application’s connection string. Now I’ll
run the web application in another container and grab the container IP
address. When I browse to the new container,
I see the home page as expected and I can go on to enter some details here.
When I submit the form the data gets saved to the database in my SQL
Server container. That log relay that I put into the Dockerfile means I can run
`docker container logs` and see the output from the application log without having
to connect to the container. Here there are log entries showing the data I’ve
just saved in the app. My application is working just fine in Docker now, with no
code changes, and just one config change to update the database connection string. My Windows 10 machine doesn’t have IIS or .NET 3.5 or SQL Server
installed. All you need to run this application is Docker, everything else is
packaged in the Docker images. I started this video with an old .NET
3.5 app running in Windows Server 2003. 10 minutes later I have the same
application running in a Docker container based on Windows Server 2016.
Docker is a modern application platform that makes it easy to move your app to a
different host, or a different data center, or even to the cloud. It also
makes it easy to manage your app and deploy application updates and Windows
updates, which is what I’ll be showing you next. That’s coming up in part 3 of
Modernizing .NETApps for IT pros.

5 comments on “Modernizing .NET Apps for IT Pros Part 2

  1. Can I change IIS setting through GUI in the docker? I think one of reasons why users stay with Windows is GUI oriented. If you can't do less app will run on the docker

  2. sorry if I missed something, but the dulcet tones of Elton have me in thrall… so where can I see part 3, oh please tell me

  3. this is good video don't get me wrong and thanks for doing it…. But you really did not get this up and running in 10 minutes… You jumped the step on how to do sql server and already used a previously done image of it. Hoping the other series covers how to do this and OS in general…but looking at the titles doesn't look like it…

Leave a Reply

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