Archive for the ‘Web Development’ Category

Evaluating JSON in Safari

Friday, August 13th, 2010

Just a quickie on parsing JSON strings in Safari.

I’m in the middle of a project developing a timesheet/rostering application, which uses a lot of Javascript. I have a series of web services that interact with jQuery. For reasons beyond the scope of this post, the web service returns a JSON string, which needs to be parsed into a JSON object, and then further processing is done on the object.

I had a bug where Safari was choking on the JSON string returned by my webservice, yet Firefox and IE were happy parsing it. As it turns out, my JSON string had a Javascript keyword in it; ‘break’.

Here is my JSON string (well, an example):

{employee: 'Joe', worked: true, periods: [{start: '09:00 AM', finish: '17:00 PM'}], break: {paid: true, hours: '1'}}

Safari was choking on the break in the above JSON string.

When I wrapped the attribute in single quotes, like so:

{employee: 'Joe', worked: true, periods: [{start: '09:00 AM', finish: '17:00 PM'}], 'break': {paid: true, hours: '1'}}

it was happy.

You can replicate this by using the below code snippet to parse out your JSON string quickly in Safari’s debug window:

var json = "{employee: 'Joe', worked: true, periods: [{start: '09:00 AM', finish: '17:00 PM'}], break: {paid: true, hours: '1'}}";
var obj = (new Function("return " + json))();

which should fail. If you add the single quotes around break though, it should work just fine.

This also fails for other Javascript keywords:

(new Function("return " + "{if: true}"))();

fails. If you wrap if in single quotes, it works.

I think the take away lesson is to always wrap your object attributes in a JSON string in single quotes, otherwise Safari will choke on it.

ASP.NET GridView with an ObjectDataSource

Monday, October 26th, 2009

Just a quick tip:

I got the following exception today:

If a data source does not return ICollection and cannot return the total row count, it cannot be used by the GridView to implement server-side paging.

If you’re trying to return an IEnumerable from your select method, try changing it to a List or an array. That should clear the problem right up.

Configuring webHttpBinding When Using WCF with JQuery

Thursday, June 25th, 2009

Firstly, a disclaimer: I don’t have a lot of experience working with AJAX enabled WCF services, and from reading some of Rick Strahl’s posts on using JQuery with ASP.NET, I’m doing things in a really hackish and terrible manner. Hopefully my mistakes won’t impact the usefulness of this short tip.

When working with JQuery and AJAX enabled WCF services, I recently encountered the following error, through Firebug and Fiddler:

The maximum string content length quota (8192) has been exceeded while reading XML data.
This quota may be increased by changing the
MaxStringContentLength property on the XmlDictionaryReaderQuotas
object used when creating the XML reader.

This is caused by WCF webHttpBinding default having fairly draconion limitations on XML message length and depth. This thread on MSDN helped diagnose the problem, however it didn’t do much to help me solve my particular problem. Ultimately, I stumbled upon the solution quite accidentally.

Firstly, as per the MSDN thread, you need to add the custom binding configuration underneath the configuration section:

<system.serviceModel>
  <bindings>
    <webHttpBinding>
      <binding name="bindingConfiguration">
        <readerQuotas maxDepth="32" maxStringContentLength="2048000" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      </binding>
    </webHttpBinding>
  </bindings>
  ..
</system.serviceModel>

At first I thought this was a custom binding, and tried to replace the service endpoint binding to the custom binding defined above, however this was causing an “System.ServiceModel.ServiceActivationException” exception.

The above binding declaration is actually a configuration for the webHttpBinding. As such, you need to add the BindingConfiguration property onto your service endpoint, along side your binding declaration. This is as follows:

<service behaviorConfiguration="Your.Service.Behavior"
      name="Your.Service.Name">
    <endpoint address="" behaviorConfiguration="Your.Behavior.Configuration"
     binding="webHttpBinding" bindingConfiguration="bindingConfiguration" contract="Your.Service.Contract" />
</service>

This will allow you to send larger messages to your WCF services via AJAX, and get on with creating applications.

