Skip to content

Commit

Permalink
Added a bunch more docs
Browse files Browse the repository at this point in the history
  • Loading branch information
analogrelay committed Oct 14, 2013
1 parent 88fa3d7 commit 1a26ca4
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 65 deletions.
Binary file removed docs/Deploying to Websites/05-AppSettings.png
Binary file not shown.
41 changes: 41 additions & 0 deletions docs/Deploying/CloudServices/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Deploying the NuGet Gallery to Windows Azure Cloud Services

## Setting up resources
To run the NuGet Gallery on Windows Azure Cloud Services you need to provision the following Azure resources:

1. An Azure Cloud Service
2. An Azure SQL Database (preferably in a dedicated Azure SQL Server) to hold the package metadata
3. An Azure Storage account to hold package files, diagnostics data, etc.

It is assumed you've already provisioned the SQL Database and Storage Account using the [main guide](../README.md).

## Provisioning the Frontend
Create an Azure Cloud Service. Poof, done. Ok, not quite. Grab the [src\NuGetGallery.Cloud\ServiceConfiguration.Local.cscfg](..\..\..\src\NuGetGallery.Cloud\ServiceConfiguration.Local.cscfg) file and copy it to somewhere **OUTSIDE** the repository. Give it a name that you'll remember like "MyNuGetGallery.TestEnvironment.cscfg". Update the settings as per the comments inside the file using the connection strings you received while provisioning resources for the site (SQL DB, Azure Storage, etc.).

Save this file somewhere safe and **SECURE** as it now has passwords for your database inside!

## Deploying the Service
These steps should be repeated each time you have new code to deploy.

### Migrate the Database
Migrate the database by running "Update-Database" from the Package Manager Console in a Visual Studio session with NuGetGallery.sln. You must select "NuGetGallery" as the default project. Use the "-ConnectionString" parameter to specify the connection string to the target database.

We attempt to ensure most migrations are additive, but please verify this before migrating your database. Our development process attempts to ensure that old code can read new data for a short transition period. If you keep your code up to date with ours (we deploy approximately fortnightly) then you should be able to match this process.

### Updating Service Credentials
We highly recommend updating service credentials (SQL passwords, Azure Storage keys, etc.) on each deployment to reduce the risk of credential leakage. Some incomplete notes on doing this are listed below:

1. Use the CreateSqlUser task in the 'galops' executable (implemented in NuGetGallery.Operations) to create a SQL User suitable for the Gallery Frontend and update the SQL Connection String for the Frontend to use it. NOTE: DO NOT remove the old user until the old code is offline. ALSO: DO NOT use this user in the Backend as the Backend requires administrator permissions.
2. Regenerate the Azure Storage keys that are NOT CURRENTLY BEING USED by the live service and update the following settings with it. NOTE: There are multiple storage accounts (Primary, Backup and optionally Diagnostics). All storage account keys should be refreshed like this.

### Deploy the package
1. Click on the cloud service
2. Click "Staging" at the top
3. Click "Update" at the bottom
4. Upload/Select from blob storage the CSCFG and CSPKG files produced by building the solution
5. Select "ALL" roles and check all the checkboxes
6. Enter a meaningful name for the deployment (i.e. "Oct14 @ 1529 (deadbeef21)", where deadbeef21 is the commit hash of the build being used)
7. GO!
8. Once deployment completes, verify the staging URL
9. If the staging URL checks out, VIP Swap!
10. Repeat steps 1-7 to deploy the same code to the Staging slot so you can easily make configuration changes and VIP Swap to reduce downtime.
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
# Deploying the NuGet Gallery to Windows Azure Websites
# Deploying the NuGet Gallery

## Setting up resources
To run the NuGet Gallery on Windows Azure Websites you need to provision the following Azure resources:
To run the NuGet Gallery you need to provision the following common resources:

1. An Azure Website running .Net 4.5 to run the gallery frontend
2. An Azure SQL Database (preferably in a dedicated Azure SQL Server) to hold the package metadata
3. An Azure Storage account to hold package files, diagnostics data, etc.
4. [Optional] An Azure Cloud Service to run the gallery backend worker
5. [Optional] An Azure Cloud Service to provide SSL Forwarding and Traffic Management to the gallery frontend
1. An SQL Database to hold the package metadata.
2. A location in which to store package files. The Gallery supports two at the moment: Local File System and Azure Storage Account.
3. A Web Frontend to host the Gallery.
4. (Optional) A Worker Backend to perform offline processing tasks.

