Category Archives: Tools

SQL in the City London

I had a wonderful time attending SQL in the City London.  It’s really great to see the new versions of the tools and exchange new ideas with friends.  Towards full disclosure, I’ve been a Friend of Red Gate for as long as I can remember, and also spoke at SQL in the City last year in both Austin and Seattle.  This year was a new format: leading attendees through a focused journey of continuous integration and deployment together in one large room.  It worked well.

There was also a small off-track room seating about 20 to 40 down a winding hallway, though with such a large attendee base, there was usually no room.  It did help us focus on the main event, but it did remove some of the free-flowing discussion that only a small group can bring.

The opening discussion was pretty much a spot-on repeat of last year.  We did the deployment balloon game, and successfully deployed only one of our 5 or 8 groups of balloons.  It’s a wonderful object lesson, though having seen the example and corresponding slides last year, it didn’t really grab my attention.  My fellow attendees seemed to enjoy the presentation — a wonderful reserved optimism that speaks volumes of the glorious British culture.  Breaks between classes helped us absorb the material and yielded great discussions.  We also queued very well for afternoon tea.  There wasn’t much space in the venue to hold us when we weren’t sitting down, so the displays and conversation areas were loud and cramped, and most of us either spilled out of the building or back into our seats.  “A Day in the Life of a DBA” concluded the day, and seemed like it could’ve been a wonderful discussion.  Alas, I quickly zoned out as it turned into a gripe session about everything DBAs hate about developers, networks, management, users, life, and why getting woken up is not fun.  All else being equal, I wish I had fit in the smaller room.

I’m really enjoying how the tools are maturing and coming together into a great suite, targeted nicely both towards on-premise use and cloud deployments, both tools to facilitate developers and tools to facilitate IT pros.  David Atkinson did a wonderful demo of continuous integration using the Team City plugin that drives SQL Compare, SQL Data Compare, SQL Docs, other tools, and in short order, database migrations.  Justin Caldicott and Grant Fritchey did a wonderful back-n-forth demo — from both developer’s and IT’s perspective — of the challenges of deployment and how Deployment Manager really saves the day.

