Website Migrations: CodePlane, Nginx, Passenger

I’m just about done (famous last words) with a long, and not just a bit tedious, migration from Slicehost to Linode. Both are “cloud-style” VPSs, where you can do immediate one-click backups, cloning, upgrading, etc. As VPSs, you get to choose a raw initial Linux stack, and you’re then on your own to add on web servers, command-line tools, etc.

While SliceHost has worked out fine, notwithstanding [the 2008 exit of its founders]((http://37signals.com/founderstories/slicehost), Linode has much better rates these days and also seems to be gaining traction with the NodeJS community. Maybe it’s the fortunate name affinity. There’s also the distinct possibility Slicehost’s parent Rackspace will close down Slicehost itself and move things over to Rackspace. They also have great support docs. In any event, I’ve really been wanting to migrate from lighty to nginx and start using CodePlane for code repo, so I was going to be stuck doing some work anyway.

A few random notes …

Setup

I don’t intend this to be a review of Linode. Suffice to say, it was a super-easy process, and the Getting Started guide made everything nice and simple. Anyone coming from a similar environment like Slicehost would have no trouble. A nice bonus is the built-in monitoring charts, basically the kind of thing you’d get from a monit install, but right there on the admin panel, with no need to install anything. They’re powered by RRD.

Another nice bonus is ipv6 support. It’s been a long time coming, but I’m finally ready for the internet of IP-labelled things and beyond! 173.255.208.243? That’s not cool. You know what’s cool? 2600:3c01::f03c:91ff:fe93:5a3e/64.

Passenger on Nginx

I’d previously used Thin on Nginx, but Passenger promised to be a lot easier. Turned out maybe not, Passenger needs a custom Nginx install. I’d already set up Nginx with apt-get, and in retrospect, I should have tried to roll it back. So there was some challenges configuring things (the default Passenger-powered nginx goes into /opt/nginx, whereas the Ubuntu one is customised for the usual suspects on ubuntu, binary in /usr/sbin, conf in /etc/, and so on).

With the custom Passenger-powered Nginx, the core Nginx config needs no passenger or ruby reference. (ie You don’t do the apache/lighttpd equivalent of declaring a dynamic modules – the lack of such things is why the custom nginx install is necessary). You only need to declare passenger in the site-specific config. For a Sinatra app, with config.ru at /path/to, you do this:

server {
  passenger_enabled on;
  location /static {
  root /path/to/public;
  index index.html index.html;
}

(Yes, you never need to point directly to the config.ru or its directory.)

PHTML Suffix

I still have some weird bug preventing *.phtml files running. If no-one knows the answer, I’ll just rename it.

Mediawiki

After much messing around, I ended up with something that works for the (unendorsed, I think) “cool URI” scheme, i.e. site.com/EntryName. (versus site.com/index.php?title=EntryName).

  location / {
    rewrite ^/([a-zA-Z0-9_:]+)$ /wiki/index.php?title=$1 last;
    rewrite ^/$ /wiki/index.php?title=Main_Page last;
    root  /path/to/public;
  }

Self-explanatory I think. Along the way, I learned about nginx’s “try_files” mechanism, which fits nicely with many PHP CMSs like WordPress and Mediawiki, where a single front controller is the gateway to the entire app. You can do stuff like try_files $uri $uri/ /index.php?page=$request_uri…though I didn’t need it here.

WordPress

wordPress was similarly simple:

    if (!-e $request_filename) {
      rewrite ^/(.+)$ /index.php?p=$1 last;
    }

One quirk I discovered was I couldn’t do online changes using the SFTP facility. This happened at Slicehost too. I eventually discovered the cause. The directory needs to be owned by the webserver. The confusing thing is it looks like SFTP isn’t set up right or you have the password wrong or something. Glad to know this.

CodePlane

On a slightly separate note, I started using CodePlane as a code repo. It’s similar to GitHub’s private repo, but allows for unlimited projects. While I’d want to support GitHub, given all the value it provides, it’s not feasible to store dozens of small throwaway projects there, so CodePlane is really neat so far. And the developer is highly responsive. I noted on GetSatisfaction that the homepage doesn’t personalise if you’re logged in, he fixed it in a matter of hours. He’s also been open to engaging about some other suggestions I had. So it’s working out nicely so far.

Integrated Google Plus on the Homepage

I’m getting more convinced Plus is the new Twitter, and also the new Posterous. I’ve been posting things on there I previously would have stuck on the Twitter or the Posterous, and so it was time to integrate Plus on my homepage alongside the existing Twitter and Posterous links.

Latest Post

It was pretty easy to integrate my latest Google Plus post (we don’t really have a name for a Plus post yet; a plust?), as I already have a framework in place for showing the last post from an Atom or RSS feed.

First, I found my Plus feed URL thanks to Russell Beattie’s unofficial Plus Atom Feed service:

http://plusfeed.appspot.com/106413090159067280619

Using MagpieRSS, you can easily get the last post.

  1. define('MAGPIE_CACHE_ON', false);
  2.   require_once('magpierss/rss_fetch.inc');
  3.   $feed = "http://plusfeed.appspot.com/106413090159067280619";
  4.   try {
  5.     $rss = fetch_rss($feed);
  6.     $recent_post = $rss->items[0];
  7.     $title = $recent_post[title] . " ...";
  8.     $link = "http://mahemoff.com/+", $recent_post[link];
  9.     $timeAgo = timeAgo(strtotime($recent_post[updated]));
  10.     // show the post
  11.   } catch(Exception $ex) {
  12.     // log exception
  13.   }

Me

Inside the CSS3-rendered vcard, there’s a link to my plus alongside twitter etc.:

  1. <a rel="me" class="url" href="https://plus.google.com/106413090159067280619">plus</a>

/+ …. redirect to Plus

Following Tim Bray’s suggestion, I redirected http://mahemoff.com/+ to the plus page. It’s nice to have a memorable URL.

A Contact Form

I recently got fed up of spam. Well, that happened a long time ago. What bothered me recently, enough to take action, was false positives, i.e. real email that fell into my spam folder. My primary email address, michael@mahemoff.com, gets about 3000 mails a day…so what goes in my spam folder, stays in my spam folder. There’s no way known I will ever fish it out.

People I know usually get through to me okay, but of course I also receive mails from people I don’t know – who found my mail from my blog, websites, writings, or offline meetings. For them, there’s a good chance of being marked as spam, especially if they use a subject line like “hello” which is a perfectly natural thing to do when you’re just checking in with someone you’ve met at a conference, for example, so you can keep each other’s contact details. (Incidentally, I still find it astonishing how many people maintain blogs – many of them meticulous, comprehensive, and full of goodness – but include zero contact info.)

So I finally bit the bullet and made a little PHP/Javascript contact form. It’s been working great for several months now. This kind of form is nothing new, of course. Mail forms were once ubiquitous in every book on CGI. But there were a few modern twists worth mentioning.

The form looks as follows:

The gnarly twists:

  • Captcha. Or, really, ReCaptcha. Actually, I prefer Captcha to ReCaptcha – I think the benefit of scanning books is great, but can’t justify the usability cost of having to enter two words instead of one (for no extra security benefit). Still, I wanted to try out ReCaptcha, and I also like the way its a popular, centralised, service, which means it should be better at detecting evil clients than a standalone library installation. The PHP plugin and instructions turned out to be incredibly easy to follow. A pleasant surprise that meant spam prevention took about 20 minutes to set up in total.
  • SMS option. Instead of email, you can send the message as SMS (text message to my phone). I need to improve the UI here a bit, ideally creating separate tabs for SMS and email. Anyway, the way this works is via everybody’s favourite micro-blogging service, Twitter. On the Twitter website, I set preferences so direct messages are routed to my phone as SMS messages. Ideally, I would then send a direct message to myself each time someone wants to SMS me. But unfortunately Twitter doesn’t let you send messages to yourself (silly!), so I created a secondary account (the venerable “mahemoff1”). Each time someone submits a SMS, I use the Twitter API to end a direct message from the secondary account to the primary account. This gets me a text message several seconds after the form is submitted. I also receive a copy in my Twitter account, as a bonus. (For all the talk about Twitter’s unreliability, its text messaging is lightning fast. It shows up on my phone long before it shows up on Air clients, which only poll once a minute or so. Ideally I’d upload a video if I had the time, to show how quick it is.)
  • A web chat facility. Everyone should have it, to avoid making people install AIM etc just to chat with you one time! I installed an open-source chat client so anyone can talk to me. In an ideal world, browsers would notify me when someone is trying to chat, but for now, it requires pre-arrangement. I would like to enhance the app so it uses the same SMS mechanism to tell me each time someone enters the chat room.

A URL Parameter Engine (and Rambling about PHP Globals)

I’ve recently been playing around with PHP again, because (a) it’s vastly simpler to deploy personal projects in PHP than any other platform (aside from pure client-side Ajax of course!) (b) it’s so easy to get simple stuff done.

Anyway, one thing I’m doing is creating a RESTful service where parameter crunching is at an all-time high. The ancient way this was done was with magically created globals. i.e. For the URL http://example.com?id=10, you would end up with a global called $id, set to 10. But the more contemporary way to do it is to use a global array called $_GET, i.e. $_GET[$id]. This is considered safer, to ensure malicious users don’t set important globals. And in PHP 6.0, the former way is being obliterated altogether, since the relevant configuration option – register_globals is being altogether removed.

Well, to me, this is throwing out the baby with the bathwater.

This comes down to how you view PHP. For me, if I want to build a massive, complex, piece of software, I will use Rails or Java. So I consider PHP a scripting language and I value concise expression highly. Features like namespaces (to be added in PHP 6) and even OO don’t mean all that much to me in this language. I am much more concerned with syntactic sugar.

Thus, I would prefer to see templates look like this:

  1. Your name: <?= $name ?>

… and not:

  1. Your name: <?= $_GET&#91;"name"] ?>

A little thing, but in the context of a large corpus of templates, each with many variables, it makes a big difference.

So I’m working on a little parameter-processing engine which will let me use the “evil” $globalVar notation, but in a way that requires each script to pass in a whitelist of acceptable variable names. It also has some other value-adds, such as passing in default values. And these default values can be other parameters that were passed in.

(Incidentally, even if I wasn’t building this script, the first thing I would do would be to globally alias $G or to the uglier and more verbose $_GET.)

REST turns the URL into a command line, and this should push web framework developers towards smarter ways of processing parameters. Think Getopts, but for the URL instead of the shell command line. And that’s where I’m heading.

Ajax Patterns Code Now Available

All code for the Ajax Patterns demos is now available. This is the code used as examples for many of the patterns at AjaxPatterns.org, as well as the Pattern-Led Tutorial that forms Chapter 2 of the “Ajax Design Patterns” book to be published next month.

Download the code – ajaxdemos.zip.

Read the installation notes. Basically, you need PHP and Apache, and optionally MySQL is required for the wiki demos. The install should be pretty basic, as the notes indicate:

* Unzip the package to a temporary location and copy
  run/, tutorial/, and records/ to the apache document root.
  Assuming the doc root is /apache/document/root:

cp run tutorial records /apache/document/root.

(Alternatively, if you have sufficient access, set up a new virtual host in apache's httpd.conf and point it to the root of the unzipped directory, ajaxdemos/).

  • Ensure the server can write to (the initially empty) records/ directory. The easiest (though not the most secure) way is:

    chmod 777 apache/document/root/records

  • Open up run/.htaccess and follow instructions there to set the library path.

  • Finished!

You might wonder why the server-side uses PHP, when I’m more of a Java+Ruby kind of guy. Realistically, the choice was Java versus PHP due to popularity. PHP was chosen because the code needs to be easy to install, and LAMP is a lot more ubiquitous and easier to work with than integrating Java+Tomcat+MySQL together. I understand Java is at least shipping with Debian at some point, but right now, there’s few things easier than getting a LAMP setup running, especially with all the one-click installers around (http://www.apachefriends.org/en/xampp.html).

From a development perspective, I also found PHP more productive for the experimental style of development that went into the Ajax demos. The usual drivers for Java – maintainability, security, etc. – weren’t a factor. PHP also has the sort-of-merit of being the Switzerland of server-side languages. Use Perl, Java, C#, or Rails, and you’re going to be flamed loudly from some contingent. But use PHP and most non-PHP coders will say something about it would have been nice if you’d used Java/etc but I can see your point and shrug their shoulders a bit. As it happens, only a few patterns (need to) delve into server-side details, so the only real impact of using PHP is if people want to hack the code or look further into the details of implementing a pattern.

State of the Ajax Frameworks

The publicly-editable Ajax Frameworks Page got a nice kick along in the past few days, presumably due to a recent link from Ajaxian. If this list is anything to go by, the most common language is pure-Javascript, and Java is, as you might have guessed, highest on the server-side, followed by .Net and PHP. Sections for Python and Perl were opened up during this time. Thanks for your contributions!

1 Pure Javascript: Application Frameworks

  • 1.1 Isomorphic (Commercial RIA Toolkit)
  • 1.2 Bindows (Since 2003)
  • 1.3 BackBase (from 2003)
  • 1.4 DOJO (Under development; from September, 2004)
  • 1.5 Open Rico (Under development; from May, 2005; based on earlier proprietary framework)
  • 1.6 qooxdoo (Under development; from May, 2005)
  • 1.7 Tibet (Under development; from June, 2005)
  • 1.8 AJFORM (Since June 2005)
  • 1.9 ThyAPI (Under development; Since end of 2004)

2 Pure Javascript: Infrastructural Frameworks

  • 2.1 AjaxCaller (Alpha; from May 2005)
  • 2.2 Flash JavaScript Integration Kit ()
  • 2.3 Google AJAXSLT (Released June 2005)
  • 2.4 HTMLHttpRequest (Beta; from 2005)
  • 2.5 Interactive Website Framework (from May 2005)
  • 2.6 LibXMLHttpRequest (Released; June 2003)
  • 2.7 MAJAX (Released; August 2005)
  • 2.8 RSLite (x)
  • 2.9 Sack (In development; from May 2005)
  • 2.10 Sarissa (Released; from February, 2003)
  • 2.11 XHConn (Released; from April, 2005)

3 Server-Side: Multi-Language

  • 3.1 Cross-Platform Asynchronous INterface Toolkit (May 2005)
  • 3.2 SAJAX (Workable but not 1.0; from ?March 2005)
  • 3.3 Javascipt Object Notation (JSON) and JSON-RPC
  • 3.4 Javascript Remote Scripting (JSRS) (from 2000)
  • 3.5 Bitkraft for ASP.NET

4 Server-Side: Python

  • 4.1 CrackAJAX

5 Server-Side: Java

  • 5.1 WebORB for Java (from August 2005)
  • 5.2 Echo 2 (from March 2005)
  • 5.3 WidgetServer (2004)
  • 5.4 Direct Web Remoting (DWR) (2005)
  • 5.5 SWATO (2005)
  • 5.6 AJAX JSP Tag Library
  • 5.7 AJAX Java Server Faces Framework
  • 5.8 ThinkCAP JX: RAD Environment for AJAX, J2EE, and Open Source (Commercial Framework)
  • 5.9 Struts-Layout

6 Server-Side: Lisp

  • 6.1 CL-Ajax

7 Server-Side: .NET

  • 7.1 MonoRail (from May 2005)
  • 7.2 WebORB for .NET (from August 2005)
  • 7.3 Ajax.NET (from March 2005)
  • 7.4 ComfortASP.NET (from August2005)
  • 7.5 AjaxAspects (from August 2005)

8 Server-Side: Perl

  • 8.1 CGI::Ajax – Export perl methods to javascript for AJAX

9 Server-Side: PHP

  • 9.1 AjaxAC (From April, 2005)
  • 9.2 JPSpan
  • 9.3 XAJAX
  • 9.4 PEAR::HTML::Ajax
  • 9.5 CPAINT

10 Server-Side: Ruby

  • 10.1 Ruby On Rails