Monday, November 23, 2009 -
ASP.NET Web Deployment is, shall we say, problematic at times – at least for a hosted scenario where you can’t do dumps from a build server and you don’t have access to IIS (which means you can’t use WebDeploy). What you’re about to read isn’t specific to the Microsoft platform at all and works with any development tool. And NO, you don’t need a single thing installed on the server (save FTP) for it to work.
Have I tried..
Seems to be that I use a Web Deployment Project that compiles my stuff down for release, then I sync that directory using SyncBack or WebDrive up to my server. The downside here is that it repaves everything – it has to – since all of the files dropped by the Web Deployment Project have a newer timestamp than their brethren on the server. This isn’t all that big of a deal – except if you’re just correcting a typo – then you’re cutting ham with a hammer.
I still find it ironic that a Web Deployment Project doesn't deploy anything really – but that’s one of those little nuggets of “just accept it” in the same way that “wieldy” isn’t really a word, but it’s negative is.
And then last night, as I was falling asleep – right from the stars above came a lovely cadence from the Dream Angels of Deployment. I want to say it was a soft, lilting tune, but it really wasn’t … it was more Chuck D in nature.
Use Git Idiot.
This is the trickiest part of the whole deal and I just spent 2 days trying to get it to work. The skinny is that you need to map a drive to an FTP folder. If you’re a Git person you probably understand precisely what I’m about to lay out here – if not, read on.
This is no easy task on Windows 64 bit, strangely enough. If you’re going to offer me some Google links and you haven’t done this yourself – no thank you :). I’ve tried everything. The summary is that if you’re on 32-bit windows, go get NetDrive (it’s free). If you’re on 64-bit you’ll have to wait until they update it or cough up $60 (like I did) for WebDrive – it’s very worth it.
With these applications you can map a directory on an FTP server to a local drive on your machine – I’m using WebDrive here to map a drive on my WekeRoad server:
With this drive mapped on my machine, the rest is butter.
This here is just an ASP.NET MVC application:
It’s now loaded up into my repository (locally) and all’s well.
Let’s pretend I’ve done some work and am now ready to show my client – so I want to run a deployment. This is where Git is groovy, you can commit locally all you want, but be very, very selective about when you “push” your changes to a visible location – such as a remote branch on Github or on your network.
In this case we’re being good coders and considering our Master branch as “Must work, all the time”, which is synonymous with a deployment cycle, so we can feel good about setting up a situation where our server pulls straight from the Origin:Master branch.
First – we need to setup our remote (aka “origin” in Git parlance) and we can do this in a number of ways. If you’re working on a team you should put it on a network share so that all people can commit their changes. If you’re solo – you can put it wherever you like – local box, Github, whatever.
For this example I’m just going to use a directory on a local backup drive called “GitHaus”. I set it up using:
git init –bare
this tells Git that it can simply operate as Remote repository – it doesn’t need to index/track local files. This helps with disk space.
Now we can add a remote to our repository and push to it…
Our initial deployment is now ready to roll – we just need to get it to our server…
Our web server has been setup and our host has been kind enough to give us FTP access – as all hosts do. In our root directory I’ve created a sub directory which will hold our awesome website:
Note the address bar? It’s a remote FTP site, but WebDrive is tricking our shell into thinking that it’s a local folder. This is key to the deployment magic…
There’s one last thing we want to do here – setup file ignore rules. Git will drop everything in our repository when we ask it for the deployment, but we can add a file to the root (called “.gitignore” – note the dot) that has some simple expressions for files and directories we don’t want (I might be missing some… massage as you need):
*resharper.user build/ [Oo]bj/ *.suo *.sln *.sln.cache _ReSharper.*/ *.user *.csproj *.cs App_Data/ Controllers/ Models/ Properties/
This file will tell Git to ignore all of project-specific stuff we don’t want in there – ReSharper stuff, code files and code-only directories (Models, Controllers, etc) and other things you don’t want on a production box.
This file will get dragged to the root of our FTP folder after our first checkout.
This is the fun part – right-click on your FTP folder from Windows Explorer, use “Git Bash Here” (because you’re a ninja that doesn’t need Visual Tooling right!?!?!) and then clone your orgin:master branch. This will pull the files from your origin:master and push them to your server using WebDrive/FTP:
The important thing to note here is that all file operations are happening locally on your machine – NOTHING is required on your server! After all is said and done we can delete out the files we don’t need and drop our .gitignore file right next to the .git repository. Here’s the site:
Another note: you will probably need to massage the .gitignore file to get it to work as you need it to. I might suggest adding a line at some point that ignores the web.config (for obvious reasons) as well.
One of the great side of effects of running deployment this way is that you now have a deployment history, and should you need to rollback after a botched deployment – you can!
A downside to this is that the repo on your server will contain the entire history of your project. Git allows you to get around this using the “rebase” command – which “smooths out and rewrites” your source history – but that’s for another post.
A final note – you can do all of the above with Subversion as well – it just takes 10 times as long and speed, when working over FTP, is pretty important.
I just stumbled onto this solution in the last few days (as I mention above) and so far it’s working great for me, personally. It could be wrought with danger and unintended greasy substances – so if you find issues and it turns out I’m full of crap please do let me know!