It is assumed you know how to provision these resources. This guide will describe how to deploy the components to them once created.
## Deploying to Azure

## Deploying the Database
There's not much that needs to be done here. First, create a SQL Azure database (preferably in a dedicated SQL Azure server). In this example, we'll use "NuGetGallery" as the name. First, create the database in the Azure portal.
We suggest using Windows Azure for hosting the gallery, as that is the environment used by http://www.nuget.org itself. When doing so, we suggest using Azure SQL Databases (formerly SQL Azure) for the database and Azure Storage Accounts to store package files.

![Creating the Database](01-CreateDB.png)
We support two profiles of Azure deployment: [Azure Websites](Websites) and [Azure Cloud Services](CloudServices). Before using those guides, however, you need to ensure you provisiong the supporting resources (Database, Storage, etc.).

## Provisioning for Azure

### Provisioning a Database

We recommend provisioning a dedicated Azure SQL Databases Server for the Gallery. If you are going to use our backend worker to generate statistics reports from data in a NuGet Warehouse, we recommend provisioning a separate Server for that database in production (the Warehouse may be co-located with the Gallery database if necessary though, and we do co-locate them in our non-production environments).

So, first create a database:

![Creating the Database](images/01-CreateDB.png)

Next, we need to create a user for the site to use. Open the **server** in the Azure Portal and click on the URL under `Manage URL`

![Manage URL](02-ManageUrl.png)
![Manage URL](images/02-ManageUrl.png)

Type "master" in the database field and log in using the SA password for the server (which you should have copied down when you created the server ;)).

Expand Down Expand Up @@ -46,7 +53,7 @@ If you used a different site username, use it in place of 'nuget-site' in the sc

Now, log off the management portal and switch to VS. Open the NuGetGallery solution and expand the "Package Manager Console" tool window:

![Package Manager Console](03-PackageManagerConsole.png)
![Package Manager Console](images/03-PackageManagerConsole.png)

Craft your connection string using notepad or some other text editor. You want it to take the following form:

Expand All @@ -64,48 +71,35 @@ Update-Database -ConnectionString "[ConnectionString]" -ConnectionProviderName S

Replacing '[ConnectionString]' with the connection string you just crafted. The command should succeed and you should have a fully prepared database!

## Setting up configuration
### Provisioning Storage Accounts
We also recommend the following Storage Accounts for each environment you intend to deploy (i.e. development, test, production, etc):

1. A Primary Storage account to hold package files and other supporting content.
2. A Backup Storage account to hold package and database backups in case the primary storage account is lost.
3. A Diagnostics Storage account to hold logs and other data. In non-production environments, we recommend using the Primary storage account to hold this data. In production, however, your traffic may be large enough that you may wish to move diagnostics data (Web Server logs, etc.) to a separate storage account

### Gathering configuration
Now that you've got the database ready, all the resources are ready for you to deploy the site. First, though, we need to configure the Website so that it will be able to talk to the database and storage when it is deployed. To do this, go to the website in the Azure Portal and select the Configure tab.

Craft a connection string using the 'nuget-site' user you created earlier (by taking the connection string above and replacing sa and '[sapassword]' with the username/password for that user). Then, in the portal, add the database connection string like so:

![Adding Connection String](04-ConnectionString.png)
![Adding Connection String](images/04-ConnectionString.png)

Then, go to the storage account you created in the portal and select "Manage Keys". Use the name and primary key on that page to build a connection string like this:

```
DefaultEndpointsProtocol=https;AccountName=[account name];AccountKey=[primary key];
```

Using that connection string, go back to the Configure tab of the website and set the AppSettings as shown below:

![Adding App Settings](05-AppSettings.png)

Replace '[site url]' with the URL you intend to use as the root of your site, and for the storage connection string, use the string you crafted before. The GalleryOwner setting is a standard email name in the form "Display Name <emailaddress>". If you intend to use SSL, you can set RequireSSL to true, but you should probably wait until you get it up and running before doing that.

Save the changes and get ready to deploy!

## Deploying the frontend
Go back to the dashboard tab and set up deployment from source control. Assuming you cloned this repo from Git, you probably want to choose "Local Git Repository". That is the case we will cover here.

