Saturday, January 28, 2017

Adding Swagger to an ASP.NET Web API 2 app that uses .NET Framework 4.5.2

Swagger is an API specification framework. It reminds me of WSDL in the SOAP days. In this article I will guide you in add Swagger documentation to an ASP.NET Core Web API app.

I will show you how to add Swagger documentation to an ASP.NET Web API 2 application that is running under .NET Framework 4.5.2.

Create a simple Web API application using Visual Studio 2015.

1. File >> New >> Project

2. Templates >> Visual C# >> Web

3. Choose “ASP.NET Web Application (.NET Framework) Visual C#”

4. Give your application a name like “WebApi2Swagger” then click on OK.


image

5. On the next dialog, choose Web API, uncheck “Host in the cloud”, then click OK.

image

6. Once the application template is created, open the Controllers/ValuesControllers.cs file and delete the [Authorize] annotation over the class declaration line.

7. Run the application by hitting CTRL + F5 on your keyboard. Add /api/values to the address line to see the sample API that is created by this template. It should look like this:

image

8. Run the following command in the “Package Manager Console” in Visual Studio:

Install-Package Swashbuckle

9. The next step is to enable XML documentation in your web application. Right-click on the web app project node in Solution Explorer and choose Properties.

image

10. In the Build tab, enable “XML documentation file” in the Output section.

image

Copy the XML filename and paste it in a text editor so that you can use it later. In the above case, the filename is bin\WebAPI2Swagger.XML.

11. Open App_Start/SwaggerConfig.cs. Make the following change:

Find “//c.IncludeXmlComments(GetXmlCommentsPath());” around line 100. Right after this line, add the following code:

c.IncludeXmlComments(string.Format(@"{0}\bin\WebAPI2Swagger.XML",
        System.AppDomain.CurrentDomain.BaseDirectory));

Note that the filename is what you had previously pasted in a text editor.

12. Build and run your application. Add /swagger to the URL address. You should see a page that looks like this:

image

Testing it out

Click on Values.

image

Click on the “GET” button.

Click on the “Try it out!” button. You should see the Curl command, Response Body, Response Code, and Response Headers.

 

Conclusion


Although this tutorial is very simplistic, the steps  we went through equally applies to more complicated API objects.

Saturday, January 21, 2017

Continuous deployment of ASP.NET MVC 5 app to Azure thru GitHub

In this post, I will show you how to deploy an ASP.NET MVC application on GitHub to Azure. The application will first be pushed to GitHub then we will configure Azure to automatically sync changes from GitHub.
The following are prerequisites:
  • git is installed on your computer
  • you have Visual Studio 2015 (or later)
  • you have a GitHub account
  • you have an Azure subscription

Creating a simple ASP.NET MVC 5 application

The first step is to create an application named Aspnet2Azure. In Visual Studio 2015:

File >> New >> Project

Templates >> Visual C# >> Web >> ASP.NET Web Application (.NET Framework)

Name the application Aspnet2Azure then click OK.

image

Select MVC, uncheck “Host in the cloud”, then click OK.

Hit CTRL + F5 to view the web app in a browser:

image

Adding GitHub source control to your application

Before we push our code to GitHub, here are some configuration changes that you  need to make to the ASP.NET web application:

1) Open the .csproj file in the solution folder and comment out this block of XML:

<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
  <PropertyGroup>
    <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see
http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
  </PropertyGroup>
  <Error Condition="!Exists('..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props'))" />
  <Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
</Target>


NOTE: This is a NuGet packages restore feature, which is ON by default. Simply put, if the packages are missing, NuGet will download them before the build starts. This feature is not needed in production and, therefore, should be disabled.

2) In the web.config file, comment out this block of XML:

<system.codedom>
  <compilers>
    <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
    <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
  </compilers>
</system.codedom>


NOTE: These settings are used for dynamic compilation. They can be safely removed from the web.config file if you do pre-compilation and only put the compiled assemblies on the web server.

3) This is optional. In order to see debug information in production, add this to your web.config in the <system.web> block:

<customErrors mode="Off"/>

Go to http://github.com and login into your account.

image

On the right-side, beside “Your repositories”, click on the green “New Repository” button.

image

Enter Aspnet2Azure for repository name, then click on the green “Create repository” button.

image

We will follow some of the instructions highlighted above. Go to a command-line in the web application Aspnet2Azure directory (not the solution) on your computer. and type in the following commands:

git init
git add .
git commit -m "first commit"
git remote add origin https://github.com/{github user}/Aspnet2Azure.git
git push -u origin master


NOTE: Make sure you enter your GitHub handle instead of {github user} in the URL above.
Once you have successfully completed the above, you can go back to GitHub in your browser and view all the files in your Aspnet2Azure repository:

image

Continuous deployment on azure

Go to http://portal.azure.com and login into you Azure account.

image

Click on the big + (New) on the top left-side.

image

Click “Web App” on the next blade.

image
  • Choose an “App name” that is sufficiently unique when combined with domain azurewebsites.net
  • Choose your subscription
  • For “Resource Group” either create a new or use an existing resource group
  • While configuring “App Service plan/Location”, you get to choose which data center you want.
Finally, click on the blue Create button at the bottom of the blade. Once your web app is created, it will appear in the list of your “App Services”.

image

Click on the web app you just created.

image

Enter “deploy” in the filter field at the top then select “Deployment Options”.

image

On the next blade, click on “Choose Source”.

image

Click on GitHub. If this is the first time you connect to GitHub from Azure, you will be asked for your credentials. Once your GitHub credentials are known to Azure then you will see a blade that looks like this:

image

Click on “Choose project” to select the appropriate GitHub repository that you wish to connect Azure with.

image

Click on the Aspnet2Azure repository you previously setup on GitHub.

Back in the “Deployment source” blade, click on the blue OK button at the bottom of the blade. If you click on “Deployment options” again, you will determine that Azure is building your app. Finally, when the build process is complete, you should see the following:

image

Now let us point to our application in the browser.

image

Even though the web application appears to be working, our task is not yet complete because we have not setup the database properly. To make my point, click on the Register link on the top right-side and try and register a user. Most likely, you will receive the following error if you have turned debug on in the web.config file:

image

Setting up the database with SQL-Azure

Back in the Azure portal (http://portal.azure.com), click on “SQL databases” on the left navigation.

image

Click on + Add at the top left corner.

image

Add a database name, choose the same resource group that you created when you setup the App Service. Click on “Server Configure required settings” to setup your server. This involves entering a database server name, login name, and password. It is necessary for you to remember the username and password because you will need it later on when you configure the database connection string for your web application.

image

Once you have setup the database server, click the blue Select button at the bottom of the blade.

image

Back in the SQL Database blade, click on the blue Create button. The newly created database should show after a short while.

image
Click on the database. You should see a link “Show database connection strings” on the third blade.

image
Click on the “Show database connection strings” link. The connection strings for ADO.NET, JDBC, ODBC, and PHP will be displayed:

Copy the connection string for ADO.NET and paste it into Notepad or any other text editor. Replace {your_username} and {your_password} with your database credentials.
Our next task is to tell our web application about our connection string.
Click on App Services then click on the web application.

image

In the top filter field, enter the work “setting”. Then, click on “Application settings”. This leads to the next blade titled “General settings”. Scroll down until you find the “Connection strings” section.

image

Give the connection string the name “DefaultConnection” and the value is the connection string that you previously pasted in a text editor. Do not forget to click on Save at the top of the blade to save the connection string.

This is the moment of truth. Get back to your web application and register a user. It should work for you as it did for me.

image

The magic of setting up continuous deployment with azure through GitHub is that if you make a change to your application then push the changes to GitHub, then Azure will automatically sync with GitHub and you will see your changes in production within minutes. Try it out.

 

References:

https://docs.microsoft.com/en-us/azure/app-service-web/app-service-continuous-deployment
https://github.com/Microsoft/azure-docs/blob/master/articles/app-service-web/app-service-continuous-deployment.md
http://answers.flyppdevportal.com/MVC/Post/Thread/d5721a11-0f95-4751-b801-84ef056b2b09?category=windowsazurewebsitespreview

Thursday, January 19, 2017

Wednesday, January 11, 2017

Docker on windows 10 error: A firewall is blocking file Sharing between Windows and the containers. See documentation for more info

I got this error after I reset my Docker credentials on Windws 10 Insider Preview Build 14986.rs_prerelease.161202-1928:
A firewall is blocking file Sharing between Windows and the containers. See documentation for more info
This error happened when I tried to share a drive with Docker for Windows 10. I right-clicked on the Docker whale icon in the tray and selected “Setting”. I then clicked on “Share Drives” on the left-side. When I tried to enable any of my existing drives and click on Apply, I got the above error.
My first inclination was to turn off the firewall. The only firewall I use is the built-in Windows Defender. I disabled networking so I do not get attached over the network, then I disabled the Windows Defender. That did not solve the problem. Since I had no idea what else to do, I posted a comment on the “Docker for Windows” Git Hub site.

The Fix:

1. Share the C:, D:, E: … drive in File Explorer
2. Go into the properties of "vEthernet (DockerNAT)" network adapter and uninstall "File and Printer Sharing for Microsoft Networks". Install it again and make sure it is enabled.
I thank the “Docker For Windows” team on GitHub for helping me find a fix for this problem after only 18 days.

Friday, December 30, 2016

Docker-Compose’ing an ASP.NET Core app that uses PostgreSQL database in Linux containers on Windows 10

Docker Compose is a tool for defining and running multi-container applications. In this post I will show you how you can create two containers. One will host a PostgreSQL database and the other will host an ASP.NET Core website. Docker Compose will build a virtual network that allows both containers to communicate with each other.

PostgreSQL is an open source relational database management system ( DBMS ) developed by a worldwide team of volunteers. PostgreSQL is not controlled by any corporation or other private entity and the source code is available free of charge.

The pre-requisites needed to proceed are:
  1. Windows 10 Professional or Enterprise (Anniversary Edition)
  2. Hyper-V enabled on the host Windows 10 operating system
  3. Yeoman command line interface
  4. .NET Core 1.0 is installed on your computer
You can get more information on installing the Yeoman command line interface at http://yeoman.io/codelab/setup.html.

Scaffolding an ASP.NET Core SQLite application with Yeoman


1) Open a command-line window in Windows 10.