Going Camping with CouchDB On OS X Tiger

Saturday, June 13th, 2009

With Snow Leopard being released at the end of September this year, Tiger is definitely starting to show it’s age. I’ve been putting off upgrading to Leopard for quite some time, not being able to justify the down time associated with upgrading an OS. This has had an unpleasant side effect of not being able to do things quite as easily as I want, and finding information is hard.

Due to the recommendations in the comments of my Ruby CMS article, I have decided to start playing with the Camping Ruby microframework backed by CouchDB. Getting Camping up and running was easy enough, and I managed to get some trivial functionality going. Camping uses SQLite for it’s database, which is fine if I wanted to massage my data into a relational form. However, I have models with optional attributes, and rather than making nullable database types, I want to leverage CouchDB’s schema-less, RESTful document storage. Each persisted object in my application will be available on a unique url, so CouchDB is a nice fit for what I want to do.

The Great Installation

I found this great article about getting Camping talking to CouchDB, and it seemed easy enough, so I decided to try it. Since I already had Camping working, all I needed was to get CouchDB installed on my Macbook. As much as I’m not scared of compiling applications from source, I’ve had issues in the past with OS X and compiling, so I decide to find a simple package or disk image to install. I found CouchDBX, however checking the requirements showed that it supports Leopard only.

With a little more research, I found out I had to use Macports to install CouchDB. Macports relies on XCode Tools which come available on the DVDs that came with OS X. If you haven’t previously installed XCode Tools, then you should install them before you install Macports. Something that is buried in a support ticket, however, is that Macports targets XCode tools 2.5. My XCode tools was something like 2.4.8. While I did manage to get Macports installed, the installation for CouchDB fails when it tries to build tk. If you, like me, have an older XCode Tools than 2.5, you’ll need to download 2.5, which you can find deep inside the Apple website. This does require an Apple Developer Connection account to get, so if you don’t have one, you’ll need to create one.

Installing CouchDB is as simple as issuing

sudo port install couchdb

and Macports will take care of the rest. CouchDB lists it’s dependencies as Spidermonkey, Erlang and a few others, however each of those has dependencies, and each of those dependencies has dependencies, and it ends up taking quite a long time and downloading a fair few packages. The upside is that if you didn’t have Erlang previously installed, you do now. Erlang is something I’ve been wanting to take a look at.

Start The Server Before You Leap

While the article I linked to above about getting Camping and CouchDB talking is good, it’s not exactly the most verbose explanation especially if you haven’t read the documentation for CouchDB and prefer to just dive in. For those who are still a little unsure like I was about how exactly to do this, I’ll outline my approach below.

Before you get started writing any code at all, you need to start your CouchDB server. This is something that escaped me for the longest time, and when I finally twigged, it gave me a bit of grief. To start CouchDB, issue the following command:

sudo couchdb

If you try this without escalating privilege, it will return an error “{“init terminating in do_boot”,{{badmatch,{error,shutdown}},[{couch_server_sup,start_server,1},{erl_eval,do_apply,5},{erl_eval,exprs,5}, {init,start_it,1},{init,start_em,1}]}}”, which searching for will bring you to the CouchDB wiki page for error messages. This page will tell you the problem is an unavailable port. For me, at least, this is not true. CouchDB runs on port 5984 which as far as I know is not used for any system services or other software. The reason I was getting this error was that I wasn’t running it with enough privilege.

Once you get CouchDB started, you’ll notice it blocks the terminal. I don’t like to have too many windows open at once, so I’d prefer to have it run as a background process. Fortunately CouchDB will let you do that with a command line switch option, along with changing the location of the pid file. I’ll leave figuring out how you want to start it up to you.

Once you have CouchDB started, you’ll have access to a web-based administration panel called Futon. Futon is available to you at http://localhost:5984/_utils/, assuming you’re running CouchDB on your local host. The Futon utility will allow you to create databases and insert documents in preparation to test your connectivity with Camping.

Camping Time

