Deploying ASP.NET Core And EF Core To Docker On Azure Using Visual Studio 2017

Deploying ASP.NET Core And EF Core To Docker On Azure Using Visual Studio 2017

In a previous blog post I showed you how you can setup unit tests to run in memory when testing ASP.NET Core & EF Core applications. But what about when you want to deploy a new application built on .NET Core. In this post I outline the steps that are needed in order to build and deploy an ASP.NET Web API application to a Docker container hosted in Azure. I will walk through the steps needed to do a deployment into a new Docker Container, using Visual Studio 2017, along with a new set of Azure SQL databases. Note, the process outline here is very simple and will not scale beyond an individual developer's prototype environment, so consider this a simple introduction rather than a full solution for a team project.

Installation requirements

In order to build and deploy the project you will need to download and install the following pre-requisites:

** Docker requires Hyper-V enabled on the host machine in order to run, thus, make sure that you enable this setting for your Windows 10 OS:

Docker Hyper-V Enabled

Docker Configuration

Install Docker for Windows by running the installation file downloaded from the stable channel and following all the default prompts as indicated in the Docker installation wizard.
Once Docker for Windows is installed and started, you will have to enable the Shared Drives functionality by right clicking on the Docker Whale and choosing Settings... In order to bring up the main setup screen. On the Settings window, locate the Shared Drives tab and make sure the checkmark under the Shared column is selected and then press Apply to commit the changes:

Docker Drive Settings

Visual Studio 2017 Installation Configuration

Once Docker is installed and configured you should install Visual Studio 2017 with the following Workloads:

Azure Settings

Select the Azure development option from the installation menu and make sure you match the Summary configuration checklist with the following:
Azure Installation Checklist

ASP.NET Settings

Select the ASP.NET and web development checkbox under Web & Cloud and make sure to match the following settings:
ASP.NET Installation Checklist

.NET Core Cross-Platform Development

This is an important step in configuring the Visual Studio 2017 installation, because it essentially enables support for Docker Containers. Therefore, make sure that you select the .NET Core cross-platform development checkbox under the Other Toolsets section of the Workloads installation menu. Your settings should look like this under the Summary:

Cross Platform Development Tools Checklist

Once the settings are done, continue with the next steps on the installation wizard and finish the install.

The Sample Project Structure

Before diving into how to deploy the application, it would be good to know just a little bit on how things are setup in my test sample project. So in my previous post, I had separated the different layers (Data, API) into separate projects, however, when deploying through VS2017 I encountered some limitations in the Visual Studio tooling for Entity Framework Core (1.0) migrations. Essentially doing data migrations for projects outside of the current deployed project do not play well. I am sure this is because these are still relatively early days for EF Core and the tooling will eventually catch up, but for now everything in the sample is pretty much in one project and organized in data folders.
Here is a quick logical overview of the API project itself:

  • Docker Compose project, this is the project that configures the container
  • Web API, which holds the RESTful API endpoints
  • Data access, maintains data access components
  • Tests, contains unit test for the ASP.NET Core Controllers that expose the REST API

Project Structure

However, I will not dive into the inner workings of the actual sample project in this document since it is not as relevant to the deployment piece.

Setting up The Deployment Configuration

Once you have all the tools installed and the source code for your project, open up the solution for your API Project and conduct a Build in order to make sure everything is working as expected.

Creating a publish profile

Visual Studio makes it straight forward to deploy a prototype project to the cloud by leveraging publishing profiles. In order to create one, just navigate to the API Project using the Solution Explorer window and select the project file. Right click on the project file to access a new menu, within that menu select and click on the Publish… option in order to bring up the deployment configuration wizard. Then from the Publish menu window select the Azure App Service Linux (Preview) and click Publish:

Azure App Service Linux (Preview)

