
ASP.NET Deployment Needs To Be Fixed - robconery
http://wekeroad.com/post/4373719917/asp-net-deployment-needs-to-be-fixed
======
MartinCron
I am doing some very straightforward asp.net deployment using git, TeamCity,
nunit, and powershell.

If the gauntlet of (unit-integration-acceptance) tests (in the master branch,
naturally) all pass, the code is deployed to a staging server. Then there are
some tests which run against staging. If those tests all pass, then the
artifacts for the new version of the site are copied into a new directory
(side by side) on the server. finally, a powershell script tells IIS to serve
from the new directory.

End result? Deployments are zero-downtime non-events tha happen multiple times
daily. Rollbacks are trivial (and rare). Any not-yet-ready for prime time code
can be checked into any other git branches.

Database changes? I have a tiny bit of code, called from Application_OnStart
that checks to see if it needs to do any CREATE TABLE or ALTER TABLE
statements.

Sure, I had to create all of this stuff myself, but it's all crazy simple,
reliable, and does just what the project needs.

Maybe someone could make some product to handle all of this, but the
flexibility of linking together the best tools for the job wins for now.

Also, it's just easy.

~~~
robconery
I don't see how this is "straightforward". You have to have a server that runs
TeamCity - which means installing TeamCity and setting up a build
config/environment. This is all well and good for most teams - it's needed to
keep the team from checking in crap.

But you're using that setup to deploy your code - this is the missing piece to
me. Why would you push from your Build Server? It has nothing to do with
deployment (in concept).

Moreover you say that "Rollbacks are trivial" - which is hardly the reality
for most people. How do you rollback a push from your BuildServer? Manually?

How do you alter your DB Schema? What if your deploy screws up your DB Schema?
I guess what I'm asking for is a bit more detail here - you're sort of waving
off everything I posted about (and experienced over the last 12 years)...

~~~
kenjackson
_Why would you push from your Build Server? It has nothing to do with
deployment (in concept)._

Your build server has everything to do with deployment. Your build server
should be the only place _production_ builds should ever come from. What you
seem to be suggesting is replicating a build server for deployment. To me that
seems like a violation of SOC and DRY -- but applied to infrastructure rather
than code.

Once you break out staging from production, which you should do anyways, I
don't think there's any issue left from the things you listed. And the
additional benefit is I don't have to learn another framework like Capistrano.

With that said I do think deploying w/ ASP.NET is a pain, but not for the
reasons you mentioned. But because getting the configurations working in all
the right places is painful, IMO.

~~~
robconery
I think we'll differ here - but it's a nuance really. In .NET your BuildServer
has everything to do with deployment by necessity - that's not the case in
other frameworks.

It does work, it is convenient, but that's not a Build Server's function _in
concept_.

Which things RE deployment did I leave out? I was considering the config as
part of the coding...

~~~
Grumpydev
Surely with any compiled language the "build" (or build server) has everything
to do with deployment? You have to build it _somewhere_ , either on a build
server, on a server elsewhere (AppHarbor style), or on your local machine.

You could cut the build machine out by building locally and pushing the
binaries out via git, but that's just really an implementation detail.

~~~
latch
I would have agreed with Rob, but I have to admit you make a good point.

Rob is nonetheless correct that deployment in ASP.NET is poor. I think you
explained one of the reasons why: static languages. It seems like you've
convinced yourself that something is convenient because you feel that there's
really no other solutions. I think you right and wrong...You are right because
it isn't going to change, so deal with it...You are wrong because there are
alternatives which have changed.

------
kprobst
I've used NAnt to build/deploy happily for years. I suppose it depends on each
project or application's particular context.

I will say this: If there's some kind of requirement where Dev1 will overwrite
Dev2's changes on the _target server_ , especially if we're talking about
production, then you're probably doing it wrong. We never deploy from a
developer's box or ad-hoc copying of files. Anything that needs to be deployed
needs to be in source control, and needs to be deployed from the build box. I
don't care if someone forgot an ASCX template and it takes a half hour to redo
the whole thing.

------
macca321
I pretty much agree with MartinCron that it is easy to chain together the
tools you need for your particular situation, although I run LINQPad scripts
instead of powershell or ruby or xml so I get c# intellisense goodness
everywhere (great for Ms.Web.Adminstration and SMO).

I do wonder if some kind of multi-tenant app that holds application versions
in assemblies and can roll up or down between them at will is the future
though.

------
JonoW
I reckon the article title isn't really accurate, there isn't anything wrong
or broken with asp.net deployment, it's just that there isn't a single,
complete sanctioned product from Microsoft. I don't see this as a problem, I
think using a bunch of techniques (NAnt, MSBuild, xcopy, PowerShell etc) is
ok, gives you lots of flexibility. Not that MS creating such an integrated
tool would be a bad thing.

------
fleitz
You need MSIs and PSExec. It's the best deployment system I've used. The MSI
configures your server, alerts you to missing dependencies, ngen's your DLLs
and loads them into the GAC. If you tag your MSIs with the build number you've
also got easy rollback.

There are a couple gotchas that generally require writing an MSI helper DLL
but it's no biggie. The only PITA is that if you precompile during the build
stage you have to know the path of the application in advance.