There were two Ruby gems I had considered when deciding how to connect Ruby to CouchDB. I should point out that due to the RESTful nature of CouchDB, you strictly don’t need any Ruby gems and could roll your own fairly easily, if you wanted to. I didn’t want that level of control, personally. The two gems I considered were CouchRest and RelaxDB. CouchRest is a simple Ruby wrapper around the CouchDB REST API, whereas RelaxDB is more abstracted, bringing ActiveRecord-like functionality to CouchDB. While before I would have chosen RelaxDB, I’m intentionally trying to work a little closer to the raw APIs here, so I chose CouchRest.

You can install CouchRest through RubyGems:

sudo gem install couchrest

however I found that the gem version wouldn’t work and kept throwing errors when I started my Camping application. To overcome this, I just cloned it from the GitHun repository and placed it in my Camping app directory and referenced it that way.

The first thing to do would be to create a normal Camping sample application, if you haven’t done already. For the purposes of this post, I’m going to use the “skeletal Camping blog” application used in the documentation, and edit that to work with CouchDB. I figure this will give everyone a relatively common base from which to start. Import CouchRest just below where the application imports Camping:

require 'camping'
require 'couchrest' # or 'couchrest/couchrest' or similar if you've cloned from Github

Given that the purpose of this article is to demonstrate connecting to CouchDB, and not the design of a framework around it, we can safely ignore defining a model for now, and rely on CouchDB as our model. So if you’re following along from the example application, you can safely delete the classes from Blog::Models module. We’re not going to delete the whole module, because of the create method.

The Camping create method that is run when the server starts up your Camping app. From the documentation, “This is a good place to check for database tables and create those tables to save users of your application from needing to manually set them up.” Instead, we’re going to use this method to set up CouchRest in our application:

module Blog::Models
  def Blog.create
    db_url = 'http://localhost:5984/'
    storage = CouchRest.database("#{db_url}blog")
    Blog::Controllers::Index.set_storage(storage)
  end
end

Next, because we’re now calling a new method on the controller class, we need to modify that. Change the Blog::Controllers::Index class to the following:

module Blog::Controllers
  class Index < R '/(\w+)'
    def Index.set_storage(storage)
      @@storage = storage
    end
    def get(id)
      @post = @@storage.get('posts/' + id)
      render :index
    end
  end
end

What I’ve done here is given the controller class a static reference to my CouchDB database (from the create method). Then the controller was changed to respond to a regex, which is passed into the get method. We use the id passed in to retrieve a document from CouchDB, which we assign as an instance variable.

Lastly, we need to modify the Index function view to pull data from the CouchDB database:

def index
  h1 @post[:title]
end

This will output the title of the test document created at the start of the article.

If you haven’t already, start up Futon and create a database for the purposes of this demo. Call the database “blog”, and fill it with a test document with the id of “posts/test”, and at least a “title” property with the value “Test Post”, and any other properties you wish.

Start the Camping application with camping blog.rb, and point a browser to http://localhost:3301/test, and you should see “Test Post” in a header tag, rendered out to the browser, which means that Camping has successfully communicated with CouchDB.

I didn’t cover putting data into CouchDB, however you would do it in a similar vein, writing a post method inside your routes to create data and save it to CouchDB. From here, personally, I’m going to create some wrapper classes for requests and models and build up something which is a little DRYer, however as far as a demo, this is good enough.

jQuery Context Menu Unbind Click Fix

Thursday, April 9th, 2009

Updated on May 28, 2009, due to partial fix. The fix should now be a complete fix.

Apologies for the somewhat confusing title.
I’ve been doing a lot of jQuery work, replacing all the AJAX.NET crap in my project at work to speed the interface up. I’ve started using the awesome jQuery Context Menu plugin. However, I found it was also messing around with jsTree which I am using on the same page.

The problem is that the jQuery Context menu overzealously unbinds all click events from the document. This means that it’s going to break all your other Javascript that relies on clicking. Checking the documentation for jQuery’s unbind function, you can see that it accepts a function as a second parameter. This is the function that will be unbound if you pass that in as a parameter.
So, I fixed the jQuery Context Menu by changing the following:

  1. In the main contextMenu function, near the end, just above the return statement, I added the following:
    // External click event for document
    function onDocumentClick(e) {
          var menu = $('#' + o.menu);
          $(document).unbind('click', onDocumentClick).unbind('keypress');
          $(menu).fadeOut(o.outSpeed);
          return false;
    }
    
  2. Next, I change the function that assigns the click listener to the document to assign the defined function, instead of an anonymous function. So, change:
    // Hide bindings
    setTimeout( function() { // Delay for Mozilla
          $(document).click( function() {
                $(document).unbind('click').unbind('keypress');
                $(menu).fadeOut(o.outSpeed);
                return false;
          });
    }, 0);
    

    to

    // Hide bindings
    setTimeout(function() { // Delay for Mozilla
          $(document).click(onDocumentClick);
    }, 0);
    
  3. Lastly, I remove all instances of:
    $(document).unbind('click');
    

That’s it. That fixed the problem for me. You’ll notice I don’t bother with the keypress bindings. That’s because I’m not using them, so I’m not bothered. I’m assuming the fix for that will be a similar strategy, for those who are bothered.

I’ve uploaded my version for those who can’t get it working using the tips in this post, but remember the copyright remains with Cory S.N. LaViska over at A Beautiful Site.
jquery.contextMenu.js

Visual Studio 2008 Deletes LINQ DBML Designer File

Wednesday, April 1st, 2009

Do you spend hours wrangling with your “Interactive” Development Environment, trying to prevent it from deleting your boiler plate .designer file for your LINQ DBML? Do you get baffled watching Visual Studio delete said file from your software version control system, and then struggle to get the two back into sync?

Then you might be encountering this bug right here. The reason for this post is because this bug seems very hard to find information on in Google. So hopefully I can raise some awareness, and at least have it pop up on a Google search.

Typical symptoms are the designer file for the DBML being deleted when the DBML is updated. If you’re also using source control, Visual Studio will attempt to delete it from your source control at the same time. Renaming the DBML file will cause it to regenerate, however it can cause major headaches when combined with source control, removing it, adding it, pending delete actions hidden in a project you thought you had unchecked out.

The solution is the suitably moronic action of moving all your using statements inside your namespace declaration. A co-worker found this solution in this MSDN forum thread. Once you move your usings, Visual Studio happily stops deleting your designer file, and you can finally get back to work programming instead of fighting your tools.

Parsing ASP.NET pages with SGMLParser

Monday, March 9th, 2009

I’m going to take a short break in my Ruby CMS series to post something I encountered at work.

During my development of the CMS at work, I’ve had to deal with parsing HTML content in order to compile page content into tags. This involves being able to replace certain elements of a page with other elements. At first I tried to do this with regular expressions, however this didn’t turn out too well when it came to dealing with the inconsistencies in legacy sites running on the current, older CMS. Next, I tried parsing the pages as XDocuments, which worked ok as long as I was parsing well formed pages. As soon as it hit a malformed page, however, it died in a fiery burst of exceptions.

Then I looked at SGMLParser, and it seemed like it was my savior. It parsed SGML, of which HTML is a subset, and it auto corrected malformed content, and would handle all the inconsistencies of life, in use HTML, and it would allow me to parse it into an XDocument so I can manipulate nodes. However, even SGMLParser had it’s own problems: it wouldn’t handle ASP.NET server tags very well, which was a problem.

We provide “plug in” functionality to CMS sites by the way of ASP.NET server controls. You build your functionality, stick the server control files into your site, drop the binary into the bin folder and insert the server control tags into your page. Fire it up, and it will appear and function. However, when running pages with server control tags through the SGMLParser, it wouldn’t recognise the namespaces, and would strip them, completely breaking them.

This was unsatisfactory, as we were planning on using a similar sort of set up to perform the same thing in the new CMS. So, I hit Google, looking for ways to get around this. There’s not a lot of information out there about it, other than “SGML parses SGML, not ASP.NET, which isn’t valid SGML” which was exceedingly unhelpful, because I already know.