2) In a suitable working directory on your hard-drive, create a folder named dev with the following command:
mkdir dev

3) Go into the newly created directory with:
cd dev

4) In the dev folder, create a file named global.json with the following content:
{
  "sdk": {
    "version": "1.0.0-preview2-003131"
  }
}
Note that for this example, we will be using ASP.NET Core version 1.0, as specified in the global.json file.

5) You will now use the Yeoman scaffolding tool to create an ASP.NET Core 1.0 application that uses the SQLite database. Type the following inside the dev folder:

yo aspnet

The following menu will display:

image_thumb1

6) Hit the down-arrow on your keyboard until you get to “Web Application” then hit ENTER.



7) Hit ENTER again to select Bootstrap.

image_thumb3image

8) When asked for an application name, type-in AspnetPostgres then hit ENTER. The application will get created for you. This is what it should look like when it is done:

image

9) Note these suggested instructions:
cd "AspnetPostgres"
dotnet restore
dotnet build
dotnet ef database update
dotnet run
Execute the above five instructions in sequence. Eventually, your command-line windows will be running the Kestrel web server listening on port 5000:

image

10) View the web application by pointing your browser to http://localhost:5000. This is what the web application, running on your host computer,  looks like:

image

Stop the web application by hitting CTRL + C on your keyboard and close your browser.
We are now ready to modify this application so that it uses PostgreSQL instead of SQLite.

Changing app so that it uses PostgreSQL instead of SQLite

We need to make only four changes to our current application so that it works with PostgreSQL instead of SQLite.
  1. Update the connection string in file appsettings.json
  2. Replace a SQLite dependency in file project.jsone with a PostgresSQL dependency
  3. In the Startup.cs file, specify that the app is using PostGresSQL and not SQLite.
  4. Also in Startup.cs, we will instruct the app to implement automatic database migration

1) The Connection String

Open appsettings.json in a text editor and make the following changes:

Replace:
"DefaultConnection": "Data Source=AspnetPostgres.db"
With:
"DefaultConnection": "User ID=docker;Password=docker;Host=db;Port=5432;Database=InstituteDB;Pooling=true;"
The appsettings.json file will eventually look like this:
{
  "ConnectionStrings": {
    "DefaultConnection": "User ID=docker;Password=docker;Host=db;Port=5432;Database=InstituteDB;Pooling=true;"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

2) PostgresSQL dependency

Open project.json in a text editor and make the following changes:

Replace:
"Microsoft.EntityFrameworkCore.Sqlite": "1.0.1",
"Microsoft.EntityFrameworkCore.Sqlite.Design": {
  "version": "1.0.0",
  "type": "build"
},
With:
"Npgsql.EntityFrameworkCore.PostgreSQL": "1.0.0",

Restore

Before we touch any C# code, it is wise to restore dependencies. While in a command-prompt inside the AspnetPostgres directory, run the following command:

dotnet restore

3) Startup.cs file - use PostGresSQL instead of SQLite

Open Startup.cs in a text editor. Find the ConfigureServices() method and make the following changes:

Replace:
services.AddDbContext<ApplicationDbContext>(options =>
  options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
With:
services.AddDbContext<ApplicationDbContext>(options =>
  options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection")));

4) Startup.cs file – automatic database migration

Also, in the Startup.cs file find the Configure() method. We will use dependency injection to get an instance of the database ApplicationDbContext context class. To do this, add an additional argument to the Configure() method so that its signature looks like this:
public void Configure(
  IApplicationBuilder app,
  IHostingEnvironment env,
  ILoggerFactory loggerFactory,
ApplicationDbContext context)
At the bottom end of the Configure() method, add this line of code:

context.Database.Migrate();

Build

Build your application in a terminal window with the following command:

dotnet build

Dockerfile & Docker-Compose

We will deploy two containers. One with the PostgresSQL database and the other with our ASP.NET 1.0 Core application.

Linux containers will be used in this exercise. Therefore, right-click on the Docker (whale) icon in your system tray and make sure it displays:

image_thumb13

If it does not show the above message then you should switch to the Linux container.
Dockerfile
Create a text file in the AspnetPostgres folder named Dockerfile.linux and add to it the following content:
FROM microsoft/aspnetcore-build:1.0.3-projectjson
ENTRYPOINT ["dotnet", "run"]
ENV ASPNETCORE_ENVIRONMENT=Development
WORKDIR /app
COPY . .
RUN dotnet restore
RUN dotnet build
EXPOSE 80
I will explain what each command in Dockerfile.linux does.

FROM microsoft/aspnetcore-build:1.0.3-projectjson We will be using the official Microsoft docker container named microsoft/aspnetcore-build:1.0.3-projectjson as our starting image. This is a suitable container because it already has the .NET Core sdk + npm + bower. Also, it is based on .NET Core version 1.0, which is compatible to our web app.
ENTRYPOINT ["dotnet", "run"] The web application will be started by executing the “dotnet run” command which starts the web server.
ENV ASPNETCORE_ENVIRONMENT=Development We are setting the ASPNETCORE_ENVIRONMENT environment variable so that we can see detailed error messages. In production, you will change this to Production.
WORKDIR /app A directory named /app is created in the Linux container to host our source code.
COPY . . Our source code is copied from the YoAspnet folder on our Windows 10 computer to the /app folder in the Linux container.
RUN dotnet restore This command executes “dotnet restore” in the /app folder in the Linux container.
RUN build This command will build the application
EXPOSE 80 Port 80 is the port number that will be exposed by the container.

docker-compose.yml
Create a text file in the AspnetPostgres folder named docker-compose.yml and add to it the following content:
version: '2'
services:
  db:
    image: postgres
    environment:
      - POSTGRES_USER=docker
      - POSTGRES_PASSWORD=docker
  app:
    links:
      - db
    depends_on:
      - db
    ports:
      - 88:80
    build:
      context: .
      dockerfile: Dockerfile.linux
The above docker-compose.yml file describes two containers:

Container db will host the PostgresSQL database server. This container is built using the postgres image, which will be downloaded from http://hub.docker.com. A user named docker will be created also with password docker.

Container app will host our ASP.NET Core 1.0 application. This container is dependent on container db. The internal container port 80 will be exposed to the host as port 88. The context of the build process will be the current directory and the build process is defined in the Dockerfile.linux file, which we already scripted.

Executing docker-compose.yml

In a command-prompt, execute the following command in order to run docker-compose.yml:

docker-compose up

The instructions in the docker-compose.yml file will take about two minutes to complete. When it is done, you will see that the Kestrel web server is listening on port 80:

image

Open another instance of a terminal window and execute the following command to find out how many containers are running:
docker ps

There are two containers running. One is named aspnetpostgres_app_1 and the other is named aspnetpostgres_db_1.

image

Find out what virtual networks were created by executing the following command:

docker network ls

This reveals that a network named aspnetpostgres_default was created which both containers use to communicate with one-another:

image

Let us also find out where the data is being saved. Type the following command:

docker volume ls

This shows that a volume was created by PostGresSQL for the data:

image

This database volume will not be deleted automatically when the container is stopped or removed.

Now for the moment you have been waiting for: Point your browser to http://localhost:88. You should see our website being served from the ASP.NET Core 1.0 container:

image

Click on Register in the top-right corner and enter a user email and password:

image

After clicking on the Register button, you should see that the new user was indeed created:

image

Cleanup

Stop the terminal window that you used for docker-compose by hitting CTRL + C on the keyboard.
Type the following command to tear down all the containers and networks that were created by docker-compose.yml:

docker-compose down

At this stage, the database volume will still exist. To delete the database volume, type the following command:
docker volume prune

References:

https://docs.docker.com/compose/overview/

Thursday, December 29, 2016

ASP.NET Core 1.0 SQLite app in Windows Docker container on Windows 10 with yeoman

In a previous post, I showed how you can scaffold an ASP.NET Core 1.0 app that uses SQLite and deploy it into a Linux Docker container on Windows 10. In this post I will show you how to do the same thing, but instead in a Windows container rather than a Linux container.
If you are new to Docker on Windows 10, you can refer to a previous post that will help you install and configure it.
The pre-requisites needed to proceed are:
  1. Windows 10 Anniversary edition or later
  2. Hyper-V enabled on the host Windows 10 Anniversary operating system
  3. Yeoman command line interface
  4. .NET Core 1.0 is installed on your computer
You can get more information on installing the Yeoman command line interface at http://yeoman.io/codelab/setup.html.

Scaffolding an ASP.NET Core SQLite application with Yeoman


1) Open a command-line window in Windows 10.

