Page 33 - MSDN Magazine, April 2017
P. 33
MSIs, too, but the packaging process is all automated, so you can’t run an install process that has a Windows UI and needs user input. When you’re looking at a solution architecture to figure out which parts can run in Docker containers, keep in mind any component that can be installed and run without the Windows UI is a good candidate. This article focuses on .NET Framework apps, but you can run anything in a Windows container that runs on Windows
Server, including .NET Core, Java, Node.js and Go apps.
Migrating .NET Apps to Containers
How you migrate to Docker depends on how you’re currently running your app. If you have a fully configured app running in a Hyper-V VM, the open source Image2Docker tool can automati- cally generate a Dockerfile from the VM’s disk. If you have a build process that publishes an MSI or a WebDeploy package, it’s easy to write your own Dockerfile by using one of Microsoft’s base images on Docker Hub.
The Dockerfile is like a deployment guide for the Web application, but instead of being a vague human document, it’s a precise and actionable script.
Here’s a complete Dockerfile that scripts the packaging of an ASP.NET WebForms app into a Docker image:
FROM microsoft/aspnet:windowsservercore-10.0.14393.693 SHELL ["powershell"]
RUN Remove-Website -Name 'Default Web Site'; \\\\\\\\
New-Item -Path 'C:\\\\\\\\web-app' -Type Directory; \\\\\\\\
New-Website -Name 'web-app' -PhysicalPath 'C:\\\\\\\\web-app' -Port 80 -Force
EXPOSE 80
RUN Set-ItemProperty -Path 'HKLM:\\\\\\\\SYSTEM\\\\\\\\CurrentControlSet\\\\\\\\Services\\\\\\\\ Dnscache\\\\\\\\Parameters' \\\\\\\\
-Name ServerPriorityTimeLimit -Value 0 -Type DWord
COPY ProductLaunch.Web /web-app
Nine lines of script are all I need, and there are no application changes. This could be an ASP.NET 2.0 app, currently running on Windows Server 2003—with this Dockerfile I can build it into an image that immediately upgrades the app to Windows Server 2016 and the .NET Framework 4.5. I’ll walk through each of those instructions:
• FROM microsoft/aspnet tells Docker which image to use as the starting point. In this case, it’s a Microsoft image with IIS and ASP.NET installed on top of a specific version of Windows Server Core.
• SHELL ["powershell"] changes to a different shell for the rest of the Dockerfile, so I can run PowerShell cmdlets.
• RUN Remove-Website uses PowerShell to set up IIS, removing the default Web site and creating a new one with a known location for the application.
• EXPOSE 80 opens port 80 explicitly to allow network traffic into the container as Docker containers are locked down by default.
• RUN Set-ItemProperty turns off the Windows DNS cache inside the image, so any DNS requests get served by Docker. • COPY ProductLaunch.Web copies the published Web site project from the ProductLaunch.Web directory on the host
into the image.
The Dockerfile is like a deployment guide for the Web application,
but instead of being a vague human document, it’s a precise and actionable script. To produce the packaged app I run the docker build command from the directory that contains the Dockerfile and the published Web site:
docker build --tag sixeyed/msdn-web-app:v1 .
This command builds a Docker image with the name sixeyed/ msdn-web-app and the tag v1. The name contains my user account for the Hub (sixeyed), so I can share this image by signing in with my credentials and pushing it to the Hub. Tags are useful for ver- sioning images, so when I package a new version of the application, the image name will stay the same, but the tag will be v2.
Now I can run a container from the image and that will start the application, but the sample app has a dependency on SQL Server so I need SQL Server running before I can start the Web site.
Pulling Dependencies from Docker Hub
Docker has a networking stack that lets containers reach each other over a virtual network, and also lets containers reach external hosts running on the physical network. If I had a SQL Server instance running on a machine in the network, the ASP.NET app in the container could use it—I’d just need to specify the server name in the connection string. Or I can run SQL Server in a container, and the Web app will be able to reach it by using the container name in the connection string.
There are more than half a million images on Docker Hub, which have been downloaded more than 9 billion times.
SQL Server Express is available on Docker Hub in an image maintained by Microsoft. To start a database container from that image, I run:
docker run --detach `
--publish 1433:1433 `
--env sa_password=MSDNm4g4z!n3 ` --env ACCEPT_EULA=Y `
--name sql-server ` microsoft/mssql-server-windows-express
This starts a container in the background with the detach flag and publishes port 1433, so I can connect to the SQL instance in the container from outside, perhaps using SQL Server Management Studio on the host. The env options are key-value pairs, which Docker surfaces inside the container as system environment
msdnmagazine.com
April 2017 21