How to migrate from Posterous to CloudFiles

Ever since Posterous announced they had been “acqui-hired” by Twitter I've been looking for new home for my blog. I knew I wanted to go back to a solution I could control but I didn't want to deal with Wordpress or having to manage a cloud servers instance. In fact this is what my requirements looked like:

  • Full control (not a third party service)
  • No infrastructure required
  • Not bloated (no wordpress)
  • Supports writing posts in markdown
  • Lets me get back to using my own domain

Once we released StaticWeb support on Rackspace CloudFiles I knew I wanted to go a static blog route. The only question then was what to use. I looked at Jekyll (bootstrap), Octopress, and Pelican. Originally, I choose Pelican but due to import issues I ended up settling on Octopress. If I was starting from scratch I would absolutely start with Pelican. I'll leave why I was picking from these 3 for another day. For now lets just talk about how I migrated from Posterous to Octopress on CloudFiles.

Installing Octopress

Nothing special here. I just followed the instructions on octopress.org to get octopress installed on my local dev vm. I could have just installed it locally on my Mac but I like keeping my Mac "clean". Since I was also going to be using the import scripts from Jekyll I also went a head installed the Jekyll gem:

fhines@ubuntu:~/octopress (master)$ gem install jekyll

Importing content from Posterous

Unfortunately, Posterous hasn't made a an export tool available. However, I still had 2 good paths to try to rescue my content. Jekyll ships with scripts to import directly from the Posterous API or from a Wordpress.com exported xml file. There is a ton of options no matter where you're migrating from (Tumbler, Posterous, etc). The Jekyll Blog Migrations page details them all.

The first two posterous import scripts I tried threw various errors. So I actually went the following route so that I could use the wordpress.com import method:

  1. Sign up for a free wordpress.com account.
  2. Imported from posterous to wordpress.com
  3. Exported my wordpress content to a .xml file which I saved as wordpress.xml
  4. Install hpricot gem install hpricot
  5. cd to the source directory of your octopress install

Now run the import:

Imported 84 attachments
Imported 1 pages
Imported 70 posts

That dumps all of your posts in to the '_posts' directory. Unfortunately, that didn't export my media from Wordpress.com.

I ended up manually downloading my images from Wordpress.com and uploaded them to CloudFiles using GunnarApp. I'd already had a CloudFiles container setup and mapped to img.ronin.io. So I just used Gunnar to upload all the content there. Then I simply updated all my posts to link to http://img.ronin.io rather than http://pandemicsyn.files.wordpress.com

Getting your content hosted on CloudFiles and served via StaticWeb and Akamai.

This, is the easiest part. At this point you've got octopress installed and your content is ready to go.

Installing Swiftly the awesome swift cli tool

If you need to access CloudFiles the swiftly cli tool is an awesome way to do it. It's what I'm currently using to upload my blog content to CloudFiles.

  1. cd ~; git clone https://github.com/gholt/swiftly.git
  2. cd swiftly; sudo python setup.py install

Add the following three lines to your .profile/.bashrc etc to make using it a bit faster:

export SWIFTLY_AUTH_URL="https://auth.api.rackspacecloud.com/v1.0"
export SWIFTLY_AUTH_USER="yourCloudFilesUsername"
export SWIFTLY_AUTH_KEY="yourCloudFIlesAPIKey"

Of course you can also always use something like CyberDuck to upload your blog. I just prefer using the command line.

Create container to use and CDN enable it

  1. Either through the API, CyberDuck, or the Rackspace Control Panel create a CloudFiles container called "public" and cdn enable it. Be sure to note the containers cdn url. In my case it was c3444344.r44.cf0.rackcdn.com. While you’re at it, you should drop the containers CDN TTL to the minimum (900 seconds or 1 hour if you’re doing it via the control panel).

Setup your StaticWeb index page with swiftly

Next we need to tell CloudFiles what we want to use as the index page:

  1. swiftly put public -h X-Container-Meta-Web-Index:index.html
  2. Verify the X-Container-Meta-Web-Index headers shows up.

To verify the header is present run:

fhines@ubuntu:~/octopress (master)$ swiftly get public --headers | head -n 10
X-Container-Bytes-Used:    0
X-Container-Meta-Web-Index: index.html
X-Container-Object-Count:  0
X-Timestamp:               1338787149.54098
X-Trans-Id:                tx5c5fe6ebae214187b4b4103304f46c43

Setup a CNAME

Now you can setup a CNAME to point your domain to the cdn enabled container. In my case I just pointed http://syn.ronin.io to my cdn url:

syn.ronin.io. 5 IN CNAME c3444344.r44.cf0.rackcdn.com.

Generate your content and upload it

Nearly done! Now you just need to generate your content and push content up to CloudFiles

  1. rake generate
  2. swiftly -A put public -i public

You should now be able to browse to your CDN enabled container i.e. http://c3444344.r44.cf0.rackcdn.com or using the CNAME you setup.

Your post workflow:

Whenever you add another post or page you'll want to re-upload your content after running rake generate. If you're using swiftly you can actually use the -d option to only upload changed files:

swiftly put public -i public -d

To make things quicker I created the following bash alias:

alias postit='rake generate && swiftly put public -i public'

Now once I'm done writing a post I just run postit to generate the content and push it to CloudFiles.