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.

docker run hello-world

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.

dotnet new razor --no-https
dotnet new sln
dotnet sln add CloudSample.csproj

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.

docker-compose.dcproj
docker-compose.override.yml
docker-compose.yml
Dockerfile

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.

Before:
RUN dotnet restore /CloudSample.csproj

After:
RUN dotnet restore -nowarn:msb3202,nu1503 -p:RestoreUseSkipNonexistentTargets=false

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.

docker login

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.

docker tag f83e5adab340 elanderson/testrepository

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.

docker push elanderson/testrepository

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.


Also published on Medium.

6 Replies to “Adding Docker to an ASP.NET Core Application”

  1. Funny you decide to post about deploying to DigitalOcean with Docker. I just bit the bullet and did that myself yesterday. I wanted to start moving towards a microservice architecture so I didn’t want to have to pay for additional Heroku repos. Once I finished, I found that my performance on DO was much better than ok Heroku dynos too. I found the official instructions on the Docker website about preparing an ASP.NET Core application were helpful. Looking forward to seeing the rest of this tutorial to see if there’s anything I missed.

    1. Good to know that the performance on DO is better. I haven’t tried on Heroku. I’m looking forward to any feedback you have on the next post, hopefully, between the both of us we got it all covered.

      1. Absolutely! I’ll leave some feedback once the posts are finished.

        Heroku is okay. The reason I started with it is because I love the simple deployment model. Git push and you’re done. They have a community-created build pack for ASP.NET Core so you just add that when you create your project and you’re good to go.

        I find that if you spend the time to get familiar with Docker and docker-compose, and manually dealing with SSHing into your VPS etc, it approaches that Heroku level of simplicity.

        I plan to keep learning about continuous deployment techniques (GitLab CI looks promising) and my goal is to end up in a situation where I push to my main Git repo, kicking off an automated process where my tests run, and if they pass, the Docker image is rebuilt, tagged, and my DigitalOcean VPS is refreshed with the latest version of the Docker image.

        1. Continous deployment is something I have been thinking about playing around with as well. We use VSTS at work so I might start there.

          I haven’t tried GitLab at all yet I guess that is something else I should check out. Always new stuff to check out. Part of the reason I love this industry!

  2. Bit of an coincidence! I have spent the better part of my weekend trying to get a grip on Docker with the goal to deploy a sample-ish ASP.NET Core app to a DigitalOcean Ubuntu droplet and having Nginx reverse-proxy that app, also using Docker containers. Very content with finally having scratched the surface of the Docker CLI’s and setup.

    Looking forward to your coming posts!

    1. Seems to be the weekend for DigitalOcean and Docker! From the little I have played with Docker, it has been awesome. I really need to take the time to dig in more, so far it has mostly just been using the built-in Visual Studio support. Thank you for the comment!

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.