This workshop is designed to take you through some of the options you have available when configuring and deploying an application to a production-ready environment. That could be a local web server, filesystem, Docker container, or the cloud.
In this module, you'll see how to:
- Publish a web application using Visual Studio
- Apply Entity Framework Migrations to SQL Server
- Take advantage of Environment Variables to configure an application
- Get started with some Docker basics
- Use a Docker hosted database service with ASP.NET Core
- Publish to a Docker container
- Scale a Docker Container collection
The following is required to complete this module:
- Visual Studio Community 2015 or greater OR Visual Studio Code
- ASP.NET Core 1.0
- Docker
Note: You can take advantage of the Visual Studio Dev Essentials subscription in order to get everything you need to build and deploy your app on any platform.
In order to run the exercises in this module, you'll need download the contents of this repository from GitHub
This module includes the following exercises:
- Build and Publish from Visual Studio
- Working with Entity Framework Migrations
- Use Environment Variables to configure an application
- Get Started with Docker Basics
- Switch to a Docker hosted Postgres database
- Publish to a Docker Container
- Scale Docker Containers
Note: When you first start Visual Studio, you must select one of the predefined settings collections. Each predefined collection is designed to match a particular development style and determines window layouts, editor behavior, IntelliSense code snippets, and dialog box options. The procedures in this module describe the actions necessary to accomplish a given task in Visual Studio when using the General Development Settings collection. If you choose a different settings collection for your development environment, there may be differences in the steps that you should take into account.
-
Open Visual Studio Community 2015 and select File | Open | Project / Soloution and choose the Source/MyWebApp.sln solution file.
-
In the Solution Explorer, right-click MyWebApp and click Publish.
Publish Context Menu
-
In the publish dialog, choose the Custom option
Custom Publish Option
-
In the modal New Custom Profile dialog box, name your profile Local Filesystem and click OK
-
Set the Publish Method to File System and the target location to .\PublishOutput and click Next
Configure the Publish Connection
-
In the Publish Settings screen, apply the following settings and click Publish:
Publish Settings
You should now see your Output Window open and the build process for the application. The results of the build should be deposited in the Source/MyWebApp/src/PublishOutput folder. Open a command-prompt and navigate to that folder and test your application by running:
dotnet MyWebApp.dll
But... something went wrong, and there's a wonderfully helpful stack trace dumped all over your beautiful console window. What went wrong?
Entity Framework Core has been updated and brings migrations to the cross-platform capabilities of .NET Core. In this exercise, we're going to fix the problem from the previous exercise by applying our Entity Framework migrations and restarting the web server.
-
Open a command-prompt and navigate to the Source/MyWebApp/src/MyWebApp folder.
-
Execute the Entity Framework tools command with the dotnet command-line tool by typing:
dotnet ef
You should be greeted by a helpful splashscreen of options and magic unicorns:
Entity Framework Console Splash Screen
- The database that will be used is defined in the **appsettings.json** file as a value for the **SqlConnection** setting. Apply the migrations to this instance of localdb with the command:
dotnet ef database update
The database should be created for you and updated with the configuration of the models defined in our sample project. - Browse back to the **PublishOutput** folder by executing the following command:
cd PublishOutput - Launch the web server with the command:
dotnet MyWebApp.dll
... and you should now be able to browse to the application at http://localhost:5000
-
Open the
Views\Shared\_Layout.cshtmlfile in your editor. Observe theEnvironmentTagHelper which renders its content only if the active environment matches one of the values in thenamesattribute.<environment names="Development"> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" /> <link rel="stylesheet" href="~/css/site.css" /> </environment> <environment names="Staging,Production"> <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css" asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css" asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" /> <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" /> </environment>
-
At the top of the layout file, add the following line to inject the Hosting Environment service into your view.
@inject Microsoft.AspNet.Hosting.IHostingEnvironment HostingEnvironment -
Find the footer element in layout page and modify it to display the active environment.
<footer> <p>© 2016 - WebApplicationBasic</p> <p> Env: @HostingEnvironment.EnvironmentName </p> </footer>
-
Right-click on the project in solution explorer and click on properties.
-
Select the Debug tab in the project properties window and click New button.
Create a new launch profile
-
Name the new launch profile IIS Express (Staging)
-
In the Launch dropdown chose IIS Express
Launch IIS Express
-
Add an Environment Variable named
Hosting:Environmentwith a value ofStagingand save the changes to your project properties.Set Environment Variable
-
In the Debug Dropdown, select IIS Express (Staging) and launch your application. You should now see the environment name displayed in the footer of your web application.
-
Let's run our first Docker container with the command:
docker run hello-world... and you should have a nice message returned to you that verifies your Docker installation is working properly.
-
We can then go further and run a Ubuntu Linux container and access a shell within that container with the command:
docker run -it ubuntu bash... and you are now running Linux inside of a container on Windows. The -it switch directs docker to start the container in interactive mode and to allocate a terminal for you to connect to. The ubuntu argument is the name of the Docker image to start, and bash is the command to execute in the terminal we are connecting to.
Try some standard Linux commands to verify that you are truly operating in Linux. When you are finished, execute the command
exitto depart the Linux container. -
Next, execute the following command to see the containers that we just ran:
docker ps --allYou will be greeted with a list of containers and their state.
Docker container state
Notice: Each container is listed as 'Exited'. These containers are no longer running. Also, they all have random system generated names reported in the last column.
-
We can then remove these containers by executing the following command for each of the listed containers
docker rm d6fWhere d6f is the first three characters of the CONTAINER ID in the report.
-
Start a postgres database container by executing the following command at a command-line:
docker run -d -p 5432:5432 --name pg postgresThat command should return a long hexadecimal number that is the CONTAINER ID of the container that was just started. Lets break down what Docker tasks this command performed:
- run started a new container from a Docker Image called postgres The image name is at the end of the command because all options must be declared first. The postgres image was downloaded from the Docker Hub - a repository of Docker images available for the public to use and build on.
- -d instructs Docker to run in disconnected mode. This means it will start the container in the background and return control of the command-line to you.
- -p 5432:5432 declares that Docker needs to open a network port from the container to the host machine. In this case, we are opening the port 5432 and passing it directly because that is the standard Postgres database port. The format of this argument is in the form of host machine port : container port
- --name pg declares a name for the container instead of a system generated name. In this case, pg is an abbreviation for Postgres.
-
We can reconfigure our application to use the Postgres database by modifying appsettings.json in the src/MyWebApp folder and setting the ConnectionStrings:Type value to Postgres
{ "ConnectionStrings": { "Type": "Postgres", -
Apply migrations to the Postgres database the same way we did the SQL Server database:
dotnet ef database update -
Update the footer of the _Layout.cshtml page to contain some additional information about the database type and the HOSTNAME environment variable:
<footer> <p>© 2016 - WebApplicationBasic</p> <p> Env: @HostingEnvironment.EnvironmentName - @Config["HOSTNAME"] - @Config["ConnectionStrings:Type"]</p> </footer> ```
-
Launch the application from the src/MyWebApp folder with the command:
dotnet run... and then navigate your browser to the application at http://localhost:5000 Click through to the Speaker List to see an Angular formatted grid with data presented from the Postgres database.
- Right Click on the project name in the Solution Explorer and select Add | Docker Support
-
Several files will be added to the project, and configuration updates applied to allow Visual Studio 2015 to work with the Docker container. Get started running the application in a container by clicking the Debug | Start menu item to build, deploy to a container, and attach the Visual Studio debugger.
-
This will generate a docker-compose.yml file in your project. We will update this file to control how our application is started and run inside of the container. Modify the contents of the file to contain the following:
version: '2' services: db: image: postgres ports: - "5432:5432" mywebapp: image: username/mywebapp environment: "ConnectionStrings:Type": Postgres "ConnectionStrings:PgConnection": Server=db;User ID=postgres; depends_on: - db ports: - "80:80" -
Run a Build | Build MyWebApp from within Visual Studio 2015. This will generate a Docker Image that we can use to create our containers.
-
From the command-line, let's start the collection of our database and web server with this command:
docker-compose up -dThis will start the containers and they will run in the background. There is a quirk with the way that the containers start, because the web service depends on the Postgres database and the migrations are not applied, nor is the database ready to service the web requests.
-
Let's apply the entity framework migrations to the Postgres container with the command:
dotnet ef database update -
Restart the web service in the docker cluster with the command:
docker-compose scale mywebapp=1 - Published and deployed a Web Application to aDocker Container using Visual Studio
- Changed behavior of your app based on different deployment environments
- Worked with composing multiple Docker containers
ASP.NET Core introduces improved support for controlling application behavior across multiple environments, such as development, staging, and production. Environment variables are used to indicate which environment the application is running in, allowing the app to be configured appropriately.
ASP.NET Core uses a particular environment variable, ASPNETCORE_ENVIRONMENT (or Hosting:Environment), to describe the environment the application is currently running in. This variable can be set to any value you like, but three values are used by convention: Development, Staging, and Production.
In this exercise, we will run our first Docker containers and verify that Docker Beta is running properly in our environment. If Docker is started properly on your machine you should see a whale in the system tray:
Docker Whale Icon in the System Tray
With the latest beta of Docker for Windows and Mac, you should be able to have Docker containers running in the background while you are working in Visual Studio. We can get started with Docker commands by opening a command prompt or a Powershell prompt and start executing commands with the Docker command-line tool.
Now that we have Docker running, lets move our test database to a container so that we can start and stop it, move it to another host, and manage the database like it was a virtual machine.
BONUS CREDIT
Examine the source code and determine where the speaker list is created and add your name and topic to the list. Rebuild and run your application to verify you added yourself to the seed data properly.
Next, we will add Docker support to our project which will allow us to manage the configuration of the application as it runs in the container through a series of configuration files. This will also allow us to easily deploy a container with our application completely configured the way it should be run to another environment.
Add Docker Support to a Project
At this point, you should be able to navigate to http://localhost and see the results of your docker containers running.
BONUS
Update your docker-container.yml file to contain the following to enable a load-balancer and the ability to scale your web application:
version: '2'
services:
db:
image: postgres
ports:
- "5432:5432"
lb:
image: dockercloud/haproxy
links:
- mywebapp
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "80:80"
- "1936:1936"
mywebapp:
image: username/mywebapp
environment:
"ConnectionStrings:Type": Postgres
"ConnectionStrings:PgConnection": Server=db;User ID=postgres;
depends_on:
- db
By completing this module, you should have:










