Martin Suchan – BloQ Random #WPdev stuff

17Oct/1416

How to deploy your own NuGet server on Azure Website in 15 minutes

Let's imagine this typical scenario: You are an indie developer or a company developing apps in Visual Studio. You have already developed and use several own useful libraries across various projects. Right now you are maintaining each of these libraries in separate Git/TFS repository and adding these libraries as submodules to your projects. Because these libraries are hierarchically dependent one on another, it's quite hard to maintain the dependencies and changes properly. You've thought about packaging these libraries as separate NuGet packages, but adding them to public nuget.org gallery is not an option since these libraries contain private knowhow.

In this article I'll demonstrate, how to deploy your own NuGet Server on free instance of Azure Website, secure it with Basic HTTP Authentication, setup this new server so it can be used from Visual Studio, easily create automatic PowerShell scripts for deploying these libraries as NuGet packages to your server, use these NuGet packages in your projects and also how to achieve all this in just couple of minutes!

Step 1. New Azure Website

This guide uses for hosting private NuGet server free instance of Azure Website. Installing private Nuget server on virtual machine and IIS is really not much different.

Step 1.1 Azure account

In case you don't have Azure account already, you can create one here for free.
For this article you don't need to use any payed Azure service, private NuGet server can run just fine in free Azure Website instance, but if you need better availability, custom domain or SSL, then you need to switch to one of payed tiers.

With a valid Azure account the first step is creating new Azure Website, where the NuGet server will be hosted. Click New in the Website section, pick any free name in the URL field and then pick any hosting plan and location. You can choose the Free Website plan and change it later to payed one.

1azure

 

 

 

 

 

 

 

 

 

 

 

 

The new website is created in just couple of minutes.

2azure

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Step 2. New ASP.NET Web project in Visual Studio

The private NuGet server will be deployed as a simple ASP.NET Web site, so just open Visual Studio 2013 and create empty ASP.NET Web project in the Cloud section:

3vs

 

 

 

 

 

 

 

 

 

 

 

 

 

In the next dialog just select vanilla empty ASP.NET project. Note the "Host in the cloud" option should be unchecked, you will be using website already created in the previous step.

4vs

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Step 3. Adding and configuring the NuGet.Server package

Once the empty ASP.NET project is created in Visual Studio, the next step is adding the NuGet.Server package to it... from NuGet. It sounds a bit meta, but it's actually really simple. Folks from the nuget.org created single NuGet package for deploying your own NuGet server. You can also check the original guide as a reference.

5nuget

 

 

 

 

 

 

 

 

 

 

 

 

So far it was just a simple Wizard like guide without really any configuration, but this changes now. Once the NuGet.Server package is added including all dependencies, you need to configure it a bit.

First you need to configure the web.config file with your unique API key to secure the deployment of your new NuGet packages. New Guid can be generated simply using nguid ReSharper snippet.

6key

 

 

 

 

 

 

 

 

 

 

The other web.config switches are optional, more information about those switches is in the original NuGet.Server article.

Once the API key is configured, you can test the build and deployment of the project to Azure. Right click the Project and choose Publish.

Here just log in with your Azure credentials and you should get this dialog with list of your Azure Websites.

7azure

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Note if you don't see the Publish option in Visual Studio, you probably need to install the latest Azure Tools for Visual Studio 2013

Once you are logged in, you can just press Publish and after few seconds your own NuGet server is deployed and running in the cloud, yay!

8ie

 

 

 

 

 

 

 

 

 

 

 

Step 4. Adding Basic HTTP Authentication

So far it was just a quite simple guide, but it's time for some actual customization. Publishing private NuGet server to the cloud is great, but the problem with Azure website is that anyone can access the repository once the Uri is revealed. One solution, how to make the NuGet server available only for selected developers, is adding Basic HTTP Authentication.

How Basic HTTP Authentication works in a nutshell:

The server sends back a header stating it requires authentication for a given realm. The user provides the username and password, which the browser or client concatenates (username + ":" + password), and base64 encodes. This encoded string is then sent using a "Authorization"-header on each request from the browser. Because the credentials are only encoded, not encrypted, this is highly insecure unless it is sent over https.

Securing the NuGet site with basic authentication can be done by following this guide. Start with adding BasicAuthenticationModule to the project + few supplemental configuration files that can be found here, and then finally by adding configuration for the authentication in web.config file:

<configSections>
  <section name="basicAuth" type="Devbridge.BasicAuthentication.Configuration.BasicAuthenticationConfigurationSection" />
  ...
</configSections>
...
<basicAuth>
  <credentials>
    <add username="nugettest42" password="42nugettest"/>
  </credentials>
</basicAuth>
<system.webServer>
  <validation validateIntegratedModeConfiguration="false" />
  <modules runAllManagedModulesForAllRequests="true">
    <add name="MyBasicAuthenticationModule" type="Devbridge.BasicAuthentication.BasicAuthenticationModule" />
    ...
   </modules>
 ...
</system.webServer>

 

After rebuilding and republishing the project to Azure this is what you get if no error occurs.

9ie

 

 

 

 

 

 

 

 

 

 

 

 

No one can access you packages now without knowing the username and password.

 

Step 5. Publishing NuGet packages to the private NuGet server

The NuGet server that was just created is up and running. The next step is creating NuGet package for libraries you actually use.

In this sample let's create .NET 4.5 library for generating numbers based on seed 42.

