Publish and Deploy Asp.Net Core Applications from Jenkins to IIS - 2017 Edition

Georg Dangl by Georg Dangl in Continuous Integration Sunday, October 22, 2017

Sunday, October 22, 2017

Posted in Jenkins DotNet

If you have an Asp.Net Core application that you want to continuously deploy to either Azure or IIS on a Windows Server, you should follow the following, simple steps.

This is a follow up post to last years article. It's updated for the Visual Studio 2017 project format.

Get the Required Tools on the CI Server

Just like with unit testing in a CI environment, you’ll need the .Net Core SDK to be available to Jenkins. It’s available at the official download site. Make sure you've got matching SDK and runtime versions, as you might encounter issues with xUnit if you have a later SDK installed with no matching runtime.

Additionally, if you're using IIS instead of an Azure Web App, you need the .Net Core Windows Server hosting bundle on the hosting server, available on the same site. See the official documentation for how to install it.

You will also need to install Node.js  and npm on the server that is hosting Jenkins so you can run all the prepublish commands for an Asp.Net Core application. To install Node.js, go to its download site and grab the latest Windows installer. When installing, make sure that Add to PATH is enabled in the install options (it is by default), so that the npm command is added to the PATH environment variable and therefore directly recognized in the command line interface.

Make sure to restart Jenkins after you've added the tools, as the PATH variable is only read at startup and not watched for changes!

Tip: It's not required to globally install node modules like bower or gulp on the build server. That should be handled by node.js’ devDependencies and proper pre- and postpublish scripts in your deployment process.

Finally, the Web Deploy tool should be installed on your server to easily deploy to IIS and Azure from the command line.

Configure Jenkins to Build the Project

In Jenkins, just create a new project and configure the source code management, for example by pulling from a Git repository. To build, publish and deploy, the following commands are necessary. They're explained in detail in the next section.

  1. Windows Batch
    cd src\<ProjectFolder>
    dotnet publish -c Production -o publish

    The dotnet publish command restores, builds and publishes the web application. With -o publish, we're specifying the output folder to be /publish, relative to the project directory.
  2. Windows PowerShell (optional)
    cd src\<ProjectFolder>
    ./TransformWebConfigForProduction.ps1
    There's no built in support in the dotnet CLI currently that allows the transformation of web.config files, so we're calling a custom PowerShell script to do it for us before deploying.
  3. Windows Batch
    "C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:IisApp='%WORKSPACE%\src\<ProjectFolder>\publish' -dest:iisapp='<SiteName>',computerName='<WebDeployEndpoint>/msdeploy.axd?site=<SiteName>',authType='basic',username='<DeployUsername>',password='<DeployPassword>' -enableRule:AppOffline

    Uses Web Deploy to copy the publish folder to the server. You might have to adjust the path to msdeploy.exe if it's different on your machine.

 

Publish the Project

The first build step switches to the project directory and then calls dotnet publish -c Production -o publish.

To make sure your pre- and postpublish scripts run, include them in your package.json (for npm) and project.csproj (for dotnet) files, for example like this:

This combination would effectively run the npm install command first, followed by bower installgulp clean and gulp min, then compile and publish the application via dotnet CLI. This example is from the WebDocu project, a very simple MVC website. You can get a bit more creative for your apps, for example by using the Angular CLI to build your Single Page App front end bundles and copy them into your wwwroot folder before publishing.

The WebConfigTransformRunner dependency is optional. It's to get the console tool via NuGet if you intend to run web.config transformations in the next step.

Run web.config Transformations (optional)

To run web.config transformations from the command line, make sure the WebConfigTransformRunner tool is referenced in your project and call this script in your project directory:

If you want to read more about manually running web.config transformation, see here.

Publish to IIS with Web Deploy

For the next step, you should have set up Web Deploy on both the source and target server. There’s only one step needed, and that is calling msdeploy.exe to publish the app to IIS or Azure.
When doing that, you must supply valid credentials for the user that has publishing rights in IIS. In Azure, you can simply download the publish profile in the Web App settings and extract the deployment username and password.

Since it’s never a good idea to include plain text user credentials in a script or build step, you should set up credentials in Jenkins and use these as variables in your build step.

The command for web.deploy is rather long:

"C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:IisApp='%WORKSPACE%\src\<ProjectFolder>\publish' -dest:iisapp='<SiteName>',computerName='<WebDeployEndpoint>/msdeploy.axd?site=<SiteName>',authType='basic',username='<DeployUsername>',password='<DeployPassword>' -enableRule:AppOffline

  • ProjectFolder
    That's simply where the project is inside your Jenkins workspace.
  • SiteName
    The name for the site. This is rather important since the WebDeploy service will determine whether or not the user has access to the service depending on the site name that is specified here.
  • WebDeployEndpoint
    You should just specify the Url endpoint for the WebDeploy service. You either configure it manually in IIS or just download the publish information for an Azure Web App. Here's a post about configuring Web Deploy on IIS.
  • DeployUsername
    The username for the user who you gave access to WebDeploy. You should really use Jenkins credentials for this instead of pasting the actual username and password in your Jenkins job.
  • DeployPassword
    Should be clear – Provide the user accounts password

The authType=’Basic’ parameter is not strictly required. If your happen to be in an Active Directory domain, you could also use Windows Authentication and completely omit any credentials in the Web Deploy process.

Specyfing -enableRule:AppOffline means that your app is taken offline during the deployment process to avoid file locks.

verb:sync makes sure to sync our publish folder with the server, so this is the operation (“verb”) to perform

If you want to dig further into msdeploy, these three links from the technet contain a lot of info:

Summary

Now you should be able to click on “Build now” and let the magic happen, continuous deployment for your .Net Core website. It's good practice to configure triggers for your job. I often use branches for workflow control, e.g. I have a job that deploys a website to a staging (or testing) environment whenever a push happens to the develop branch.

Happy Deploying!

 


Share this post


comments powered by Disqus

Dangl.Blog();
// Just 💗 Coding

Social Links