I peeked into the source of SGMLReader to see if maybe I could remove the functionality that stripped out unknown namespaces. Sure, this would probably defeat the purpose of using SGMLParser, but it would help me out in this specific project. Unfortunately, the codebase is rather complicated and I really didn’t want to dig in and spend hours on something I wasn’t sure was even going to work.

I saw that the project has a custom HTML dtd, so I considered briefly writing a dtd for ASP.NET. However, while I was thinking of all the different permutations of server tags, especially when you can specify your own namespaces and tag names and attributes, I quickly decided that wasn’t suitable either.

In the end, and I believe this is honestly the only way to do it, I ended up pre-processing my content, wrapping ASP.NET server tags within <![CDATA[ ]]> tags. I noticed that SGMLParser was wrapping my older <% %> ASP style tags in this fashion, and leaving them unmolested. After I parse it into the XDocument, do my manipulations and pull it back out as the desired content, I run a post-process through it, removing the <![CDATA[ ]]> tags that were added in the pre-process. After, I’m left with my content as it went in, with the modifications done through the compiling process.

Of course, I do the pre-processing and post-processing with a regular expression:

</?[\w]+:[^>]*/?>

 
which I think is kind of funny, in a way. I can never seem to escape regular expressions.

ASP.NET Ajax, FCKEditor and Firebug

Friday, February 13th, 2009

Firebugs

Today at work I had the pleasure of dealing with a functionality bug in our new CMS that is written in ASP.NET. Our CMS uses FCKEditor for the rich text editor, and we’re using a whole gang of ASP.NET Ajax stuff for the interface. Specifically, we’re using a TabContainer with user controls inside each tab.

The CMS is designed in the way that most CMS’s are – we have 2 major components. Page objects contain the content data of a page, so text, HTML meta data, etc. Template objects contain templates – that is, HTML files with areas where you insert the page content, similar to how Dreamweaver does it’s templates for you.

When you publish a page/site, the CMS compiles the content into the template, then saves that as a file. When you’re editing or creating a page in the admin interface, the application reads the content areas available in the current template you have selected for that page, and creates an FCKEditor dialog for it.

Because you might not know how the content you’re writing fits into the template you’re going to use, we provide a preview function. This preview function will read in the content of the FCKEditor dialogs, create a temporary page object, set the src of an iframe to our preview page, which takes the page objects and feed it to a preview function which will compile the page and return the string, which we dump to the output stream of the preview page. We then fire up the iframe inside an ASP.NET popup extender, for a nice modal preview.

This all worked fine, until we got the tab container involved.

In order to streamline the work flow and reduce the page refreshes on postbacks, we decided to put the content in a tab container, with different parts of the page in different tabs. When we did this, we noticed that when the preview button did a partial postback, it reloaded the FCKEditor dialogs from the database, obliterating the changes we made to the page (if any), or just displaying nothing for the content if it was a new page.

This was just on my computer.

On a co-workers computer, it worked perfectly as intended, despite the fact we were both working from the same source, in the same IDE, running it in the same browser. What gives?

After poking around on both computers and trying the application in different browsers, we concluded that it doesn’t work only in my Firefox – IE was fine on my computer, and all browsers were fine on his. Acting on a hunch, I disabled Firebug for my Firefox, because I noticed my co-worker didn’t have Firebug installed.

The application started working again.

I don’t know why this happens, and why Firebug should be interfering with the Javascript in an obtrusive way, or even which Javascript it’s interfering with. I don’t know if Firebug was screwing with FCKEditor or ASP.NET Ajax. So, this post is partially to put this info out there, in the hopes that someone else can answer for me.

It’s also partially to say, if you’re seeing odd behavior that seems to be cropping up inconsistently across machines running Firefox, try disabling Firebug. Since being done by Firebug, I’ve decided to leave it off during all development, and thinking back, I wonder how many other Javascript bugs I’ve fought with that were caused by Firebug, and not the code.

C# Interface Method Gotcha When Inheriting

Tuesday, February 3rd, 2009

I noticed some interesting behavior from C# yesterday at work. Truth be told, I’ve noticed this in the past, but I’ve only figured out what’s causing it today.