10dll

 

 

 

 

 

 

 

 

 

 

 

This library is then consumed by simple .NET 4.5 WPF project.

12app

 

 

 

 

 

 

 

 

 

 

The library is now used as a project reference, so let's change it to a proper NuGet package.

 

Step 5.1 Creating NuGet package for the library

How to create NuGet packages is described thoroughly on nuget.org website, in short it's necessary to create .nuspec metadata file describing the package name, version, all included dlls and other required data. This file can be edited either as a XML document in any text editor, or using NuGet Package Explorer tool, if you prefer editors with UI. Running in command line this command produces the actual .nupkg file:

nuget pack MyRandomGenerator.nuspec

Note you can run this command either in NuGet Package Manager Console or in cmd.exe or PowerShell. In case of the latter you need to download the nuget.exe executable and place into folder, that is included in PATH Environment variable.

Pushing the nupkg file to either official nuget.org gallery or to own NuGet server is done by running:

nuget push MyRandomGenerator.nupkg

Step 5.2 Adding your NuGet server into Visual Studio

In order to use your new NuGet server as a package source in Visual Studio, you need to add it first into the list of sources, so open Visual Studio and go to Tools -> Options:

12sources

 

 

 

 

 

 

 

 

 

 

 

If you look back at the last screenshot in Step 3, these are the Uris you need to use.

Note, the package sources can be added either using Visual Studio Options dialog, or using command line. In our example where NuGet Server requires Basic HTTP Authentication you have to use the command line option, because the dialog in Options does not support adding password protected remote sources. So let's run this in NuGet Package Manager Console:

nuget sources add -Name "NugetTest 42" -Source "https://nugettest42.azurewebsites.net/nuget" -UserName "nugettest42" -Password "42nugettest"
nuget sources add -Name "NugetTest 42 Publish" -Source "https://nugettest42.azurewebsites.net/" -UserName "nugettest42" -Password "42nugettest"

 

Step 5.3 Uploading NuGet package to your NuGet server

There are several ways, how to upload your MyRandomGenerator.nupkg to your NuGet server:

- the file can be either included directly in the Web app project in the Packages folder
- or it can be uploaded directly to the server using filetransfer via FTP
- or using the nuget.exe:

nuget push MyRandomGenerator.nupkg -Source https://nugettest42.azurewebsites.net/ -ApiKey fd9907c1-22c1-42c4-b9c6-b485684ea25c

 

Step 6. Automatic scripts for publishing NuGet packages

The previous Step shows, how to pack your .NET library as a NuGet package, upload it to your NuGet server and add your server into Visual Studio as a package source. So far it was quite lot of a manual work. To make the process a single click user experience, the following guide shows, how to pack all these steps in two Powershell scripts.

First script called 0_InitSources.ps1 contains methods for adding both NuGet server sources to Visual Studio. This is useful for initial configuration of your environment when joining the developer team.

# initialize
Write-Host "`nInitializing NuGet sources" -foregroundcolor Green
nuget sources add -Name "NugetTest 42" -Source "https://nugettest42.azurewebsites.net/nuget" -UserName "nugettest42" -Password "42nugettest"
nuget sources add -Name "NugetTest 42 Publish" -Source "https://nugettest42.azurewebsites.net/" -UserName "nugettest42" -Password "42nugettest"

# wait for user input
Write-Host "`nDone!" -foregroundcolor Green
Pause

Second script called 1_PushNewVersion.ps1 contains logic for single click rebuilding of your MyRandomGenerator library, packing it into NuGet package and publishing it to your NuGet server. This second script also contains interactive dialog where the user can enter version number of the new NuGet package and also release notes for this new package.

Note that the second script is based on New-NuGetPackage PowerShell Script which contains all important and useful methods that you might need when building automated NuGet deployment scrips:

$nuspec = "MyRandomGenerator.nuspec"
$solution = "..\NuGetDemo.sln"
$config = "Release"
$msbuild = "C:\Program Files (x86)\MSBuild\12.0\bin\MSBuild.exe"
$pushoptions = "-Source ""https://nugettest42.azurewebsites.net/"" -ApiKey ""fd9907c1-22c1-42c4-b9c6-b485684ea25c"""
set-alias msbuild $msbuild

# clean
Write-Host "`nCleaning solution" -foregroundcolor Green
msbuild $solution /t:Clean /p:Configuration=$config /verbosity:m /nologo

# build
Write-Host "Building solution`n" -foregroundcolor Green
msbuild $solution /t:Build /p:Configuration=$config /verbosity:m /nologo

# create NuGet package
Write-Host "`nPublishing NuGet package" -foregroundcolor Green
.\New-NuGetPackage.ps1 -NuSpecFilePath $nuspec -PushPackageToNuGetGallery -PushOptions $pushoptions

# wait for user input
Write-Host "`nDone!" -foregroundcolor Green
Pause

In short this script builds your project and calls the New-NuGetPackage.ps1 with the path of your nuspec file and path to your server, it's really that simple.

For configuring the PowerShell scripts with other projects you just need to change the path of your NuGet server, API key, name, password and path to your project and nuspec file. The rest is done automatically.

Summary

It's really easy to deploy your own NuGet server from Visual Studio in cloud on Azure Website, add it as package source to Visual Studio and build new package of your library with just a single click, so if you have been wondering, how hard it could be to deploy something similar on your own, just grab the source code and try it yourself 🙂