Adding Docker to an ASP.NET Core Application

I have a series of post about deploying an ASP.NET Core application to different cloud providers which centered around clouds that provided a service that supported ASP.NET Core. The following are all the post in that vein if you are interested.

Google Cloud Platform
Amazon Web Services
Microsoft Azure

I was asked if I was going to do a post on deployment to DigitalOcean. While not in my original plan it was a good idea. The thing is DigitalOcean doesn’t have a service to support ASP.NET Core, but they do support Docker so this post is going to cover adding Docker support to a sample ASP.NET Core application. Look for a future post on how to deploy to DigitalOcean.

Docker

What is Docker? To quote Wikipedia:

Docker is a computer program that performs operating-system-level virtualization also known as containerization. It was first released in 2013 and is developed by Docker, Inc.

Docker is used to run software packages called “containers”. In a typical example use case, one container runs a web server and web application, while a second container runs a database server that is used by the web application. Containers are isolated from each other and use their own set of tools and libraries; they can communicate through well-defined channels. All containers use the same kernel and are therefore more lightweight than virtual machines. Containers are created from “images” which specify their precise contents. Images are often created by combining and modifying standard images downloaded from repositories.

Installing Docker

Head to this link and click the Get Docker link to download the installer. After the install is complete you will have to log out and back in. When I logged back in I got a message about Hyper-V not being enabled.

After logging back in I then got the following message about hardware-assisted virtualization not being enabled.

After tweaking my BIOS settings and logging back in I was greeted by the Docker welcome screen.

Open a command prompt and run the following command.

You should output that starts with the following if your installation is working.

Hello from Docker!
This message shows that your installation appears to be working correctly.

Sample Application

This is the same as in the cloud series, but am including it in case you missed that post. The sample application that we will be deploying is the basic Razor Pages applications created using the .NET CLI. The following commands are what I used to create the application, create a solution, and add the project to the solution. I ran all these commands in a  CloudSample directory.

Add Docker Support

Open the solution created above in Visual Studio and right-click the project and select Add > Docker Support.

Next, you will have the select the OS you want to target.

This will add the following four files to your project.

The process will also change your project to start in Docker when you hit run from in Visual Studio.

Publishing

In order to publish we need an account with a registry that we want to publish to. There are multiple options, but I am going to be using Docker Hub. Go to Docker Hub and sign up for an account. After you get signed in on your Repositories tab click Create Repository.

On the next page enter a name for your repository, select if you want it to be private or public and click Create. I’m using the name TestRepository and making it private.

Now that we have a Docker Hub account hope back to Visual Studio and right-click on your project and select Publish.

On the next on the dialog select the Container Registry option and then Docker Hub. Then click the Publish button.

On the next dialog enter your username and password for Docker Hub and click Save.

After saving Visual Studio will build and publish the application to Docker Hub.

Issues

If you get luck the above will work for you. I hit a couple of issues that made the above fail for some reason. The following is the first error I got.

Error: Service ‘cloudsample’ failed to build: The command ‘/bin/sh -c dotnet restore /CloudSample.csproj’ returned a non-zero code: 1

After some digging, I found this GitHub issue. The gist of the fix is to change the following in the DockerFile.

The above fixed the build when in release mode, but publish still failed on me with the following error when the tools were attempting to tag the image.

System.Exception: Running the docker.exe tag command failed.
at Microsoft.VisualStudio.Web.Azure.Publish.ContainerRegistryProfileVisual.DockerTag(ProcessStartInfo startInfo, String serverUrlString)
at Microsoft.VisualStudio.Web.Azure.Publish.ContainerRegistryProfileVisual.<PostPublishAsync>d__24.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.ApplicationCapabilities.Publish.ViewModel.ProfileSelectorViewModel.<RunPublishTaskAsync>d__116.MoveNext()

I haven’t found a way to get around this issue. I ended up using the Docker CLI to push my image. This takes a few steps. First, use the following command to log in.

Next, use the  docker images command to find the image you are trying to push. In my case, it was the image with ID f83e5adab340. When the ID we can now use the following command to tag the image.

It is important that the image is tagged with the name of the repository it is going to be pushed to. Finally, run the following command to push the image with the specified tag into your repository.

Wrapping Up

The teams at Microsoft have made adding Docker support to an existing project super simple. Docker is something that I have had a surface level awareness of for a while, and I am looking forward to trying an actual deployment to see how that works with DigitalOcean.

Create a .NET Standard Library with Visual Studio 2017

