21 April 2008

Movable Type 4 Setup on Ubuntu

I am in the process of consolidating my blogs to a single system, and in doing so, am switching to Movable Type. This blog will eventually move, but the initial impetus was for some other blogs that were running on WordPress where I was having some problems (and spent way too much time trying to fix that - one of the key things I don't want to be doing with my blog system). But, in relation, I found the setup instructions for Movable Type a bit lacking, especially in relation to using multiple blogs, and how this works in terms of Apache and MT setup.

I also want to say a bit thanks to Duncan for showing me his Apache config, and some brief discussion of multiple blogs with MT. The MT docs were really lacking here as said, but Duncan's knowledge made it clear this was pretty easy and a nice way to go. Thanks Duncan, and check out his blog and site, and of course all his great pics on Flickr.

I am using a single installation of Movable Type, supporting multiple blogs, with each blog having their own domain name, and that blog (or really the MT content) living at the root of that domain name (this last part isn't required/essentially for this tutorial, you can easily tweak the Apache config).

So, with that, given that it actually turns out to be relatively simple to set up once you know a few key bits, I figured I'd pass along what I did...

First, I created my standard Ubuntu slice at Slicehost. I host everything with them these days, and as such, I have a base system image that I've built for myself. It's built with their standard Ubuntu 7.10 choice, and then I make tweaks to the SSH setup, add a few bits I need, etc. But, I believe you could simply take pretty much a standard Ubuntu server install and use that. Please let me know if this guide doesn't work for you in that case.

Preparations



In preparation for the move, while my existing blogs were running, I exported their data from WordPress using WordPress' Export feature, which produces a WXR file. Save that to my local machine.

I also made sure I had my domain names secured, and the DNS for them setup. In particular, one thing to note is that Movable Type is sort of a two part system. You have the MT web application, which is a publishing application, but is not what someone hits when visiting your blog(s). MT publishes your blog out as static content (or that's the default option anyway). So, I setup an "mt" subdomain on one of my domains where I will access MT (more on that below).

Apache and Perl Install



Apache 2 and mod_perl were not on my system by default, so I needed to install those. This amounts to:
sudo apt-get install apache2 libapache2-mod-perl2 libapache2-mod-perl2-doc

The above will not only install it, but configure mod_perl for use in Apache, and you can now run Perl based web apps (MT is developed in Perl). Also, depending on how you want to do email, you may need to install Perl's Mail::Sendmail (if using SMTP; if you use sendmail, then you can choose that when setting up MT):

sudo perl -MCPAN -e "install Mail::Sendmail"



Create a Database



I created a database for MT using MySQL. I also setup a specific MySQL user, password, and assigned them rights to that database. You'll need this info later when setting up/configuring MT.

I have been using Navicat for nearly all my DB management. It works really well given it can do SSH tunneling as I don't open the MySQL port on my servers, etc. It is a commercial app, but as a developer who works with DB's often, has proven to be my tool of choice (I've tried many others, and this is the one that's worked best for me).

Apache Configuration



I have a relatively minimal Apache configuration file. The bulk of it is done with a file that sets up my virtual hosts (several domains point to a single machine). The setup for MT has a few critical pieces:

  • Setting a ScriptAlias for the "mt" directory, so mod_perl knows to execute .cgi files there.

  • Setting an Alias for the "mt-static" directory, which is MT's static content, and which you'll want to be referenced from all your blogs. You can also do this with a symlink, but I've done it with an Apache alias below so that I don't have to worry about a given blog's static content getting wiped out and breaking this (if the static content gets wiped out, you can just republish in MT to restore it, so I prefer to keep that purely maintained by MT).

  • Setup the proper options/settings for the MT directory.



Thus, my configuration for my virtual hosts looks like the following (fake domain names used), notes following:


NameVirtualHost *
<VirtualHost *>
ServerAdmin chris@example.com
ServerName mt.example.net
DocumentRoot /var/www/mt

Alias /mt-static /var/www/mt/mt-static
<Directory /var/www/mt/mt-static>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>

ScriptAlias / /var/www/mt/
<Directory /var/www/mt>
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

<VirtualHost *>
ServerAdmin chris@example.com
ServerName example.com
ServerAlias example.com www. example.com
DocumentRoot /var/www/example

Alias /mt-static /var/www/mt/mt-static
<Directory /var/www/mt/mt-static>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
Redirect /mt.cgi http://mt.example.net/mt.cgi
</VirtualHost>


The first VirtualHost block sets up where I'll access MT, thus at http://mt.example.com. There you will see both the Alias for mt-static, and also the ScriptAlias for mt. These are critical.

The second Virtual Host block defines one of the actual blogs, which will be accessible at http://example.com or http://www.example.com. For additional blogs, you would add another of these blocks per domain name. The key bits here are the DocumentRoot and the Alias for mt-static. The DocumentRoot is where you will have MT publish your static blog content. Make sure that directory is writable by Apache/MT.

Finally, the Redirect sets things up so that when you are logged in and visit your blog, and see the various links for "Edit this content" that those will actually work (they point to mt.cgi, so this redirects them to whatever domain is serving mt).

Setup Movable Type



Next, visit http://mt.example.com/mt.cgi in your browser to begin setting up and configurating Movable Type. It will ask you about your database, and a few other bits, and then prompt you to create the first blog. Make sure the blog URL and directory match what you setup in your Apache configuration above. Beyond this you will need to refer to Movable Type docs for questions. But, you should essentially have a blog running, and will just need to Publish it to have MT write the static files into the directory you've defined.

The last step for me was to import my blog content from my prior WordPress setup, using the WXR dump I created at the beginning of all this. One key note here. When you go into MT's Import page - choose the blog you want to import to (even if you only have one) first. Only then when you pick WXR (if appropriate) for your import will it give you the proper fields for the info it needs for the WXR import. Otherwise it'll set your import type back to MovableType, and claim it has read in your import file fine (but you'll of course have no content).

I'm still tweaking my templates and doing a few bits to the sites I'm moving over, so I'm off to continue on that. Hope this helps someone.

16 April 2008

Working at Home, The Zone, and Importance of Equipment

Recently, there was a good writeup at Hivelogic on Offices and the Creativity Zone. This is partially also in response to the Jason Calcanas' post on how to save money, 37 Signals response, and so on. I'm getting around to my thoughts/response, as someone who has been working at home for about 60% of the last 10 years.

I'd like to comment on/respond to a few things, in particular:


  • chairs and desks

  • pair programming

  • "The Creativity Zone", as well as working in coffee shops

  • what I think is important for a home office - and in working at home

  • passion for your work, and the relation of that and hours put in at startups



Chairs and Desks



First, chairs and desks. As most folks will say, do NOT skimp on a chair. Go straight to a Herman Miller Aeron, or a Human Scale chair, do not pass go. I'll wait. I've had my posterior in an Aeron since I started at Adobe (thank you Adobe!) in 1996. When I moved, and was no longer working in the office, I used their program that allowed employees to buy these chairs at a discount, and picked one up for $500. I'd have gladly paid full price. Additionally, make sure you get the proper size, it makes a huge difference!

Following on that, I completely disagree on getting cheap desks, or doing the door/board on top of a file cabinet approach mentioned in Calcanas' post. I don't think you need to spend a lot on a desk, afterall, you just need a good surface. However, the key here is getting a desk that is the proper height. If you do the file cabinets thing, or buy your average stock desk they are almost always too tall. Take it from me, I'm 6'2" tall, and these desks are still too tall if you properly set your chair height (thighs level, feet flat on ground, forearms level or close to it, etc.). So, I suggest finding adjustable height desks, or if you are building your own, to make sure you figure out the proper height. I've been using Anthro's AnthroBench desks, which are not cheap, but are kick ass. However, the height adjustment is non-trivial, so you mostly have to get it right the first time. I've seen some since, that consumers can buy, that have more of an infinite height adjustment (which is what we had with the desks at Adobe, but I was unable to buy those).

Pair Programming



I'll cut to the chase: I'm not into it. I know folks who are and swear by it (e.g. Pivotal Labs does it the most and best I've ever seen). But, it's not for me. It doesn't fit with the way I think and work. I like a personalized environment, I like things quiet, and I like a bit more free flow. I also don't feel that it is a guarantee of better code quality.

Some of the complications to me are all the personalization developers like to do, whether that be fonts, keyboards, screen arrangements, colors, coding styles, and so on. Some of that can be worked around, but I'm simply not a fan, and don't believe it's the big advantage various others believe it is. But, in the same note, if it works for you, you prefer it, and you find someone/people to pair with that works well, then more power to you.

Also, I have a long history of doing remote work, working with other remote folks, and so on, and that is either impossible, or mostly defeats pair programming (Pivotal may disagree, but I do know they've had some hardships in this area as well). Differing time zones are not friendly to pair programming.

All this also ties into the next topic...

The Creativity Zone



I think Hivelogic nails it with this:
Unfortunately, most people can’t simply step into The Zone. In the very same way you’d want to find the right time and place to read a book, creative types need to setup the specific conditions they need to enter The Zone. For some people, this might mean listening to a certain kind of music. It might be fueled by caffeine and a dark room late at night. Some people work best in the silence of the early morning. It all depends on the person.


As you can guess from my pair programming comments above, I agree about having the right environment, and that you can't just force the work to flow. I've worked with a lot of different folks. Some people like to listen to music, some don't. Those that do range from listening to classical on low volumn to high volumn metal. Some work at night best, others can do the 9-5 thing, etc. This to me is similar to the situation of working in a cafe.

I think working in cafes is not good. I'm ok with popping in for an espresso, having a casual meeting there, or just using it to take a break from the office (whether that be a company office, or home office), and just checking email or reading RSS, or what not. But I don't buy it for serious work, and secondarily, I think you people who do do that suck. Yep, straight up, you suck. You go into a coffee shop, and take up space, and then ignore everyone. Why are you there? And why do you think that's fair? You are in no way contributing to the "cafe culture" or environment of a cafe, you are detracting from it. I was glad to see Ritual take away outlets and such. You shouldn't be sitting there for hours on end leeching from them.

And furthermore, I simply don't buy it as a productive environment, even when you wall yourself off from what is around you - which by definition tells me you don't think it's a productive environment either, otherwise you wouldn't need to bring your headphones and ignore everyone and all that.

Instead, make yourself a nice home office. There are a ton of resources on the web on how to do this if you need some pointers. Which leads me to...

What's Important in a Home Office - And In Working at Home



The above referenced articles already cover some of this, I'll try to be brief. Bring on the bullets:

  • Great chair and desk, see above

  • Proper lighting. In this I mean both the actual lights, but also how windows affect your workspace. Do not face directly into a window, as much as the view may be awesome. Usually you want windows on the side of you (not in front or back). I have a nice forest, mostly, to look out on my left side window - easy enough when I need a break to just turn my head.

  • A separate room. Not everyone can do this, but I feel VERY strongly about this if you plan to do significant amounts of work at home. You need a space that you can go to that is your office, where you can make a shift into work mode, have some isolation, close doors (so phone calls are quiet and so you can work without distraction), etc. It doesn't have to be huge, but make it your office space.

  • Good machine and monitor(s). Big monitors are key. I use a MacBook Pro as my main machine, but have an external 24" monitor (I want to go to a 30" when I can) on it as well, and an external keyboard is good too.

  • I feel you shouldn't have a beverage bar in your office. Just keep it in the kitchen, save electricity or whatever. But, for me, this is a good way to force me to get up and walk a bit, allows some different thinking time, etc. I almost always have a glass of water on my desk, but I get up to make an espresso, or maybe grab some fruit, or whatever. The break is always good.

  • Ok, I used to laugh at this recommendation, but I'm now one who does it, although I don't think it's required... Get up, and take a shower, get dressed, etc. I mention this for the two reasons I need to do it (but if you don't, then no biggy): I am not a morning person. I need to wake up a bit slower, and I prefer less interaction with people when I first get up. So, for me, what I've found is great, is to get up, and go shower. It is my way of having a slower re-entry. But, it also helps shift me into work mode (even if I don't wind up "going to work" for another hour or two. It flips that switch more explicitly for me.



That's all for now, as I want to get on to the last point...

Passion



In some of the referenced articles, and this has grown to be discussed a lot in reference to these, there is mention of whether folks need to be work-a-holics to have a successful startup. 37 Signals says to fire them. Calcanas mostly the opposite. I'm very strongly in the 37 Signals camp on this - to me it all comes down to passion. I believe this beyond startups as well, and it's one reason I just have no interest in working for larger companies anymore, because I feel the logistics simply make it a lot harder to have everyone be passionate. But, in the end, the folks I want to work with are passionate about their work/the project. This is how I want to be with what I'm working on. Sure, there are always parts that aren't as fun, but the overall idea is to have an overarching passion for what you're doing. To me that produces the best result, regardless of actual hours worked. In fact, I'd argue that you will get FAR better results from passionate folks working moderate hours, than simply a box of people putting in massive hours.

I recall we used to joke about how there was this notion that at Oracle (or substitute various others), all the engineers worked 80 hour weeks. That was BS of course. Note, I haven't worked at Oracle, but know folks who did, although that is somewhat beside the point... They may have been at the office 80 hours a week, but there is no way they were productively cranking out great work for all 80 hours. No, they were going to the gym, eating in the cafes, goofing off, or half awake at the keyboard. Recipe for burnout.

Now, as long as you have the passion, that's the key to me. After that, if you want to put in some epic hours because you're so psyched to be moving some great project forward, that's cool. I've done it. I don't think it's something that's sustainable long term, but bursts of this are great, go for it.

Right now, to share a bit, I'm making less money than I have in a long long time, but I'm more psyched than I probably ever have been, on the work I'm doing. I'm hoping the money part changes as the startups I'm working on grow, but I'm just loving it. Working with others who are passionate, working on cool stuff, running the show myself, or being involved at fundamental levels is why I left the mothership, and I really just wish I'd left sooner. I can get into that Creative Zone every day, and I look forward to doing so!

So, I recommend you think hard about your work environment, how you make for a productive and enjoyable environment. But most of all, shoot for the passion, and mold your environment to support and foster that passion.

11 April 2008

Shoulda and object_daddy Sitting in a Tree, t-e-s-t-i-n-g

Like some other folks working with Rails, I've been a bit frustrated with Fixtures. Foxy Fixtures, Rathole, and such things, including what is in Rails 2, have helped a lot. However, the two biggest frustrations for me come down to the fragility of fixtures, and knowing what fixtures you have and how they relate to their associated fixtures. I would find myself thinking, "hmm, which user do I use when I want the one with X associations" or what not. Naming your fixtures well helps, but only so much.

Lately, I've come across two plugins that I am really loving. These are Shoulda and object_daddy. Shoulda seems to be gaining in popularity in the Rails community, which doesn't surprise me. It gives you some of the best syntax of RSpec, without having to use RSpec (which I am not all in love with, unlike various others), as well as it gives you some nice "should" methods, and other features I'll get into in a minute.

object_daddy I think is rather obscure. I only found out about it due to Tammer Saleh's presentation (video link) on Shoulda from the 2008 MountainWest RubyConf. object_daddy has improved in its short life, and is quite useful today. What it does, is provide a factory/generator mechanism for creating model objects. I've done this in the past with object constructors or factories, etc., but object_daddy organizes all this, and provides a slick mechanism, called "exemplars", that specify how model attributes are defined when generating objects, and more importantly, when generating multiple objects. Tammer covers this issue in his presentation, which I highly recommend watching.

It's taken me a bit of time/use of Shoulda to get really into it, but like so many things, use it a bit and then the light bulb not only goes off, but seems to erupt with light. The big one here for me was how to leverage contexts, and by that I really mean nested contexts. My tests now not only read better, but can be written in a much nicer fashion, as well as organized in a great way. On the organization front for example, I now often have two top level contexts in a functional test: one for cases where I'm testing actions without a user being logged in, and the other for when a user is logged in. Great way to group them.

But, what's got me most excited lately is the combination of these two testing tools, and what it's done to my tests. First, I've darn near eliminated fixtures on the project I'm using this most with so far. This has removed the fragility, as well as it's just FAR easier to understand a test case's setup/scenario. I use Shoulda's contexts and setup, combined with generated objects from object_daddy to create "scenarios" (to steal the term from the plugin that provides this kind of thing for fixtures). The benefit is that you have all of the info about your test right there in one place in front of you. You don't need to bounce between likely multiple fixture files and your test code file to ascertain what's being used in your test. Plus, you can be very specific about the data being used in that particular test (or tests).

I heartily recommend you try this out. Two other things of note:


  • Shoulda can be mixed in with existing TestUnit. So, you can slowly convert to it, or just build new tests with it, etc. Very nice. And, it doesn't require anything special to run the tests (it really is just a method generator for building TestUnit tests).

  • Check out Shoulda's "should_eventually" method. I'm making more and more use of this, as I use a Test First approach. So, I go in, and build lots of tests, and do a lot of "should_eventually" as I think of things to test and functionality I need, etc. Then as I determine how to write those tests, and following on from that, write the implementation, you simply remove the "_eventually" and let it rip.



Note, if you are an RSpec fan, you can of course achieve the same as Shoulda for contexts and such (I think anyway), so just pull in object_daddy and leverage that aspect.

And last, but not least, I've forked object_daddy to make one tiny change (a single line, actually, a single method call name change!) that's made a big difference for me (comments very welcome). This change is to, by default, call create in the generate method that object_daddy adds to your ActiveRecord objects, instead of calling new. This avoids what I found to be the common case of doing:

my_new_object = SomeModel.generate
my_new_object.save
my_new_object # or some use of it

Now, you can simply call SomeModel.generate, and use that inline, knowing it's saved in the DB, etc. I want to take a look at adding options to generate, or additional generate methods that provide the flexibility to use new, or create! or such things, for the cases where those are needed. My fork is hosted on GitHub, and is public, so feel free to check it out: http://github.com/chris/object_daddy.

p.s. For those that wonder why I've "all but eliminated fixtures", as in, what do I still have in fixtures? The only things are standard data, which in my case amounts to a couple specific users, and a couple of Roles and Permissions. These normally get setup in the DB migrations, but I'm working through what Rails does when you run tests and it wipes the DB clean (and thus doesn't pick up seed data from migrations), and other such issues.

07 April 2008

Setting up CruiseControl.rb with/for Git Based Projects

[Updated to refer to official ThoughtWorks CC.rb Git repo.]



I have a new Rails project I'm working on and I use Git/GitHub for source control. It was time to setup continuous integration, and my usual weapon of choice for that is CruiseControl.rb. Here's what I did to get my project setup under CruiseControl.rb with Git, on an Ubuntu 7.10 machine...



Setup for accessing GitHub repo


All I needed to do here was generate an SSH key for my account on the host machine, and then add that key to the allowed keys for my GitHub account.

Prerequisites



  • I setup a builder@mydomain.com email address which will get used by CruiseControl for sending build related emails/notifications.

  • You'll need to determine a port you want CruiseControl to run on, and your strategy for accessing it. For example, I run mine on a port other than port 80, and other than the default 3333. I then proxy that via Nginx, and also use Nginx to password protect access to it (since this is not a public project, etc. This will affect the CC dashboard URL setting specified below. Some notes on this:


    • I did my initial Nginx configuration using err's Nginx config generator. However, this makes a lot of path assumptions, and various other things, so you'll definitely want to go through the resulting file closely. I had a few sites on this server, so it was relatively useful to use this as a base starting point, and then just fix up paths to the access and error logs, and the PID file.

    • Here's a quicky on how to add password protection to an Nginx server (and a specific location).




Install CruiseControl and Do Site Configuration



  1. Cloned the Git version of CruiseControl.rb in location I wanted it (you could also simply download it and expand the tarball): git clone git://github.com/benburkert/cruisecontrolrb.git

  2. The DEPENDENCIES file indicated I needed to have the grit and mime-types gems, so installed those.

  3. Where your projects get stored for CruiseControl.rb is now defined by the CRUISE_DATA_ROOT environment variable, and if you don't set this, it defaults to $HOME/.cruise. I personally changed this to be /var/cruisecontrolrb.
  4. Edit the config/site_configuration.rb (probably need to rename the example version accordingly) to set site-wide settings, such as your email config and so on.

    • For email setup, I use Gmail for domains, so I have a block like this:

      ActionMailer::Base.smtp_settings = {
      :address => "smtp.gmail.com",
      :port => 587,
      :domain => "mydomain.com",
      :authentication => :plain,
      :user_name => "builder@ mydomain.com",
      :password => "password"
      }

    • You'll want to specify the Configuration.dashboard_url setting so URL's work properly.

    • There are a variety of other settings available in the file that you may want to tweak.




Add Project and Configure



  1. Did the usual usual cruise add command to add my project, but with the Git variant: ./cruise add MyProjectName --git-url git@github.com:mylogin/myproject.git (modify the Git project URL for your Git repo of course). Note that you can see all the options by doing a ./cruise add

  2. Create the test database for your project. The easiest way is just to go into $CRUISE_DATA_ROOT/projects/MyProjectName/work and do a rake db:create RAILS_ENV=test. Your first build will have already failed because this hasn't been made, this step hopefully fixes that.

  3. If your log directory isn't in Git, you'll need to go mkdir it, so something like:mkdir $CRUISE_DATA_ROOT/projects/MyProjectName/work/log.



Setup CruiseControl.rb Service/Daemon



  1. Copy the cruisecontrolrb file into /etc/init.d.

  2. I set the port for CruiseControl.rb to run on in the above /etc/init.d/cruisecontrolrb daemon file, by adding "--port 1234" (for example) to the DAEMON_ARGS variable.
  3. Start the CruiseControl.rb daemon as appropriate for your system (e.g. "sudo /etc/init.d/cruisecontrolrb start").



Finally, surf to your cc.rb site on the web and see how your build has done. If you run into build problems, you'll want to look at the cc.rb build logs (if it was your project test/build that failed) which are in the $CRUISE_DATA_ROOT/projects/MyProjectName directory (or rather, the subdirectory in there for the particular build). And Enjoy!