The behavior is this: when you inherit from a class that implements an interface, calling a hidden/overriden method from an object of the inheriting class that has been upcast to the interface will result in a call the the inherited function.

Ok, so that probably made no sense at all, which is why I will explain it, but not before a warning. I’m not sure if this is intended behavior, and I’m not sure if this is something I’m doing wrong. If someone can point me in the direction of an explanation or a correction, I would be very grateful.

Computer Bugs

On to the explanation.

Take a sample, trivial application that has widgets. These widgets just print messages out to the console. We have an interface, IWidget, which forms the contract for all widgets:

interface IWidget
{
    void DoSomething();
    void DoSomethingElse();
}

Next, we have a generic widget class, which we use for most widgets. This is called GenericWidget:

class GenericWidget : IWidget
{
    public void DoSomething()
    {
        Console.WriteLine("Doing something in GenericWidget");
    }

    public void DoSomethingElse()
    {
        Console.WriteLine("Doing something else in GenericWidget");
    }
}

 
And finally, we have a specific type of widget that does something different, called SpecificWidget:

class SpecificWidget : GenericWidget
{
    public new void  DoSomething()
    {
        Console.WriteLine("Doing something in SpecificWidget");
    }
    public new void DoSomethingElse()
    {
    Console.WriteLine("Doing something else in SpecificWidget");
    }
}

Now, we want to run some tests on our widgets, to see what’s going on. First, we’ll test the widgets themselves. Running:

GenericWidget genericWidget = new GenericWidget();
genericWidget.DoSomething();
genericWidget.DoSomethingElse();

SpecificWidget specificWidget = new SpecificWidget();
specificWidget.DoSomething();
specificWidget.DoSomethingElse();

 
will output:

Doing something in GenericWidget
Doing something else in GenericWidget

Doing something in SpecificWidget
Doing something else in SpecificWidget 

 Which is exactly what we expected to see. Test has passed.

Next, lets say we have a function that we want to pass widgets to, but we don’t know what kind of widgets we will be passing, only that they are widgets. So we pass them as widgets, but upcast them to IWidget, and call the methods on them from the interface. For example:

IWidget genericUpcast = new GenericWidget();
genericUpcast.DoSomething();
genericUpcast.DoSomethingElse();

IWidget specificUpcast = new SpecificWidget();
specificUpcast.DoSomething();
specificUpcast.DoSomethingElse();

 
which will give the following output:

Doing something in GenericWidget
Doing something else in GenericWidget

Doing something in GenericWidget
Doing something else in GenericWidget

Wait, that’s not right. The specificUpcast should call the method on SpecificWidget, shouldn’t it? At least, that’s my expected behavior. Just to prove there’s not something wrong with our specificUpcast:

(specificUpcast as SpecificWidget).DoSomething();
(specificUpcast as SpecificWidget).DoSomethingElse();

 
will yield:

Doing something in SpecificWidget
Doing something else in SpecificWidget 

which is our expected output all along.

If someone can explain this to me, or point me to a better method to upcast, then please do so. I’m finding a lot of my code needs to check for specific types in order to call the proper method, and it seems clunky and awkward. I’m sure I’m doing something wrong, I’m just not sure what.

As usual, you can find the source code here: Interface Upcasting Inherited Classes Gotcha

How To Run Your Own Webserver

Thursday, January 15th, 2009

For some time, I’ve run my own web server from the comfort of my own home. I made this decision due to the fact that I wanted more control over my server, and I wanted to run as many web development languages side by side as I could, and mainly because I wanted to run SVN. Before I started hosting my own websites, I had a sketchy knowledge of how the DNS works, and how to go about hosting your own websites on a Linux operating system. I also had minimal Linux administration skills.

There are a few good reasons for hosting your own website:

  1. No artificial caps on bandwidth and hard disk usage. You pay for what you use, and if you need more, you buy more.
  2. Total control over your hosting environment. If you want a language installed, install it. If you want to run a certain version of Rails, run it. It’s your server.
  3. Experience. Hosting your own websites on your own server can give you a lot of experience with systems administration on a server operating system.
  4. Cost. You have complete control over how much everything costs, and you know exactly where your money is going. You can spend as much or as little as you wanted.