The next screen will be the Create App Service window of the Publish wizard, and it will fill out default values for the Publish Profile that it will be creating. However, those default values can be overridden to denote more meaningful deployment settings. Note that, in this window, you can customize the various settings for Web App Name, Resource Group, App Service Plan and Container Registry, but you should be aware that ideally you should set the Location for all of your resources to the same region. For instance, configuring the App Service Plan in this walkthrough would look something like this:

App Service Plan

In the section above the App Service Plan is configured on the 'West US', thus ideally every other item in the deployment configuration should also be configured in that same location. This may not be always what you want to do, but in this specific instance, this is the desired configuration output.
Once the Hosting section is configured you can go ahead and configure the rest of the Azure resources such as the database server. You can do so by simply clicking on the Explore additional Azure services from within the Hosting window of the Create App Service wizard:

Creating Additional Hosting Services

The last action should bring up the Services tab in the Create App Service window of the wizard, and from there you should be able to add a new SQL Database by selecting on the plus sign under the top Resource Type section and creating a new SQL Database first:

Configure SQL Database

But before that, you will need to create a new SQL Server from within the Configure SQL Database window. Under the SQL Server input section click on the New button to configure the new server:

New SQL Server Creation Window

Choose a Server Name and fill out the rest of the inputs, make sure you use strong credentials for your server configuration. Press OK to return to the previous configuration window. Your configuration for SQL Server and the databases should now be ready to be created.
Now, return to the main Create App Service configuration window and click Create to launch the new Publish Profile. You should now have all of the settings ready to deploy the application to a container in Azure. Your settings will now look similar to this:

Settings Before Publishing to Azure
Noticed that the project has two databases that will be deployed along with their respective Entity Framework Migrations. This is a nice feature because you can deploy multiple databases at the same time, such as an identity database and a product database.

Hence, the next step is to simply click on Publish and wait for the deployment to finish. You will see a command window prompt pop up, that is normal, as Visual Studio 2017 is getting ready to deploy the Docker image to the Azure Container service:

INSERT IMAGE OF COMMAND LINE POP UP WINDOW

So at this point everything went according to plan, your deployment may succeed. However, I did experience some failure at first, and there are some reasons for that, but essentially the bottom line is that deploying to the Azure container service is still a work in progress. If you notice earlier, the Azure App Service deployment had the ‘Preview’ label printed on it, so we should expect that a few kinks are still being worked on. Nevertheless, let’s see how we can fix some of the possible deployment issues.

Troubleshooting Deployment Issues

Deploying to SQL Azure

The first thing that we need to address is the Firewall settings for the newly created SQL Server in Azure. From the main azure portal, locate the newly created SQL Server and under the Firewall section, click on the Show firewall settings and make sure to select Add client IP, with your current IP address, and save those settings:

SQL Azure IP Address Firewall Setting

Due to the fact that the firewall rules were not in place, the database deployment would have failed. If that is the case, then you will have to conduct a work around to get the database updated.
During the Publish step for the Web API, you will noticed that the EF Migrations actually generate the SQL script to be run in the target database. Therefore, depending on where your local project might be placed, this is approximately where you can expect the generated SQL Scripts to exist:
C:\File_Path_To_Your_Source_Code_Files\WebApi==obj\Release\netcoreapp1.1\PubTmp\EFSQLScripts==\Data.IdentityContext.sql
You can then connect to the SQL Server that you setup and configured during the Publish step and run the migration script, just as if you were zipping up a SQL Deployment script and giving it to your DBA:

Idempotent EF SQL Migration Script

On that note, the SQL script is also idempotent, which makes it nicer to run it again, if you need to, without a problem.

So as you can see, getting an ASP.NET Core & EF Core application deployed to a Docker container in Azure via Visual Studio 2017 is simple enough using the built-in tooling. However, the SQL Server firewall settings and the creation of a new SQL server from the wizard could use a bit more work. In any case, the tooling is pretty nice and it allows a developer to get up and running with the latest and greatest tools without much friction. So give the VS2017 deployment tools a try today, I think you will be pleasantly surprised by them. :)

Until next time, happy coding.