It has been almost a year since I wrote this post on creating a .NET Standard Library which was before Visual Studio 2017 was released. This post is going to cover the same basic idea, but for the new tooling which has vastly simplified the process.

.NET Standard Library

The .NET Standard Library specifies what .NET APIs are available based on the version of the .NET Standard Library being implemented. The following is a comparison to portable class libraries that really helped me understand the difference. This was pulled from the .NET Standard Library link above.

.NET Standard Library can be thought of as the next generation of Portable Class Libraries (PCL). The .NET Standard Library improves on the experience of creating portable libraries by curating a standard BCL and establishing greater uniformity across .NET runtimes as a result. A library that targets the .NET Standard Library is a PCL or a “.NET Standard-based PCL”. Existing PCLs are “profile-based PCLs”.

The .NET Standard Library and PCL profiles were created for similar purposes but also differ in key ways.

Similarities:

  • Defines APIs that can be used for binary code sharing.

Differences:

  • The .NET Standard Library is a curated set of APIs, while PCL profiles are defined by intersections of existing platforms.
  • The .NET Standard Library linearly versions, while PCL profiles do not.
  • PCL profiles represents Microsoft platforms while the .NET Standard Library is agnostic to platform.

Create a .NET Standard Library

In Visual Studio click File > New > Project.

This will launch the New Project dialog. Find the .NET Standard templates and select Class Library.

Now that the library has been created right click on the project and go to properties. On the Application tab, there is an option to for Target framework which currently defaults to .NETStandard 1.4. Depending on your platform your library needs to support will decide which version of the .NET Standard you need to use.

See the chart on this page for help with picking a version of the standard. The lower the version of the standard you target the more platforms your library will run on, but keep in mind the lower the version the smaller the API surface that is available.

Wrapping up

This process is so much easier than it was in Visual Studio 2015. The tooling around .NET Core and .NET Standard has gotten so much better. This type of library is the future and I highly recommend using .NET Standard when you have the option over portable class libraries.

Visual Studio 2017 Error: The project doesn’t know how to run the profile IIS Express

I have a couple of computers I work between for the samples I use on this blog and when switching to between of them I got the following error last week.

The project doesn’t know how to run the profile IIS Express.

I verified the project would still run on the other computer with no issues. I also verified that on the computer with the issues the project would still work using  dotnet run from the command line still worked.

Next, I went to verify the project properties. Here I noticed a strange thing on the computer with the error the Debug tab of the project properties was missing a lot of setting. The following is a screen shot of the computer with the issues.

And here is the same tab on the same project, but from a different computer.

The cause

After more time that I would like to admit I was able to track down the issue. On the computer with the issue, I often work on projects that are very large which tend to slow down Visual Studio pretty bad. In an effort to speed things up a bit I when through and disabled all the extensions that I could including the Microsoft Azure App Service Tools. Turns out that disabling the previous extension caused the Microsft ASP.NET and Web Tools extension to be disabled as well (with no warning).

The solution

The only way I was able to get the project to work properly was to enable both the Microsft ASP.NET and Web Tools extension AND the Microsoft Azure App Service Tools extension. I am not sure why the Microsft ASP.NET and Web Tools extension need the Microsoft Azure App Service Tools extension but based on my experience they are related in some way.

Visual Studio 2017 error encountered while cloning the remote Git repository

Going through the process of getting Visual Studio 2017 installed on all my machines has been pretty smooth. The new installer works great and makes it much clearer what needs to be installed.

The issue

The one issue I have had, which was only an issue on one install, is an error when trying to clone a repo from GitHub. I say GitHub but really it would be a problem with any Git repo. The following is the error I was getting.

Error encountered while cloning the remote repository: Git failed with a fatal error.
CloneCommand.ExecuteClone

The solution

After searching I found a lot of things to try. I uninstalled and reinstalled Git for Windows multiple times using both the Visual Studio Installer and the stand alone installer. I finally stumbled onto this forum thread which had a solution that worked for me. The following is a quote of the reason for the issue and a fix posted by J Wyman who is a software engineer for Microsoft’s Developer Division.

After intensive investigation we were able to determine that Git was accidentally loading an incorrect version of libeay32.dll and ssleay32.dll due to library loading search order and precedence rules. Multiple users have confirmed that copying the binaries from the “<VS_INSTALL>\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Git\mingw32\bin\” folder to the “<VS_INSTALL>\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Git\mingw32\libexec\git-core\” folder completely resolved the issue for him.

Any other users seeing similar problem should attempt the same solution.

I hope this gets other people up and running as it did me. My only worry about this fix is what happens with Git gets updated.