deploy asp net mvc applications using psexec and git

I’ve been managing a couple of asp.net mvc applications, and I have a bunch of rake/albacore tasks to compile the asp.net mvc application on the remote server and update the database using fluent migrator.

Whenever I need to deploy I do the following:

  1. RDP into the remote server
  2. Open git bash => cd to the repository’s directory => do a git fetch and git merge origin/master
  3. And then run rake compile (to compile the latest changes) and finally rake db:migrate(to update the database if there are any db changes)

Even though rake and fluentmigrator make this pretty painless. It’s still a pain to rdp and do this stuff. So, I came up with a couple of batch scripts to make this process even simpler. Now I have two batch files in the root directory of my git repo:

1
2
3
4
5
6
7
8

#deploy.bat
"C:\Program Files (x86)\Git\cmd\git.cmd" fetch &&
"C:\Program Files (x86)\Git\cmd\git.cmd" reset --hard HEAD &&
"C:\Program Files (x86)\Git\cmd\git.cmd" merge origin/master &&
rake compile &&
rake db:migrate

1
2
3
4

#remote_deploy.bat
psexec \\example.com -u userfoo -w "c:\repos\foobar" "c:\repos\foobar\deploy.bat"

The code should be self explanatory. All we are doing is, instead of running the command manually automating them.

a simple rake task to ping google, bing, and yahoo about a change in your sitemap

There is an easy way to notify google, bing and yahoo whenever you add content to your site or blog. All of them expose a url which when called with your sitemap’s url updates their indexes. This fact is known to most developers, I just wanted to share a simple rake task, which automates this. I use it to ping these search engines whenever I write a new blog post.

All it’s doing is looping over all the search engines’ urls and using curl to ping them.

1
2
3
4
5
6
7
8
9
10
11
12
13


Sitemap = "http://minhajuddin.com/sitemap.xml"
desc "ping search engines about a change in sitemap"
task :ping do
[ "http://www.google.com/webmasters/sitemaps/ping?sitemap=",
"http://www.bing.com/webmaster/ping.aspx?siteMap=" ,
"http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=YahooDemo&url=" ].each do |url|
puts `curl #{url}#{Sitemap}`
end
end


software developer's obsession with ninjas and rockstars

We software developers are so obsessed with trying to be cool that we forget who we are. I am sure many of you have seen phrases like javascript ninja/C# ninja/ php rockstar developer (with a silhouette of a rockstar) on various websites.

Think about what these phrases mean for a second.

Why the hell would I call myself a javascript ninja, instead of a javascript developer or a javascript hacker?

Is it because javascript ninja sounds cooler?

Does it mean that I would rather be a ninja than a javascript developer?

I get pissed off whenever I see a guy who gets his body peirced or calls himself a rockstar developer or calls himself some ninja just to look cool.

We are not ninjas or rockstars, we are programmers/developers/hackers and we need to be proud of that. Intel gets this right: Our rock stars are’nt like your rockstars.


use malcolmx to search for domain names from the command line

The other day I stumbled upon instantdomainsearch.com. It’s the best among the domain name checking apps I have used till now. It’s very zippy and has a clean interface.

It has just one limitation, it allows you to search domains one at a time. And if you have a bunch of domain names which you want to check in one go, you can’t do it. So, I slapped together a gem: MalcolmX which allows us to check for multiple domain names in one go. You can checkout it’s code on github. Once you install it using gem install malcolmx you can check for multiple domain names like this:

malcolmx cosmicvent minhajuddin myfunkyfreakydomain

the problem with yet another *

Naming is a very hard problem, everyone who has named a company/product/child knows that. A good name can often be a motivating factor for a product. And seeing people name their products Yet Another X makes me mad! I mean these guys are putting in so much effort in building these products and they can’t figure out a decent name! Naming something Yet Another X is mostly the easiest thing to do. But, before you do that just think about how it would sound when you ask someone to use “Yet Another Blogging Engine” or “Yet Another IRC Client” (Hey checkout this awesome “Yet Another Blogging Engine”). Or think about asking a guy to help you with “Yet Another Something”, Why would anyone want to (buy/use/work) do that, when they can get the original?

Any product worth your effort deservers a better name, Any product with this kind of name doesn’t deserve to be used. Period.

synergy server debugging tips

I’ve been using Synergy to work seamlessly across my ubuntu and windows 7 machines.

Recenty I changed my ubuntu box to the synergy server, and the synergy server was crashing without all the time. Looking into the logs (/var/log/syslog) didn’t show anything, I was left scratching my head for a long time. Then I realized that the synergys can be executed in foreground using the -f flag. I executed synergys -f -c /etc/synergy.conf and there it was, when I switched the computer using a hotkey it crashed. But this time, it wrote the actual error on the screen, so I could investigate more and fix it. So, the next time your synergy server keeps crashing and you don’t find anything in the logs run it in foreground and see what’s going on :)

By the way, the synergy binaries in the ubuntu repositories are very old, you should download the binaries from their site

rake task to delete untracked files in git

UPDATE I should have checked if git has a command for this. Anyway SomeGuy has reminded me once again that I should GTFT (Google the f*** thing) before creating a task. Thanks for the tip SomeGuy :). Long story short, use git clean to cleanup untracked files


Whenever I merge stuff from my colleagues, I end up with a bunch of *.orig files. So, I created a simple rake task which deletes all the untracked files.

1
2
3
4
5
6
7
8
9
10
11
12
13
14


desc 'deletes untracked files'
task 'git:del' do
files = `git status -s`
files.lines.each do |f|
next unless f.start_with? '??'
f = f.gsub('??', '').strip
File.delete(f)
puts "deleted => #{f}"
end
end


This will permanently delete all untracked files from your working copy, so use it with care! :)

hookup hotkeys to swap active machine in synergy

I have a Windows workstation and an Ubuntu laptop. And I use them simultaneously at work. Using two keyboards and mice can be a pain. And that’s when I found Synergy. Once you setup synergy you can use one keyboard/mouse to manage both your computers. It works like a dual monitor setup, only that the other monitor is a different machine.

I am a keyboard person and moving the mouse over to the next screen to use the other machine is …. well, It’s not enjoyable. Synergy makes it very easy to hookup hotkeys to be able to do things. You can add the following code to the synergy configy file which is located at C:\Users\minhajuddin\Documents\synergy.sgc if you are using a windows machine as the synergy server.

section: options
    keystroke(Alt+\u006B) = ; switchInDirection(right)
    keystroke(Alt+\u006A) = ; switchInDirection(left)
end

Now when you hit Alt+k you’re active machine will be changed to the one on the right, Alt+j will change it to the one on the left.

By the way, if you don’t know anything about synergy and want to get started with it, checkout How to configure Synergy in six steps

r3t a rails3 template with devise mongoid rspec cucumber and more

Lately I have been prototyping a lot. And the initial rails wireup with all my gems was becoming a pain. I checked out RailsWizard It’s an awesome app, and for most of the requirements it would work right out of the box.

I needed a template with a little more customization, so I created a rails project wired it up and put it on github. So, now, whenever I need to do some quick prototyping, I don’t get distracted by the initial wireup. I just clone the repo and start banging out code :)

Here is a screenshot of the users page

r3t Rails Template Screenshot

Download the template

pageant and plink for the windows git user

Alright, pushing and pulling can be a pain if you are using git (through msysGit) on windows. You’ll have to enter the password every time you want to pull or push, And if you are working in a team where you need to sync your stuff a lot, this is really painful.

I use ubuntu for half of my work and Windows for the other half. And this is one of the many places where ubuntu shines, It remembers the passwords of my private keys in a keyring. Once you configure it, it doesn’t ask you for the password of your private key, it just works.

If you want to do the same with windows, you’ll need plink, putty and pageant which you can dowload here. Once you have it copied to a directory, you need to do the following:

  1. Create an environment variable called GIT_SSH and copy the absolute path of plink to it, e.g. d:\utilities\putty_stuff\plink.exe
  2. Create a shortcut of pageant on your desktop
  3. Right click and open up the properties of this shortcut and and append the path of your key to the target of this shortcut. ()
  4. Copy this shortcut to the startup directory in your windows programs menu to start it automatically when you login to windows

Now, whenever you login to your computer it will start pageant automatically and ask you for the password of your private key. Once you do that you can pull and push as much as you want, you won’t be pestered for your password anymore :)

how to setup your router to automatically reconnect

At my home I have a DSL router which disconnects whenever it feels like it ;) To reconnect it, I usually have to open up the router’s home page, browse to the page with the connect link, enter the username and password and then submit the form. I know just reading the above text makes me sleepy and it’s such a distraction.

So, I wrote a small script which reconnects the router if it has disconnected. you can use it if you have the same problem ;)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36


require "net/http"
require "uri"
require 'base64'

def request(page, method = 'get', form_data = nil)
uri = URI.parse("http://router#{page}")
http = Net::HTTP.new(uri.host, uri.port)
request = method == 'get' ? Net::HTTP::Get.new(uri.request_uri) : Net::HTTP::Post.new(uri.request_uri)
request.set_form_data(form_data) if form_data
request.basic_auth("username", "password")
http.request(request)
end

def connect
connect_url = '/webconfig/quick_start/connect.html/action_qstart_connect?qstart_pppIntf=pppoe_0_35&qstart_pppUserName=username&qstart_pppPassword=password&submit_Connect=Connect'
res = request('/webconfig/wan/wan.html')
unless res.body.match "Disconnect"
puts 'disconnected, connecting ....'
res = request(connect_url)
else
puts 'connected'
end
end

while(true)
begin
connect
rescue
puts $!
end
sleep 5
end


helper script to create new posts using jekyll

Alright, so, whenever I try to write up a blog post Jekyll wants me to do a lot of redundant and painful stuff. To create a blog post, you’ll have to do the following:

  • Create a filename called 2010-10-01-helper-script-to-create-new-posts-using-jekyll.markdown which has a timestamp, hyphens and a title which is kind of a pain to type.
  • And once you have this file you’ll have to put up some yaml front matter: the title, and the layout is the minimum, Here you are typing the title again.

It’s not a big deal, but it’s still annoying. So, I came up with a small ruby script called new.rb, which basically automates this stuff.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

#!/usr/bin/env ruby

# Script to create a blog post using a template. It takes one input parameter
# which is the title of the blog post
# e.g. command:
# $ ./new.rb "helper script to create new posts using jekyll"
#
# Author:Khaja Minhajuddin (http://minhajuddin.com)

# Some constants
TEMPLATE = "template.markdown"
TARGET_DIR = "_posts"

# Get the title which was passed as an argument
title = ARGV[0]
# Get the filename
filename = title.gsub(' ','-')
filename = "#{ Time.now.strftime('%Y-%m-%d') }-#{filename}.markdown"
filepath = File.join(TARGET_DIR, filename)

# Create a copy of the template with the title replaced
new_post = File.read(TEMPLATE)
new_post.gsub!('TITLE', title);

# Write out the file to the target directory
new_post_file = File.open(filepath, 'w')
new_post_file.puts new_post
new_post_file.close

puts "created => #{filepath}"

Download the gist

create a simple gem using jeweler

So, you’ve come up with some awesome re-usable utility in ruby, and you want to use it across your projects. And you don’t want to copy/paste the files across different projects, cause that’s a pain and keeping all your re-usable code across the projects up to date is not feasible.

It’s obvious at this point that what you want is a gem, which would make sharing of code across your projects a breeze, with the added benefits of seamless upgrades. Hopefully this blog post will teach you how to create a simple gem in a few steps.

Gem creation is very easy if you use the right tools. If you go to ruby-toolbox.com you can see that there is more than one tool for gem creation and management. The top-most on this list is Jeweler, It is an awesome gem with a lot of nifty features which makes gem management a breeze.

OK, Enough talk let’s fight. The first thing which you need to do is install jeweler with the command [sudo] gem install jeweler

Once you have jeweler installed just follow the steps below to create your own gem:

  • Run the command jeweler fixnum_extensions in the directory where you want to create your your gem (fixnum_extensions here is the name of the gem).
  • With the above command jeweler creates a bunch of files and directories for your gem. One of the files which it creates is the Rakefile which has a lot of predefined tasks which you can use to manager your gems.
  • The file where you need to put your ruby code is lib/fixnum_extensions.rb my file has the code below in it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