How Do You Do It?

First, it helps to get an idea of what you really want. Do you want to run a huge corporate intranet with load balancing and proxy servers, or do you just want a small server to host personal sites and tinker? Is your budget limitless, or are you already living on ramen for dinner 5 nights a week? Do you want to host proprietary languages like Cold Fusion or ASP.NET, or will a Linux/Apache install satisfy you?

Personally, I was only interested in hosting personal sites, and doing it cheaply was my utmost concern. This is what I will focus on, as this is what I have experience in. So, what I was looking for was a relatively easy solution that was above all cheap.

1. Get Your Hardware

Before you can start, you need to have hardware to put your server on, and if you already don’t have it, appropriate networking gear to support multiple computers accessing the same internet connection (if you want to use a personal computer as well).

As your end goal is a web server, this server preferably needs to be up 24/7, which means whatever hardware you choose to run it on will essentially cease to exist with regards to usage. Most of the time, hopefully, you’ll never need to do much work on the server itself, only transferring data to and from it.

I already had my networking gear, and I commandeered an old desktop computer for my server. It was a Pentium IV 3.0GHz with 2GB of RAM. I found in the year or so I ran the server that my memory usage didn’t ever go above ~400mb. I also had a 120GB hard disk in there. This computer used to serve as my old gaming workstation, however I don’t play games much these days, and I bought a laptop that was more powerful.

Cost: Free

2. Get Your Software

I chose to run CentOS 5 as my Linux distribution. My choice was admittedly relatively arbitrary, however I was relatively happy with the choice. I installed the OS and included only the packages that I knew I needed – that meant no xserver, and no GUI. I was going to administrate this server via ssh on my laptop. I then updated the OS and installed all the required software.

I immediately recognised that it would be hard to individually install and hook up everything that I wanted to run, and decided to run a web-server software package to help. I eventually settled on Webmin after a few false starts, and Webmin proved to be very user friendly and relatively powerful. If I was doing the same thing again, I would be relatively comfortable doing it all individually without Webmin, but it was Webmin that provided me with a safety net while learning.

Cost: Free

3. Get Connected

I was already running the biggest Internet providing plan that my ISP offered. As I live in Australia, we have to live with usage caps on our Internet plans. Mine was 20GB download during peak traffic, 40GB download during off-peak, and unmetered upload. This was perfect for hosting a server, as most of my traffic was upload, once I got everything installed.

However, you do need more than just an Internet connection to get a server online, you also need a static IP address. Technically you can do it with a dynamic IP and a dynamic DNS service, however that was a level of complexity I didn’t have the patience to deal with. So I put a static IP on my account as well.

Cost: $10/month for the static IP, Internet was free because I was using the connection anyway

4. Get Hosted

This is the final step to getting your server ready to host websites. So far, you have a server with the software installed, and you have an Internet connection and a static IP. You can type your static IP in a browser and get your Webmin’s default landing page (if your router supports NAT  loopback, which mine didn’t). To get your web server attached to a domain name, you first must register the domain name, then point it to nameservers that run a DNS server. 

You could run the DNS server on the same machine, or a different machine, but that was all too complicated for me. I instead chose to get a hosted DNS solution with Nettica, and have Nettica manage my name servers. Then it was simply a matter of pointing my domains to the Nettica nameservers, pointing my Nettica entries to my server IP, and add the virtual servers with Webmin, letting it take care of configuring Apache for named virtual hosting.

Cost: $50/year

So that’s it. For about $170/year, I could host my own server and serve as many websites as I had room for on the Internet. I had complete control over the server, and I could install what I wanted, when I wanted.

I don’t run the server now, as I have recently moved to a location where I cannot justify it, but overall I found the experience very rewarding. Sure, you can get cheaper shared hosting, but there’s nothing like deciding you want to install, say, SVN and just installing it, and having it up and ready in 10 minutes for no charge.