Then you just use a little VBScript to let PSExec work it's magic. Maybe I
should put together an MSI that installs all the stuff you need to make it
work.

Email me if you want some help setting up an MSI / PSExec based deploy system.

~~~
henrikschroder
The GAC? You actually use the GAC? Successfully? You're the first person I've
seen that does that.

~~~
fleitz
It's pretty easy, most commercial DLLs are signed, and most open source
projects that aren't simply get compiled from source. MSI makes it super
simple to add as DLL to the GAC. You do need versioning support in your DLLs
but once you have the infrastructure in place it's not a big deal.

------
aaronrc
Didn't really understand what's wrong with msdeploy?

Deploying can't get much easier than clicking a single button in VS.Net...
Rolling back IS an issue but it can be mitigated by versioning one's source
code and testing the site locally before deploying.

~~~
trezor
I'm sure MSDeploy is nice when it works. Serious emphasis on " _when_ it
works". I spent an entire evening trying to get MSDeploy to push something
from my local machine to my VPS. Conditions: The VPS is remote and not a
member of my home-domain, but the path between them is 100% whitelisted in all
intermediate firewalls.

How hard _can_ that be?

Evidently very hard. Despite spending the entire evening trying to get them to
communicate and push files, it simply didn't happen. In the end I ended up
writing my own deployment-system based on source-control, Samba and rsync in
Bash. It was easier, it worked and I know why it works.

If that is easier to get working than a "one click" solution, the authors of
said solution better get a bigger button. I can't seem to click this one.

~~~
mountaineer
I've had similar frustrations with msdeploy. Are you initializing the
rsync/Bash from your local machine? What are you running on the server to
receivie it?

~~~
trezor
It's all done by a bash-sc ript on an intermediate linux-shell which has
access to source-control (perforce) and the server (via smb). I can post the
script later if you are interested.

------
minhajuddin
ASP.NET deployment is broken, but any good dev should be able to come up with
his own recipe very easily. I had psexec/rake/albacore/fluentmigrator
deployment setup for my asp.net mvc servers and it worked out fine for me. I
even did a blog post on it: [http://minhajuddin.com/2011/02/04/deploy-asp-net-
mvc-applica...](http://minhajuddin.com/2011/02/04/deploy-asp-net-mvc-
applications-using-psexec-and-git/)

~~~
trezor
Agreed. I've setup my own based on SSH, bash, Perforce and rsync.

That said, Rob has a good point about MS owning the entire stack and it's
pretty odd how they can't seem to put together a working deployment-process.

Whatever you do: Don't say MSDeploy. It's a joke and getting it working
requires more voodoo than cooking together your own ad-hoc stuff, like I did.

One of the comments on the blog made me lighten up though:

    
    
        Rails Developer: if only you had a good MVC framework!
        MS: Done
        Rails Developer: if only you had a good View Engine, none of that aspx crap!
        MS: Done
        Rails Developer: If only you had a good pacakage manager like RubyGems!
        MS: Done
        Rails Developer: If only you had a good depolyment tool like Capistrano!
        MS:...
    

Who knows? It might right around the corner ;)

~~~
chrismo
What's the gems-like pkg manager?

~~~
statenjason
NuGet[1] is the package manager trezor is talking about.

[1]: <http://nuget.codeplex.com/>

------
mdpm
There is too much variance in app configuration, implementation and
infrastructure to have a single tool for the job. I'm glad there's a
functional gap - it leads to solving your 'issue' with code, making sure you
have your own continuous integration process.

Another 'button pushing' solution from Microsoft is the _last_ thing we need.
People follow 'best practices' that are not actually pragmatic for the need at
hand far too much already.

------
plasma
We deploy our releases by switching to a subversion branch on the web server/s
- at the same time if necessary.

Rollbacks are easy because we just switch back to a previous 'release'
snapshot branch.

Works well enough for us so far.

------
mwdev
git push appharbor master?

Maybe appharbor should open source their deployment routine because I sure
don't have any issues with deploying my apps there and rolling back when I
need to.

~~~
robconery
It's an HTTP git receiver - nothing magical there

------
mariusmg
aspnet_compiler and push it over ftp. Some guys are just overreacting drama
queens.

~~~
robconery
A very convincing argument.

------
chrisjsmith
I agree - it doth stink pretty badly. You either have to roll your own
deployment platform (which we did but was expensive and time consuming) or you
have to put up with immature half finished tools with a learning curve from
hell such as msdeploy.

Just make something that works, doesn't require acres of XML, does
configuration properly (web.config transforms don't work on app.config btw
which sucks and you cant msdeploy anything related to clickonce).

Batch files + robocopy are more useful at the moment than anything OOB.

------
drivebyacct2
If anyone can tell me how to have a proper Debug/Release App.Config for an
Azure Worker Role? I've tried all sorts of voodoo magic and hand editting
ccproj files. It's a joke.

~~~
smhinsey
Do you mean using the *.config transform system, or something else?

~~~
drivebyacct2
Yes. The existing ones don't work inside of the Azure packaging and upload
process. At least not when invoked through Visual Studio.