#This is a contrived example but it's fine
class Fixnum
def add(number)
number + self
end
def sub(number)
number - self
end
def mul(number)
number * self
end
def div(number)
number / self
end
end

  • Now you need to open up the Rakefile and add a description and summary instead of the TODOs.
  • Note that it fills up the author name and email by looking at your git configuration files, it also creates a git repository with a nice .gitignore file and makes the initial commit.
  • The last thing you need to do before building your gem is create a VERSION file, to do this just run rake version:write. This command creates a VERSION file in your gem’s root folder which holds the version number of your gem.
  • Finally, to build our gem run rake build (ignore the warnings when you run this command). This will create a folder called pkg which holds your final gem file fixnum_extensions-0.0.0.gem.

Now, you can share this gemfile with anyone you want and they’ll get all your code in a nice gem package. To install it, just run the command gem install pkg/fixnum_extensions-0.0.0.gem

To test it out open an irb session and run the following commands

1
2
3
4
5

require 'rubygems'
require 'fixnum_extensions'
1.add(2).mul(3)

Jeweler adds a lot of nifty tasks which are great, to check them out just run rake -T

git - basic commands

Before you read this blog entry please read The git parable. It is a nice read to understand the need and reason for git.

basic commands

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

#create the repository, first thing when creating a project
git init

#shows you the current status of your repository
git status

#adds files or directories to the staging area
git add filename

#commits the changes from the staging area to the repository
git commit -m 'commit message'

#shows the repositories graph
gitk --all

# to check the commits
git log

# get the last commit info
git log -1

# file which stores the ignore file patterns
.gitignore

#to checkout a commit
git checkout SHA1ID

#to check the differences between working dir and latest commit
git diff

#diff between those two commits
git diff commit_id1 commit_id2

#server #to push to a server
git push

#to manager remotes
git remote

# to get the latest commits
git fetch

I’ll update this post with more examples as I get the time

post update hook for gitosis and jekyll

If you have a gitosis server on which you host blog using jekyll (that would be 0.00001% of the bloggers I guess ;) ). You can use the following file as a post-update hook to update your jekyll blog.

So, let’s say your git repository is named example.com, browse to /home/git/repositories/example.com/hooks and create a file with the name post-update, copy the content below to your post-update file. That’s it you are set, the next time you push to your git repo, your blog will be automatically published.

1
2
3
4
5
6

#post-update
unset GIT_DIR && cd /var/www/blogs/example.com && git pull && jekyll
#/var/www/blogs/example.com is where your blog's repo is cloned
echo "finished deployment"

Below are a couple of problems I ran into and how I fixed them:

  • File permissions issue cannot write to .git/FETCH_HEAD, you’ll get this error if the ‘git’ user doesn’t have write privileges to your blog’s cloned directory, you can fix it by giving write permissions to your git user to this directory
  • Permission to repo denied to username: this means your git user doesn’t have read priveleges on your repository. Fix it by giving the git user readonly privileges in your gitosis.conf

how to install a ruby version with rvm when you are offline

This has happened to me manytimes, When I try to install a version of ruby, rvm crashes unable to download the right version of the ruby source code. Sometimes because it can’t resolve rubyforge.org and other times for other reasons.

Anyway, when such a thing happens, or when you don’t have an internet connection to the computer on which you want to install a version of ruby, you can copy the zipped file with the source code to your $HOME/.rvm/archives/ directory and then run rvm install <ruby-version>. This will install the desired ruby version skipping the download and using the file present in the archives direcotry.

1
2
3
4

cp ruby-enterprise-1.8.7-2010.02.tar.gz /home/minhajuddin/.rvm/archives
rvm install ree-1.8.7

rvm and how to install it on ubuntu 10.4 lucid lynx

RVM (Ruby Version Manger) is an awesome tool which allows you to manage different versions of ruby on the same machine. I’ve worked in the .net world for quite some time. And coming into ruby I was very frustrated with the fact that I couldn’t have multiple versions of ruby or that of rails. This made playing around with edge stuff a PITA. In .net I would be able to install different versions of the framework side by side and not having that in ruby or rails was really frustrating.

Enter RVM a tool to manage different ruby installations, the ruby story gets better than the .net stuff :) With RVM you can not only install different versions of ruby but also different patch levels of ruby. So, now you can have ruby 1.8.7 patchlevel 249, and ruby 1.8.7 patchlevel 299 happily working off your computer.

Alright, so you’ve decided to install rvm on your ubuntu (lucid lynx) box. There are a a lot of good tutorials on how to do this. Installing RVM is the one on the rvm website, Setup Ruby and Rails is a good one which actually tells you how to install rails and stuff with RVM. I did the following stuff to get it working on my machine.

  1. Do a fresh installation of ubuntu lucid lynx and install a basic version of ruby using apt-get. You might already have a computer with ruby installed if that’s the case you don’t need anything for the first step.

  2. Run the following on your bash prompt to install a few libraries which are needed by rvm to compile ruby

1
2
3

sudo apt-get install curl git-core bison build-essential zlib1g-dev libssl-dev libreadline6-dev libxml2-dev autoconf libxslt1-dev libpq-dev postgresql

  1. Install RVM by running the following:
1
2
3

bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )

  1. Fix your .bashrc.
1
2
3
4
5
6
7
8
9

#replace the following which is usually found on line 6
[ -z "$PS1" ] && return
# with
if [[ ! -z "$PS1" ]] ; then
# also put the following line at the end of the file
[[ -s $HOME/.rvm/scripts/rvm ]] && source $HOME/.rvm/scripts/rvm
fi

  1. Finally change the ownership of “~/.gem” using sudo chown minhajuddin /home/minhajuddin/.gems

Now you should be able to install new versions of rvm using rvm install ruby<version> like rvm install ruby-1.9.2 and change the rvm version using rvm use ruby-1.9.2

RVM is a just the right amount of crazy which was needed in the ruby world at this point of time. And if you find it useful please donate some dough to the guys working on RVM, they are making the lives of a lot of guys like us more enjoyable.

jekyll the programmers blog engine

I have been using Wordpress quite some time now, and even though I don’t blog often, I’ve had a lot of friction working with wordpress to publish blogs (even though I don’t post often). I think the main reason for the friction is because of the fact that I am a programmer and my desire to control the formatting and stuff of a blog post. Wordpress allows you to enter the raw html code, but it doesn’t work out correctly most of the times, by the time I preview the changes and come back to the html view my painfully crafted html seems to be lost. And this problem is compounded by the fact that I post code snippets(By the time I finish editing the blog post, my code snippet would get html encoded 4 times). I’ve tried windows live writer too, I must say it’s a very good product. But, what I was really looking for was something which would get out of my way when I wanted to post a blog. And that’s what jekyll does. From jekyll’s home page:

Jekyll is a simple, blog aware, static site generator. It takes a template directory (representing the raw form of a website), runs it through Textile or Markdown and Liquid converters, and spits out a complete, static website suitable for serving with Apache or your favorite web server.

Jekyll is a shiny gem(no pun intended) which is not known to many people. Jekyll does exactly what I need, It allows me to write up blog posts in a plain text editor like Vim. And all I have to do to publish a post, is, put the text file which has the contents of the post in a specific folder and run jekyll, that’s all. Moreover jekyll allows you to use pygments for formatting any code snippets you want, It also allows you to write your blog code using markdown or textile. And lastly jekyll actually generates the final html content of your blog posts. So no more database roundtrips and no more crazy performance problems, Your webserver just serves these static html pages which is crazy fast. I hope this change allows me to blog more often(Now that I am free from the shackles of wordpress :) ).

Redirector - A simple rack application which makes redirection of multiple domains a breeze

The last couple of months I have been dabbling in all kinds of Ruby web frameworks. The choice of web frameworks in ruby is really amazing.

The other day, I had registered a couple of domains for one of my projects. And, I wanted to setup redirects of the ‘*.org’ and ‘*.net’ domains to the ‘*.com’ domain. I searched around a bit to see if there was a simple way to do this. But, I didn’t find any simple solution. If I hadn’t known any ruby frameworks, I would have hacked a bunch of php files and would have setup directories for each of the redirects. But, I have been digging ruby for a while now, and I am lovin’ it :)