Once you complete this wizard, you'll need to set up deployment credentials. I'll assume you've got that under control ;). Go to the gallery and checkout the branch you want to deploy (say 'master'):

```
git checkout master
```

Add Azure as remote and push that branch up!

```
git remote add azure [git url]
git push azure master
```
Now that you have your dependent resources and their configuration, move on to...

NOTE: If you don't use master, make sure to update the "Branch to Deploy" setting in the Configure tab.
## Deploying the Frontend/Backend
Once you've provisioned these resources, continue to the guide for deploying to the profile of your choice:

After pushing, the site will build, which may take a while. Once finished, just browse to the site and it should start up! The first request may take quite a while, so be prepared to wait a few minutes.
1. [Azure Cloud Services](CloudServices/README.md) - Recommended for extremely high availability services
2. [Azure Websites](Websites/README.md) - Recommended for simple deployment scenarios

Now that you've got the site up, try registering a user and uploading a package!
We do not currently recommend Azure Websites for extremely high availability deployments of the Gallery. Other Azure features for traffic management, such as Azure Traffic Manager, do not support Azure Websites at this time. Also, Azure Websites does not provide the Production/Staging VIP Swap mechanism used in Cloud Services to allow for staging of production changes.

## Making an Admin
Once you've got your gallery deployed, you probably want an admin user. That's pretty easy to do. First, register your admin user through the site. Then log in to the database using the Azure SQL Management Portal and the 'nuget-site' user (as we did above). Then run this SQL:
Expand All @@ -122,4 +116,4 @@ SELECT @userId = [Key] FROM Users where Username = 'username'
INSERT INTO UserRoles(UserKey, RoleKey) VALUES(@userId, @adminId)
```

Replacing 'username' with the name of the user you just created. Now log out and back in with that user and you should see the Admin tab! **NOTE** The name of the role is important, it is "Admins" (plural!).
Replacing 'username' with the name of the user you just created. Now log out and back in with that user and you should see the Admin tab! **NOTE** The name of the role is important, it is "Admins" (plural!).
46 changes: 46 additions & 0 deletions docs/Deploying/Websites/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Deploying the NuGet Gallery to Windows Azure Websites

## Setting up resources
To run the NuGet Gallery on Windows Azure Websites you need to provision the following Azure resources:

1. An Azure Website running .Net 4.5 to run the gallery frontend
2. An Azure SQL Database (preferably in a dedicated Azure SQL Server) to hold the package metadata
3. An Azure Storage account to hold package files, diagnostics data, etc.
4. [Optional] An Azure Cloud Service to run the gallery backend worker
5. [Optional] An Azure Cloud Service to provide SSL Forwarding and Traffic Management to the gallery frontend

It is assumed you've already provisioned the SQL Database and Storage Account using the [main guide](../README.md).

## Provisioning the Frontend
Create an Azure Website and configure it for deployment however you choose (Git deployment, FTP, etc.).

Using the connection strings you received while provisioning resources for the site (SQL DB, Azure Storage, etc.), go to the Configure tab of the website and set the AppSettings. To determine what to set, open the [src\NuGetGallery\Web.config](..\..\..\src\NuGetGallery\Web.config) file up and use the comments in the AppSettings section to assist you.

Save the changes and get ready to deploy!

## Deploying the Frontend with Git
(If you want to use a different deployment mechanism, you're on your own :))

Go back to the dashboard tab and set up deployment from source control. Assuming you cloned this repo from Git, you probably want to choose "Local Git Repository". That is the case we will cover here.

Once you complete this wizard, you'll need to set up deployment credentials. I'll assume you've got that under control ;). Go to the gallery and checkout the branch you want to deploy (say 'master'):

```
git checkout master
```

Add Azure as remote and push that branch up!

```
git remote add azure [git url]
git push azure master
```

NOTE: If you don't use master, make sure to update the "Branch to Deploy" setting in the Configure tab.

After pushing, the site will build, which may take a while. Once finished, just browse to the site and it should start up! The first request may take quite a while, so be prepared to wait a few minutes.

Now that you've got the site up, try registering a user and uploading a package!

## Deploying the backend
TODO.
File renamed without changes
File renamed without changes
57 changes: 35 additions & 22 deletions src/NuGetGallery/Web.config
Original file line number Diff line number Diff line change
Expand Up @@ -19,46 +19,59 @@
<section name="glimpse" type="Glimpse.Core.Configuration.Section, Glimpse.Core" />
</configSections>
<appSettings>
<!-- ASP.Net settings -->
<add key="webpages:Version" value="2.0.0.0" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<!-- If you're running in Azure, we suggest you set these in your .cscfg file. -->

<!-- ******************* -->
<!-- DEPLOYMENT SPECIFIC -->
<!-- ******************* -->
<!-- These should change on every deployment (to rotate credentials, etc.) -->
<add key="Gallery.AzureStorageConnectionString" value="" /> <!-- The connection string for the Azure Storage Account used for Package Storage IF Gallery.StorageType is AzureStorage -->


<!-- ******************** -->
<!-- ENVIRONMENT SPECIFIC -->
<!-- ******************** -->
<!-- These only need to change when defining a new environment -->
<!-- development only key, override on live site -->
<add key="Gallery.Environment" value="Development" />
<add key="Gallery.FacebookAppId" value="" /> <!-- Set this if you have a Facebook App ID you want to use for the Like button -->
<add key="Gallery.GoogleAnalyticsPropertyId" value="" /> <!-- Set this if you have a Google Analytics property for the site -->
<add key="Gallery.AzureCdnHost" value="" /> <!-- Set this to the Azure CDN Host you are using for blob storage, if you have configured one -->
<add key="Gallery.SiteRoot" value="http://nuget.localtest.me/" />
<add key="reCAPTCHA::PrivateKey" value="6LcebdwSAAAAAI5dI90LpPMFGKDxdCt6fjwEwMut" />
<add key="reCAPTCHA::PublicKey" value="6LcebdwSAAAAAFI06sH9RRb2VP1HFCjYpg74lKG7" />

<add key="Gallery.ReleaseBranch" value="dev" />
<add key="Gallery.ReleaseName" value="" />
<add key="Gallery.ReleaseSha" value="123abc" />
<add key="Gallery.ReleaseTime" value="2013-03-20 15:07:41 " />
<!-- *************** -->
<!-- STABLE SETTINGS -->
<!-- *************** -->
<!-- Depending on your policy, these likely do not need to vary -->

<!-- Gallery Settings. See IAppConfiguration -->
<!-- If you're running in Azure, we suggest you set these in your .cscfg file. -->

<!-- Use these settings for local non-SSL testing -->
<add key="Gallery.RequireSSL" value="false" />
<!-- Use these settings for local SSL testing (configure it in VS first) -->
<!--<add key="Gallery.Require" value="true" />
<add key="Gallery.SSLPort" value="44300" /> -->
<!-- VS usually uses "44300" as the port. If that's taken, it uses "44301", "44302", and so on. -->

<!-- SmtpUri is expected to be of the format: smtps://username:password@host:port. Note that if username contains an "@", you need to URI Encode it! -->
<add key="Gallery.SmtpUri" value="" />
<!--
Location for the Lucene Index.
AppData -> ~/App_Data/Lucene,
Temp -> [Path.GetTempPath()]/NuGetGallery/Lucene,
-->
<add key="Gallery.LuceneIndexLocation" value="AppData" />

<add key="Gallery.Environment" value="Development" />
<add key="Gallery.SiteRoot" value="http://nuget.org/" />
<add key="Gallery.RequireSSL" value="false" />
<add key="Gallery.GalleryOwner" value="NuGet Gallery &lt;nugetgallery@outercurve.org&gt;" />
<add key="Gallery.ConfirmEmailAddresses" value="true" />

<!-- Set this to true if there is a backend worker based on NuGetGallery.Backend. This disables background tasks in the Website -->
<add key="Gallery.HasWorker" value="false" />

<!-- Feature Configuration -->
<add key="Feature.FriendlyLicenses" value="false" />

<!-- ***************** -->
<!-- ASP.Net settings. -->
<!-- ***************** -->
<!-- These should never need to be changed -->
<add key="webpages:Version" value="2.0.0.0" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<connectionStrings>
<add name="Gallery.SqlServer" connectionString="Data Source=(LocalDB)\v11.0;Initial Catalog=NuGetGallery;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
Expand Down

0 comments on commit 1a26ca4

Please sign in to comment.