2) In a suitable working directory on your hard-drive, create a folder named dev with the following command:
mkdir dev

3) Go into the newly created directory with:

cd dev

4) In the dev folder, create a file named global.json with the following content:
{
  "sdk": {
    "version": "1.0.0-preview2-003131"
  }
}
Note that for this example, we will be using ASP.NET Core version 1.0, as specified in the global.json file.

5) You will now use the Yeoman scaffolding tool to create an ASP.NET Core 1.0 application that uses SQLite as its database. Type the following inside the dev folder:

yo aspnet

The following menu will display:

image_thumb1

6) Hit the down-arrow on your keyboard until you get to “Web Application” then hit ENTER.

image_thumb3

7) Hit ENTER again to select Bootstrap.

image

8) When asked for an application name, type-in YoAspnetWin then hit ENTER. The application will get created for you. This is what it should look like when it is done:

image

9) Note these suggested instructions:
cd "YoAspnetWin"
dotnet restore
dotnet build
dotnet ef database update
dotnet run
Execute the above five instructions in sequence. Eventually, your command-line windows will be running the Kestrel web server listening on port 5000:

image

10) View the web application by pointing your browser to http://localhost:5000. This is what the web application, running on your host computer,  looks like:

image

Stop the web application by hitting CTRL + C on your keyboard.

We are now ready to deploy this SQLite database driven application into a Windows Docker container.

Writing code to create the database

We will be publishing a release version of our application and then deploy it into a Windows docker container. One of the instructions that we executed in the command line (dotnet ef database update) is intended to apply migrations and create the database. This cannot be done in production once our app is published. Instead, we will have to execute code in our application that creates the database according to our connection string.

The connection string is specified in appsettings.json file and its content is:
{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=YoAspnetWin.db"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}
Open the Startup.cs file in a text editor and find the Configure() method. We will use dependency injection to get an instance of the database ApplicationDbContext context class. To do this, add an additional argument to the Configure() method so that its signature looks like this:
public void Configure(
  IApplicationBuilder app,
  IHostingEnvironment env,
  ILoggerFactory loggerFactory,
  ApplicationDbContext context)
At the bottom end of the Configure() method, add this line of code:

context.Database.EnsureCreated();

EnsureCreated() is new EF core method which ensures that the database for the context exists. If it exists, no action is taken. If it does not exist then the database and all its schema are created and also it ensures it is compatible with the model for the context.

Eventually, the Configure() method will look like this:
public void Configure(
  IApplicationBuilder app,
  IHostingEnvironment env,
  ILoggerFactory loggerFactory,
  ApplicationDbContext context)       
{
  loggerFactory.AddConsole(Configuration.GetSection("Logging"));
  loggerFactory.AddDebug();

  if (env.IsDevelopment()) {
      app.UseDeveloperExceptionPage();
      app.UseDatabaseErrorPage();
      app.UseBrowserLink();
  } else {
      app.UseExceptionHandler("/Home/Error");
  }

  app.UseStaticFiles();
  app.UseIdentity();
  app.UseMvc(routes =>
  {
      routes.MapRoute(
          name: "default",
          template: "{controller=Home}/{action=Index}/{id?}");
  });
 
  context.Database.EnsureCreated();
}
Save your file then execute this statement from the command-line to ensure that your app compiles OK.
dotnet build

Deploying web app into Windows Docker container

We will be deploying our web app into a Windows container. Therefore, right-click on the Docker (whale) icon in your system tray and make sure it displays:

image

If it does not show the above message then you should switch to the Windows container.
We will next publish our application into a directory named out. Therefore, run the following instruction inside of a command-line window in the YoAspnetWin folder:

dotnet publish -c Release -o out

Have a peek at the files in the out folder. You will notice that it contains all the compiled files that make up the release version of our application:
image

Create a text file in the YoAspnetWin folder named Dockerfile.nano and add to it the following content:
FROM microsoft/dotnet:1.0-sdk-projectjson-nanoserver
ENTRYPOINT ["dotnet", "YoAspnetWin.dll"]
WORKDIR /app
ENV ASPNETCORE_URLS
http://+:82
EXPOSE 82
COPY out .
I will explain what each command in Dockerfile.nano does.

FROM microsoft/dotnet:1.0-sdk-projectjson-nanoserver We will be using the official Microsoft docker container named microsoft/dotnet:1.0-sdk-projectjson-nanoserver as our starting image. This is a suitable container because it already has the small Windows Nano server. It also has the .NET Core version 1.0 runtime, which is compatible to our web app. Note that it does not contain the .NET Core SDK, so we cannot run commands like dotnet restore, dotnet build, etc… in the container.
ENTRYPOINT ["dotnet", "YoAspnetWin.dll"] The web application will be started by executing the “dotnet YoAspnetWin.dll”. The name of the DLL file is dictated by the name of the containing folder during execution of the “dotnet publish” step, which we did previously.
WORKDIR /app A directory named /app is created in the Windows container to host our published app.
ENV ASPNETCORE_URLS http://+:82 The environment variable ASPNETCORE_URLS is set so that the listening Kestrel web server port in the container is 82.
EXPOSE 82 Port 82 is the port number that will be exposed by the container.
COPY out . The contents of the out folder is copied into the /app working directory in the container.

Inside a command-prompt in the YoAspnetWin folder, execute the following to build an image named dotnetweb/nano that contains our web app:

docker build -t dotnetweb/nano -f Dockerfile.nano .

This will download the microsoft/dotnet:1.0-sdk-projectjson-nanoserver container from http://hub.docker.com and subsequently build our new image. When it is done, you can type the following command to see all the images you have:

docker images

image

You will find at least these two images.
  1. dotnetweb/nano is the docker image we just built
  2. microsoft/dotnet:1.0-sdk-projectjson-nanoserver is the base image we used
To make a container from the image and run it, type the following command:

docker run -d -p 88:82 dotnetweb/nano

Run the following command to determine which containers are running:

docker ps

It should show the following running images:

image

You would think that we can access the web site using http://localhost:88. If you try that your browser will report back that the site can’t be reached. This is because there is a bug with Windows containers running under Windows 10 that does not allow that. The alternative, is to access the web server directly inside the container, which is being exposed on port 82. But, what is the IP address of the container? This is where the “docker inspect” command comes to the rescue. Grab the first two or three characters of the container-id. Looking as the previous screen-capture, the container-id is c1d. Therefore, then run the following command with your container-id:

docker inspect c1d

image

Grab the container’s IP address and try http://{container-ip-address}:82. In my case, this is http://172.29.131.95:82.

image

Yep. It works.

We must ensure that our database is indeed working. In order to do that, click on Register in the top-right corner of the web app and enter a user email and password:

image

After clicking on the Register button, you should see that the new user is successfully created:

image

Cleanup

To stop the container you can simply use the first two or three character of the container-id as follows:

docker stop c1d

To see which containers are still available, type:

docker ps -a

To delete the container completely, identify the first two to three character of the container-id then use the “docker rm” command similar to the following:

docker rm c1d

I you run “docker ps –a” again you will determine that the container is gone.
Find out what images you have by typing  the following command:

docker images

You can delete the image by id or by name, as follows:

docker rmi ce3
                    OR                           docker rmi dotnetweb/nano

After you remove the image you can again type “docker images” to prove that the image is indeed deleted.