Deployment Manager is struggling because it’s one of the few Red Gate tools that requires you accept their paradigm rather than fitting into a niche inside your process.  (SQL Compare, SQL Data Compare, SQL Monitor, .NET Reflector, ANTS Profiler, and even to a lesser extent SQL Source Control all get plugged into an existing workflow with ease.  Deployment Manager really needs to own the deployment process.  This is especially difficult to swallow since the IT Pro’s bread and butter is to ensure deployment is seamless, painless, and exact.  Like any good DBA, they get very OCD about it.  Deployment Manager asks the business to “trust us, we’ll do the right thing.”  Automation is wonderful, but black boxes scare people.  Deployment Manager seeks to walk this fine line, and does a descent job, but it is a very hard sell.  Alas, I digress.

I got tapped with only a few moments notice to lead a group discussion about Database Migrations — a topic I’m quite passionate about.  Of the 3 groups of 20-or-so, I chose the biggest challenge — the group that didn’t own any Red Gate tools.  We quickly got the standard gripe out of the way: the tools are expensive, and then we began exploring both the challenges of Database Migrations and the solutions that we were proposing.  (It was fun getting to use the royal “we” to discuss Red Gate for a few minutes.)  The methodology proposed seems very solid, and I’m really excited to see how they execute on this vision.  In a true continuous deployment system where the build server fully owns deploying all assets (web sites, command lines, services, GUI tools, and databases) the lynch pin to completely avoiding babysitting it is Database Migrations.  I’m really excited to see this product come to life.  The group seemed very receptive, and some said they’d give SQL Source Control a try.  (SQL Source Control is a great gateway drug into the Red Gate toolchest.)

SQL in the City is a wonderful event, and I really enjoyed attending again this year.  I’d highly recommend the free day of training and insight into Red Gate tools, and wish only that there were more of them in cities closer to me.  Many thank yous to Annabel and her team who went above and beyond to make this even a wonderful success.  Well done.

IIS Web Server Best Practices

Best practices I use when setting up IIS:

– Each site should be a separate (sub-)domain.  Thus http://somesite.mycompany.com/ instead of http://www.mycompany.com/somesite/  This solves a few problems: “../../don’t/do/this.jpg” is avoided when you can presume the root of your site is “/”, which means you can avoid relative paths (even if you need not crawl up a directory) and you can avoid the ~.  It’s much cleaner all the way around.

– Because each site is its own (sub-)domain, you also avoid the pitfall of virtual directories.  A virtual directory is an app within an app.  (http://www.mycompany.com/otherapp/) and some changes to the outer app cascade into the inner app.  For example url rewrite rules, authentication, dll mapping, etc.  Basically the system starts at your app’s directory’s web.config, crawls up the folder stack layering behind every web.config it finds, layers behind that the web.config in the framework directory, and finally machine.config.  This is why you need not copy every changes in your regular web.config into the web.config in the Views folder in MVC.  Because a virtual directory is by definition an app inside another app, of necessity you’ll inherit the outer app’s web.config, potentially negatively impacting your app as their app evolves.

– The app pool is the execution space, so, each site should have its own.  That doesn’t completely protect you from another site blowing up your site, but it does help considerably.  Especially if a technician needs to recycle the app pool as part of an app upgrade or if only one site on the machine is having troubles.

– If you consistently change things on all sites like removing headers, configuring additional mime-types, rearranging or removing default document names, setting the error pages, etc, do these on the machine node in IIS rather than redundantly for each site.

ASafaWeb.com is a great tool for highlighting configuration errors and places where you’re exposing more information than necessary.

– Make sure you handle the “naked domain” (zone apex).  Mapping to www.mysite.com is important, but users could just as easily hit mysite.com (without the www) and if your site doesn’t handle both, a consistent portion of your users will consider your site “broken”.  For SEO purposes, permanently redirect one to the other.  (Which you choose is likely a matter of corporate culture or preference, and ultimately is irrelevant … provided you consistently choose it in IIS configurations, Google Webmaster Tools, etc.)

– If at all possible, run the apps in the most recent framework version, in “Integrated” mode, with 32-bit disabled, with modern .net frameworks installed on the box, and all Windows Updates.  Ideally you’ll also be on the most modern OS version too.  Your apps may need code changes to make this possible.  These are the defaults with new installs and are promoted as “modern techniques” [read: best practices], and ensuring your apps are compliant suggests future deployments to similar or newer hardware or OSs will be less traumatic.

– c:\inetpub\wwwroot\myapp is a very awful place to put your web site folder.  Because this is the default, if I’m a hacker trying to compromise your site and I find another way into your box (FTP, RDP, network share, etc) I can stick something in all such folders and compromise every site on the box.  Script kiddies have automated attack tools that can do this.  Instead, I create a folder like C:\Internet\ or C:\Websites\ or similar.  Inside, I have a folder for each site with sub-folders for:

  • db
  • logs
  • www

I’ll then put the IIS website content in the www folder, point IIS to put the site’s logs into the logs folder, (Ever crawl through IIS’s default log folder trying to figure out which log folder you want?  I’m sorry, “W3SVC6” is not sufficiently descriptive.) and if SQL Server is on the same machine (not best practice), point it to put the mdf and ldf files into the database folder.  Now when you want to backup “everything”, just stop IIS, stop SQL, and copy C:\Internet.  You got “everything” for all sites on the box (with the exception of C:\Windows\System32\inetsrv\config\applicationHost.config which you should also backup periodically.)

– applicationHost.config is not scary.  It’s the “Metabase” (using IIS 6’s term) and is just an xml file.  From time to time, IIS’s GUI has a wacky limitation or I want at it faster than that, so I just pop open C:\Windows\System32\inetsrv\config\applicationHost.config using an elevated notepad and hack away.  Want to setup the second server in the farm to exactly match the first?  Install IIS, install all the plugins you need via Web Platform Installer, run windows update a few times, then use Beyond Compare or WinMerge to diff old box’s applicationHost.config to new box’s, and copy across.  Ta-da!  Instant second box.  (BTW, don’t copy over the “encryption key” lines nor module or handler lines for plugins you didn’t install, and make careful backups before changing this file.  Either that, or you can get good at reformatting boxes.  I needed only make that mistake once.  :D)  Of particular interest in applicationHost.config is the <sites> node.

– One of the big challenges with IIS is “who owns the site’s web.config: The IT dept or developers?”  This is because site-specific changes made in IIS are stored in the app’s web.config.  (This is also why php and node apps hosted on windows have a web.config file even though they don’t use .net.) Alter the list of default documents or change the authentication scheme, and it’ll write these nodes into web.config.  On next deploy if you flush and reset everything — including web.config — you’ll remove these settings.  Oops.  (Also see the “if you do it on every site, do it to the box not to each site” note above.)

– The remote management service is incredibly cool.  http://www.iis.net/learn/manage/remote-administration/remote-administration-for-iis-manager  Typically the only reason we RDP to the IIS machine is to use IIS Manager, run windows updates, or figure out why it ran out of hard drive space.  It is an increased attack surface to have the management service on, so perhaps configure the firewall to only expose port 8172 (or the one you configure) to the LAN and not to the public.  Now no more RDPing for config changes.

I’m confident this is hardly an exhaustive list, but based on these, you can get to a pretty good place in IIS, and probably get the Google-fu cranked up too.  Happy hosting!

Rob

Git on-premise hosting

All else being equal, you should use GitHub (http://www.github.com/) for Git hosting.  GitHub is indeed a cloud-hosted git repository, but it’s so much more than that.  It has integrated issue tracking, comment on any line of any commit (social coding), and pull request (e.g. “will you please review and pull my content”).  It’s truly a revolution in source control, and there’s really nothing like it.

If you’re forced into an on-premise solution, the natural draw is to facilitate “Git Smart HTTP” in IIS.  Git has native Apache bindings, but doesn’t have anything native for IIS, so there’s a plethora of home-grown answers.  The field is ripe for someone like Visual SVN to come through and make a good, GUI-driven Git webhost, though even Visual SVN is technically Apache.  You can use Git without http hosting as well (same as with SVN), though http hosted git servers are cool.  :D

I use WebGit.NET: https://github.com/otac0n/WebGitNet/wiki/Getting-Started  It has no built-in authentication, but none of these really do.  http://serverfault.com/questions/369573/what-iis-authentication-method-to-use-with-git-server-hosted-on-iis has some descent ideas on how to secure it, but all add weight to each repository access operation.  I chose instead to only bind to 127.0.0.1, so you’d need to be physically on my machine to get to the site, and if you’re that far, you may as well be in my repository.  You could do something similar by exposing it only to the LAN (and by extension VPN users).

If I was to do it again, I’d investigate kudu: http://blog.davidebbo.com/2012/06/introducing-open-source-engine-behind.html and http://blog.davidebbo.com/2012/06/developing-kudu-locally-and-on-azure.html  It’s what Microsoft built for Azure git deployment.  But as part of that, it has a git web engine that may be useful separately.  It has one IIS site for administration, and a second for repository access.  That’s a bit weird, but it does mean you can secure them separately.

Other popular IIS-hosted Git solutions include:

– GitWebAccess: http://gitweb.codeplex.com/  I used this one for a time.

– GitDotNet: http://www.jeremyskinner.co.uk/2010/06/25/hosting-a-git-server-under-iis7-on-windows/  The author recommends against his solution.

– GitAspx: http://www.jeremyskinner.co.uk/2010/10/19/gitaspx-0-3-available/

– Bonobo: http://www.chodounsky.net/bonobo-git-server/  I recall looking at it early on, but don’t recall why I didn’t like it.  Perhaps it’s due a second look.

– GitStack: http://gitstack.com/gitstack-and-other-web-servers/  If I remember correctly, this is a paid installer of some cobbled open-source tools.

– SCM Manager: http://www.helicontech.com/articles/hosting-git-svn-and-hg-mercurial-repositories-on-windows-with-iis/  It does SVN, Mercurial, and Git as a Java website.

http://stackoverflow.com/questions/51619/how-to-setup-git-bare-http-available-repository-on-iis-machine includes some more.

Rob

Git Tools for Windows

I get asked from time to time what tools I would install to use Git on Windows.  I randomly spout off a list that looks something like this.  In time, this list grew to something bigger than just a list.  It seems natural for it to evolve into a post.  In no particular order, here are installers for getting Git running on both/either client and server.  (Granted, the philosophical discussion of “client” and “server” are not technically relevant in distributed source control systems as everything is technically both, but it’s good to designate one of the “clients” as a “server” by policy so there’s a “canonical truth” all can go to for the latest official copy.)

Client tools:

Needed:
– mSysGit (http://code.google.com/p/msysgit/) is the base engine, and is needed to do anything git related.  Most other tools presume this is installed.  The CygWin route is a trap.  I install with these options:
   – Run Git from the Windows Command Prompt (middle option)
   – Checkout Windows-style, commit Unix-style
   – Use OpenSSH (unless you’ve previously installed Putty, you don’t need it for Git with this option)
– Git Extensions (http://code.google.com/p/gitextensions/) is GUI tools for both Explorer and Visual Studio (and Eclipse and a few other things). Includes kdiff3, a diff tool for Windows.  Ensure you choose the same options you did for mSysGit.  (Note that by default mSysGit says “OpenSSH” and Git Extensions says “TortoisePlink”.)

Optional:
– git-flow (https://github.com/nvie/gitflow/wiki/Windows) is a great workflow for git
– TortoiseGit provides icon overlays in Windows Explorer but their commit dialog “simplifies” the difference between push and commit making it absolutely useless aside from the icon overlays
– Git Source Control Provider (http://gitscc.codeplex.com/) provides icon overlays in Visual Studio

Alternatives:
– SmartGit (http://www.syntevo.com/smartgit/index.html): “smartgit” is also a protocol, making this a confusing name, client also does hg and svn
– GitHub for Windows: “simplifies” git for Windows users — that sounds like the buzz word for “doesn’t quite do it right”, I have no experience with it.

Server tools:

file urls (not preferred, only works on a lan, e.g. \serverfoldergitrepo):
– mSysGit
– share the git repository on a file share


http(s):// protocol (pick one):
– (prefered) WebGit.NET (https://github.com/otac0n/WebGitNet/wiki/Getting-Started)
– Azure’s http git server (https://github.com/projectkudu/kudu/): If only I had another 854 hours in the day, I’d get this running and make it the preferred mechanism. It is the newest and best supported of the bunch.
– Bonobo (http://www.chodounsky.net/bonobo-git-server/): It’s abandon-ware and didn’t have many features.
– GitWebAccess (http://gitweb.codeplex.com/): The website is great for configuring http access to git, but the admin interface has no authentication. Thus anyone with a web browser can reconfigure my server. Oops.
– GitStack (http://gitstack.com/): It runs on Apache, the rest of these run on IIS. Granted one can proxy Apache behind IIS: http://blog.endjin.com/2010/11/a-step-by-step-guide-to-hosting-teamcity-in-iis-7/.

git:// protocol (basically ssh://):
Guides: (follow them all — more-or-less)
http://www.codeproject.com/Articles/296398/Step-by-Step-Setup-Git-Server-on-Windows-with-CopS
http://www.timdavis.com.au/git/setting-up-a-msysgit-server-with-copssh-on-windows/
Theory:
– expose mSysGit over CopSSH daemon
– GitExtensions and Putty aren’t needed server-side, but may make debugging easier
– CopSSH is OpenSSHD compiled for Windows, doesn’t need cygwin, daemon is built-in, can be configured for user/pass or preshared keys
– point this to the same Git repositories hosted in http(s) above and now it works both ways
Alternatives:

http://windowsgit.com/ does this setup for you, purchase for 14 euro, docs are very thin, probably better to do it yourself to learn more about what’s going on under the hood.

alternatives / hosted providers:
Most of these providers host open-source projects for free, and closed-source projects for a price, and include both https:// and git://
– GitHub (https://github.com/)
– BitBucket
– CodePlex
– Pretty much any source code hosting provider

IIS Express /protocol:https

IIS Express is awesome, a great upgrade from Cassini.  It supports https, Windows Authentication, persistent sites even if Visual Studio is closed, command-line launching, it’s great.  However combining them sometimes doesn’t work too well.

In Cassini (Visual Web Developer) I could launch it like this:

WebDev.WebServer40.EXE /port:1234 /path:C:pathtosite

This works wonderfully in IIS Express as well:

iisexpress.exe /port:1234 /path:C:pathtosite

This gets awkward when moving to https.  This doesn’t work:

iisexpress.exe /port:1234 /path:C:pathtosite /protocol:https

Why doesn’t it work?  Because iisexpress has no /protocol switch.  Bummer.  I flung a request for this and got a great response from Robert McMurray.

A Step Back

Robert McMurray summarizes the two modes of IIS Express nicely as “Personal Web Server Mode” (e.g. “IIS Lite”) and “Application Server Mode” (e.g. “just launch this”).

“Personal Web Server Mode” is a durable version of (almost all of) IIS launched in the user’s context.  There’s a great system tray icon that centralizes all the running sites, and the applicationHost.config file is identical to regular IIS.  One can rig Windows Authentication, HTTPS, tracing, classic ASP, the works.  (Why “almost”?  Because there’s no tooling for configuration.  There are a few settings in Visual Studio, but nothing of consequence.  The perfect solution would be a way to point IIS Manager at it.  Unfortunately, typically the easiest way to configure IIS Express is to configure IIS proper, then diff their config files.  But I digress.)

“Application Server Mode” is much like Cassini was.  When you launch it, you specify /port: and /path:.  The unfortunate part of this mode is it presumes http.  To their credit, this mode is likely solely for backwards compatibility with Cassini, and Cassini didn’t support https at all.

Now What?

My goal is to run IIS Express in “just do it” mode, pass in a /port: and /path:, and test my https site.  All else being equal, a /protocol: parameter to iisexpress.exe would be easiest.  In its absence, let’s go hacking.  Back to Robert McMurray.  He proposes a batch file that uses appcmd.exe to rig adjustments to a cloned applicationHost.config, passing in IIS Express 8’s new /apphostconfig: flag, which specifies the config to modify.  It’s a bit of a long way around, but ok.  In theory it’s easier than brute-forcing some XPath.

A bit of tinkering, a lot of elbow grease, and an extra quarter or two into the command-line meter, and I have a batch file that allows me to launch IIS Express like this:

iisexpress.bat /port:1234 /path:C:pathtosite /protocol:https

The batch file takes care of shimming the difference between me using it like “Application Server Mode” and it running in “Personal Web Server Mode” (with a temporary config).  Thanks to Robert McMurray for pointing me in the right direction.

For compatibility’s sake, it has a PowerShell XPath mechanism for users of IIS Express 7.x, though for those with IIS Express 8, flip over into appcmd and you’re golden.

The Batch File

@echo off

setlocal enabledelayedexpansion
pushd “%~dp0”



REM because we’re shifting this off the grid soon

set script_name=%0



if ‘%1’==” GOTO help



:defaults

set site_port=8080

set site_protocol=http





:get_args

if ‘%1’==” GOTO :args_done



set arg=”%1″

set argv=%arg:/path:=%

if “%argv%”==”%arg%” goto not_path



set site_path=%argv:”=%

shift

goto get_args



:not_path



set argv=%arg:/port:=%

if “%argv%”==”%arg%” goto not_port



set site_port=%argv:”=%

shift

goto get_args



:not_port



set argv=%arg:/protocol:=%

if “%argv%”==”%arg%” goto not_https



set site_protocol=%argv:”=%

shift

goto get_args



:not_https



if ‘%1’==’/?’ GOTO help

if ‘%1’==’/h’ GOTO help

if ‘%1’==’-?’ GOTO help

if ‘%1’==’-h’ GOTO help



echo Invalid parameter: %1

goto help





:args_done





if “%site_path%”==”” GOTO no_path

if “%site_port%”==”” GOTO no_port

if not exist “%site_path%” GOTO invalid_path





:get_tempdir



set sitename=%TIME::=.%-%RANDOM%

set tempdir=%TEMP%iisexpress-temp%sitename%

if exist “%tempdir%” GOTO :get_tempdir

mkdir “%tempdir%”





:get_iisdir



if “%PROGRAMFILES(x86)%”==”” goto x86

set iis_dir=%PROGRAMFILES(x86)%IIS Express

goto iis_done

:x86

set iis_dir=%PROGRAMFILES%IIS Express

:iis_done

if not exist “%iis_dir%iisexpress.exe” GOTO iis_missing





:setup_iis



copy “%iis_dir%AppServerapplicationHost.config” “%tempdir%”



REM Mangle ‘Development Web Site’ to match what we’re after



REM These need IIS Express 8:

REM “%iis_dir%appcmd.exe” set config -section:system.applicationHost/sites /”[name=’Development Web Site’].[path=’/’].[path=’/’].physicalPath:%site_path%” /commit:apphost /apphostconfig:%tempdir%applicationHost.config

REM “%iis_dir%appcmd.exe” set config -section:system.applicationHost/sites /~”[name=’Development Web Site’].bindings” /commit:apphost /apphostconfig:%tempdir%applicationHost.config

REM “%iis_dir%appcmd.exe” set config -section:system.applicationHost/sites /+”[name=’Development Web Site’].bindings.[protocol=’%site_protocol%’,bindingInformation=’127.0.0.1:%site_port%:’]” /commit:apphost /apphostconfig:%tempdir%applicationHost.config

REM This doesn’t

Powershell.exe -Command “& {$a=New-Object System.Xml.XmlDocument;$a.Load(“%tempdir%applicationHost.config”);$b=$a.SelectSingleNode(“//sites/site[@id=’1′]//virtualDirectory”);$b.physicalPath=”%site_path%”;$c=$a.SelectSingleNode(“//sites/site[@id=’1′]//binding”);$c.protocol=”%site_protocol%”;$c.bindingInformation=”:%site_port%:localhost”;$a.Save(“%tempdir%applicationHost.config”)}”





:run_iis



echo Running IIS Express: /port:%site_port% /protocol:%site_protocol% /path:%site_path%, temp-config: %tempdir%applicationHost.config

“%iis_dir%iisexpress.exe” /config:%tempdir%applicationHost.config /siteid:1 /systray:false



 

:cleanup

 

rd /q /s %tempdir%





goto exit





:no_port

echo /port not specified

goto help



:no_path

echo /path not specified

goto help



:invalid_path

echo /path doesn’t exist: %site_path%

exit /b 2



:iis_missing

echo can’t find iisexpress.exe in %iis_dir%

exit /b 3





:help



echo %script_name% [/port:1234] [/protocol:https] “/path:C:pathtositedir”

echo default: /port:8080 /protocol:http

exit /b 1



GOTO exit



:exit



popd

endlocal



exit /b

Here’s hoping this solution works as well for you as it does for me.  Enjoy!

Rob

Moving to IIS Express and https

I’ve been asked a few times to help people move from their current use of the Web Development Server to https. This requires one also move to IIS Express as the old Web Development Server (Cassini) doesn’t support https. Here’s a brief tutorial on making the changes. This will allow you to test the sites using a very similar mechanism to a production deployment. We’ll also discuss certificates and Fiddler concerns.

Step 1: Setup

Get your environment setup:

  1. Startup Visual Studio, and load the target project and/or solution

Step 2: Configure IIS Express

For each website you’d like to convert to IIS Express and https:

  1. In the Solution Explorer, right-click on Web project, and choose “Use IIS Express” (just under “Set as Startup Project”)  NOTE: If you don’t have this option, you don’t have Visual Studio 2010 Service Pack 1 installed. Install VS 2010 SP 1 then retry this procedure.
  2. Go to the project properties by right-clicking the project, and choosing properties at the very bottom.
  3. In the Web tab, choose “Use Local IIS Web Server” and check “Use IIS Express”. Set the Project Url as necessary.
  4. Ensure “Apply server settings to all users” is unchecked. If this is checked, these changes will be inflicted on all users of the solution including any user-specific derivations (such as the location of your solution).
  5. Enable SSL by selecting the project in the Solution Explorer, switching to the Properties window, and setting “SSL Enabled: True”. You will be assigned a random port, probably localhost:44300, but you can’t change that here.

Step 3: Change IIS Express SSL Ports

  1. Close Visual Studio so it doesn’t get confused as we change IIS Express files.
  2. Open The IIS Express configuration file in your favorite text editor such as Notepad. It is in a path similar to C:Users{myusername}DocumentsIISExpressconfigapplicationhost.config
  3. Scroll down to the <sites> node.
  4. Alter the bindings lines for each of the sites to include your preferred ports.
  5. Save and close the file.

Step 4: Update the Project’s port if necessary

Back inside Visual Studio, we’ll tweak the last few things, and we’ll be ready to roll:

  1. Startup Visual Studio, and load the target project and/or solution
  2. Go into the project’s settings: Solution Explorer -> right-click on project -> Properties at the very bottom -> Web tab
  3. Update the Project Url if necessary to match the details you set in applicationhost.config

Step 5: Update configuration values

If your project uses any configuration values that reference the site url or port, you’ll need to update them to point to the new https url.

Step 6: Try it Out

We’re ready to roll:

  1. Debug the target project / solution
  2. In your browser, go to the https url you specified (example: https://localhost:44300/)

It works, but you’ll quickly discover failures because the cert isn’t trusted.

You’ll also notice that IIS Express binds specifically to “localhost:port#”, and doesn’t listen on “localhost.:port#”. (Note the dot in the second url.) Adding this dot is a great tool for debugging with fiddler as it makes the browser use DNS to resolve the site, which happily makes it use the configured proxy – Fiddler. Without this dot, it’s really easy to make web requests and get absolutely nowhere. Unfortunately, this no longer works with IIS Express. Sadly, you’ll need to remove the dot.

Step 7: Trust IIS Express Certificate in your chosen browser(s)

Unfortunately, Chrome will use the local certificate store, but has no way to alter the local certificate store, so we must use Internet Explorer to configure the certificate trust. These steps are pulled from http://stackoverflow.com/questions/681695/what-do-i-need-to-do-to-get-internet-explorer-8-to-accept-a-self-signed-certific and http://productforums.google.com/forum/#!topic/chrome/bds-Ao9LigA. The former (quoted here) shows you how to get IE (and thus .NET) to trust the self-signed certificate, the latter, targeted towards Chrome, puts the certificate in “Third-party Certificate Store” instead of “Trusted Root Certification Authorities”.

How to make IE8 trust a self-signed certificate in 20 irritating steps: (source: http://stackoverflow.com/questions/681695/what-do-i-need-to-do-to-get-internet-explorer-8-to-accept-a-self-signed-certific)

  1. Browse to the site whose certificate you want to trust.
  2. When told “There is a problem with this website’s security certificate.”, choose “Continue to this website (not recommended).”
  3. Select Tools->Internet Options.
  4. Select Security->Trusted sites->Sites.
  5. Confirm the URL matches, and click “Add” then “Close”.
  6. Close the “Internet Options” dialog box with either “OK” or “Cancel”.
  7. Refresh the current page.
  8. When told “There is a problem with this website’s security certificate.”, choose “Continue to this website (not recommended).”
  9. Click on “Certificate Error” at the right of the address bar and select “View certificates”.
  10. Click on “Install Certificate…”, then in the wizard, click “Next”.
  11. On the next page select “Place all certificates in the following store”.
  12. Click “Browse”, select “Trusted Root Certification Authorities”, and click “OK”.
  13. Back in the wizard, click “Next”, then “Finish”.
  14. If you get a “Security Warning” message box, click “Yes”.
  15. Dismiss the message box with “OK”.
  16. Select Tools->Internet Options.
  17. Select Security->Trusted sites->Sites.
  18. Select the URL you just added, click “Remove”, then “Close”.
  19. Now shut down all running instances of IE, and start up IE again.
  20. The site’s certificate should now be trusted.

After this procedure is done, Chrome will note that the url is “localhost”, that it isn’t routable across the internet, and thus it is impossible for a trusted certificate store to issue such a certificate. It will also note that the certificate’s domain and page’s domain match, and will no longer prompt you to “proceed anyway”.

Step 8: (Optional, Advanced) Use IIS instead of IIS Express

Getting IIS Express to start when you begin debugging and stop when you end debugging is very, very handy. But there are times when you’ll want to use the site but don’t want to have to launch Visual Studio first – e.g. to demo the project to a potential client. In that case, you can use the full IIS 7.5 installed in Windows instead of IIS Express with these modifications:

Configure the project to use IIS:

  1. Right-click on the project in Visual Studio, choose properties, switch to the Web tab, and uncheck “Use IIS Express”.
  2. Change the Project Url to use your chosen IIS url.

Install IIS 7.5 on Windows 7 (if it isn’t there already):

  1. Start -> Control Panels.
  2. On the left, choose “Turn Windows Features on or off”.
  3. Inside Internet Information Services, inside Web Management Tools, check on IIS Management Console.
  4. Inside Internet Information Services, inside World Wide Web Services, check on at least ASP and ASP.NET.
  5. Troll through the other settings inside Internet Information Services, checking on anything that looks interesting.
  6. Ensure WebDAV is /NOT/ installed: Internet Information Services -> World Wide Web Services -> Common HTTP Features -> WebDAV Publishing to off. You likely don’t need it, and it’s a great security hole.
  7. Ensure FTP is /NOT/ installed: Internet Information Services -> FTP must be off. Same thing, reduce the attack service.

Configure IIS:

  1. Start -> Administrative Tools -> Internet Information Services. NOTE: If you don’t have this option, you need to first install IIS.
  2. Right click on Sites, and choose Add Website.
  3. Add the website details.
  4. Click Application Pools, and ensure the app pool settings are appropriate to your use.
  5. If any of the settings for the App Pool aren’t as specified, choose the app pool, click “Basic Settings…” on the right, and alter as needed.

Sql Source Control from SSMS to Working Directory

I use Sql Source Control in an unconventional way: I want to commit both sql scripts and code at once.  This means the CI server builds once with both sides.  This works very well if I can commit from Explorer using Tortoise.  It doesn’t work so well when I commit from inside Visual Studio or from inside Sql Management Studio via Sql Source Control.

Sql Source Control is basically Sql Compare between the database in Sql Server and something else, but built into Sql Management Studio — a very excellent workflow.  What’s really awesome: the “something else” (typically a source control system) could be anything.  They’ve built-in the ability to create my own command-line arguments for any source control system I have, then created the standard built-in configurations for the usual source control systems: TFS, SVN, Mercurial, and Git.  Well, what if my “source control command” was empty?  Now I’m scripting the database objects to the folder, and “committing” them to nothing.  Perfect.

They recently added the ability to specify where the working directory is, so I place it in my sql folder right next to my src directory.  Push “fake-commit” in Sql Source Control, then the real commit can happen with the related code from Tortoise.

It takes a bit of configuration, and I reached out to RedGate for clarity.  Here’s the steps they directed me to, now immortalized, to make “database to working folder” work:

1) When linking a db to source control, chose “More… custom setup.” on the left

2) Click on the “Manage Config Files…”

3) Make a copy of the Template.xml file in that folder and rename it to “WorkingFolder.xml”

4) Edit this xml file so that the name corresponds to the filename (<Name>WorkingFolder</Name>), so it appears correctly in the drop down

5) Save the WorkingFolder.xml file

6) Close and reopen the “Link to Source Control” dialog in SSMS

7) Choose “WorkingFolder” from the drop down and specify a working folder by browsing to where you want to write the .sql files to

8) Choose your model

9) Click link

Configuring other IIS boxes in the web farm

Configuring the first IIS 7.x box is far easier than IIS 6 was, but configuring multiple web servers to behave identically can be a pain.  Web Farm Framework (available in Web Platform Installer) can automatically synchronize things, but these settings change so rarely, and changes need to propagate immediately that I’d rather do this manually.  Well, constructing the 3rd or 4th or nth machine gets old.  Can we make this easier?  Most definitely we can.

Back in the IIS 6 days, the “IIS Metabase” was a scary thing — like modifying the registry or getting surgery.  Granted, we did this every day, but it was always daunting.  In IIS 7, the entirety of the IIS configuration details are in xml in C:WindowsSystem32inetsrvconfigapplicationHost.config (unless they’re overridden in each site’s web.config).  How do you set up machine 2 to behave exactly as machine 1?  You diff the files and copy nodes.  Yeah, no more surgery.  Awesome.

Ok, setting up IIS #2 isn’t quite as simple as diffing the files, but it’s pretty close.  Here’s a rough checklist of things I do to make machine 2 function identically to machine 1:

1. Install IIS on each machine
2. Install any plugins / extensions on each machine – typically this is merely a trip through Web Platform Installer
3. Configure Machine 1 to be perfect
4. Backup C:WindowsSystem32inetsrvconfigapplicationHost.config on both machines — it’s easy to mess up, and running without a safety net is bad
5. Diff C:WindowsSystem32inetsrvconfigapplicationHost.config between the two machines, and begin noticing the differences
6. Copy changes from machine 1 to machine 2
7. Restart IIS or reboot (you probably haven’t rebooted since installing Windows Updates) — probably not essential, but best not to get started on the wrong foot

As we’re diffing applicationHost.config we’ll see a few things that we can merge, and a few things that must stay different.  Let’s look through a few sections:

<configProtectedData> node has AesProvider and IISWASOnlyAesProvider nodes.  These include machine-specific details.  If you accidentally merge these details between the two machines, go to your backup and get the original details back.  I’ve never personally hosed a box by doing so, but I’ve also treaded very carefully here.

<system.applicationHost><applicationPools> node includes one node per app pool.  Do you always set them to 4.0, startMode=”AlwaysRunning” or anything else interesting?  It isn’t 3 or 5 clicks away, it’s just a text file change now.  Be careful not to merge an identity password though — it’s machine-specifically encrypted.  Just merge in all the app pools from Machine 1 into place.

<system.applicationHost><sites> node includes one child <site> node per website.  You can configure everything here just by adding attributes and child nodes.  Or add a complete site by merging in another <site> node.  (Be careful to insure their id=”” are unique and that they reference an applicationPool that exists.)  Just merge in all the sites from Machine 1 into place.

<system.webServer><globalModules> includes a list of all the httpModules installed into IIS.  Depending on what order you clicked the check-boxes while installing IIS or what order Web Platform Installer installed plugins, these may be in different orders between the machine.  Provided you don’t add or remove nodes, you can reorder them for “cleanliness”.

<location path=”…”> nodes at the bottom alter authentication protocols for each site.  You can do similar overloads in web.config, but if you configured it through IIS, they’ll be here.  (Alternatively, if you configured it in Visual Studio, the details may only be in that site’s web.config.)

Do you have any other noteworthy nodes in your IIS applicationHost.config files?  Any other techniques for configuring IIS with ease?

Enjoy!

Rob

Pop GMail on more than one machine

I’ll set this gem here before I lose it again: http://mail.google.com/support/bin/answer.py?answer=47948

The problem definition: I’ve got more than one machine POPing my GMail.  Since GMail answers the POP’s LIST request with “everything you haven’t asked for previously” (which speeds up POP connections significantly), which ever machine gets in first wins.  The other(s) get nothing.

If I prefix my username with “recent:”, I get everything within a month — downloaded or not.  Very nice.  “[email protected]” becomes “recent:[email protected]” on both machines, and now both machines get everything.

The larger question at hand, why would I POP GMail?  It’s GMail.  The answer to that is philosophical, and larger than the forum at hand.  Let’s just say ‘cuz, and leave it at that.  :D

My current CI setup

I was asked by email what my current CI setup is, and did I have a blog post about it.  Um, actually, no.  Oops.  So, here it is.  As always, it’s a work in process, and there are lots of unfinished rough edges.  It’s also got some phenomenally cool stuff too  Thus, without further ado, my current setup for Continuous Integration:

CruiseControl.NET which runs on SVN commit that runs an NAnt build script which runs:

– MSBuild on one or more solutions

– aspnet_compiler.exe on all the websites (to validate the code in the markup)

– Use YUI Compressor to compress CSS files and compress and combine JavaScript files (yes, the irony isn’t lost here)

– NUnit tests including:

       – Fire up Cassini on each site and insure a carefully selected page doesn’t blow chunks.  (e.g. no configuration or initialization errors on each site.)

       – Database / code integrity checks like do the enum values match the lookup table content(I realize they’re mostly integration tests, and cheesy at that, but it’s a far cry better than the previous state of zero tests and “hope it works out” deployment.)

– Deploy content to test server(s), calling iisreset and stopping / restarting services as necessary.

– Label the CI build via svnrevisionlabeler (so the build number in CCTray matches the SVN version number).

– Email out to those who want the spam how the build did.  (Personally I prefer data pull mechanisms like CCTray.)

There’s also an SVN commit trigger that generates a commit email and sends it out.

That’s what I’ve got now.

What I want to add to this (given another 257 hours in the day):

– JSLint validation of .js files and hopefully script tags in html

– CSS validation of .css files and hopefully style tags in html

– HTML validation to match the page’s doctype of .aspx and .html pages

– SEO evaluation of .aspx and .html pages by crawling the site

– Database migration via Tarantino or RedGate’s Sql Compare Pro & Sql Data Compare Pro

Once I’ve got these in place, I’ll be confident that the code functions and is of descent quality before I deploy it to the test servers.  Granted, I haven’t validated that it functions correctly, only that it functions completely.  The next step will be to look to Selenium Grid to validate JS works cross-browser and that various pages function as expected.  I hope by then I can also kick-start the the idea that writing unit tests to validate the code functions as expected is also a good idea.

Add a bit of duct tape, a sprinkle of insanity, and that’s my CI setup.  Cheers.

Rob