So, I thought I could use rack to build a small app which would redirect domains based on a configuration file. The initial code I came up with was very simple. Below are the contents of the config.ru file

1
2
3
4
5
6

app = proc do |env|
[302, {'Content-Type' => 'text','Location' => 'cosmicvent.com'}, ['302 found'] ]
end
run app

Just four lines of code to get our redirect stuff working! All I had to do now was to somehow get the status, and location of redirects through some configuration file. I fired up irb and played around with yaml a bit. It’s a child’s play to get yaml working with ruby. The final code looks something like below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

#config.ru:
require File.join(File.dirname(__FILE__), 'lib/redirector')

use Rack::ContentLength
use Debugger, false

app = proc do |env|
app = Redirector.new()
status, headers, response = app.call(env)
[ status, headers, response ]
end

run app

#lib/redirector.rb:
require 'yaml'

class Redirector

@@config = YAML::load(File.open('config.yaml'))

def self.config
@@config
end


def call(env)
host_config = get_host_config(env['HTTP_HOST'])
[host_config['status'], {'Content-Type' => 'text','Location' => host_config['location']}, get_host_response( host_config ) ]
end

private
def get_host_response(host_config)
"#{host_config['status']} moved. The document has moved to #{host_config['location']}"
end

def get_host_config(host)
return @@config[host] if @@config[host]
raise "Configuration for #{host} not available"
end
end


class Debugger

def initialize(app, debug)
@app = app
@debug = debug
end

def call(env)
if @debug
puts '==== Config information ===='
puts Redirector.config.inspect
puts '============================'
end
@app.call(env)
end

end


That’s all, now all I had to do was set it up on my ubuntu server using ‘phusion passenger’. You can download all the code from http://github.com/minhajuddin/redirector. Below, is a part of my config.yaml file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

cosmicvent.net:
status: 301
location: 'http://cosmicvent.com'

cosmicvent.org:
status: 301
location: 'http://cosmicvent.com'

www.cosmicvent.net:
status: 301
location: 'http://cosmicvent.com'

www.cosmicvent.org:
status: 301
location: 'http://cosmicvent.com'

www.cosmicvent.com:
status: 301
location: 'http://cosmicvent.com'


Get a Hello World ASP.NET MVC app up on Mono

The other day I was trying to get started with Mono using ASP.NET MVC. As usual I googled and found a useful post on it http://beyondfocus.com/mono/asp-net-mvc-on-mono-two-options-for-the-ide-crowd/ . But, the post assumes you already know how to deploy an asp.net app on Mono. Anyway here is my attempt to make it easier for folks to hop onto Mono.

 


Alright, so all I am trying to do here is get the ASP.NET MVC 1.0 default template up and running on Mono. There are a few things you need, to get this working:


  1. You need to download a Virtual Machine image from http://www.go-mono.com/mono-downloads/download.html OR install Mono 2.4, apache, mono_mod, and xsp if you already have a linux machine up and running.

  2. Visual Studio with ASP.NET MVC 1.0 installed.

Now, once you have these pre-requisites,


  1. Fire up your vs and create a new ASP.NET MVC 1.0 project. Change whatever text you want to in the template, Here is how mine looks on my machine: image
  2. Publish this application to a folder, say d:\binaries\mono_mvc. and then copy it to your Mono linux machine, copy it to the /srv/www/ folder.


    image

  3. Once you’ve done that, head over to the http://go-mono.com/config-mod-mono/ to create your mod_mono configuration file. Fill out all the necessary details and click on the Download button to download your newly configuration file.

    image
  4. Copy this new configuration file to the /etc/apache2/conf.d/ directory on your linux machine.


    image

  5. The last thing you need to do is restart your apache server


    image
  6. Now you can browse to http://localhost/<your_application_name> to see your asp.net mvc application in it’s full glory :)


    image 

This is obviously a contrived example, but you can see how easy it is to deploy an asp.net mvc application to a linux box running apache and Mono. This is no more complicated than deploying a web app on a Windows box, and all props go to the Mono guys for making Mono easier to use with every release. I hope to dive in deeper into Mono real soon and I’ll share my experiences with you guys.