One of my most popular blog posts is this one, where I explain how you can have an old Rails application running on Snow Leopard.
Well now that Lion is out, it’s time to update and again make sure our old projects are still maintainable (yes, I have customers that don’t need to move to the latest and greatest – I wish).
Although this post targets old versions of Rails and Ruby, you can follow the same steps for the latest versions (1.9.2 and 3.0).
Since 2010, things have changed in the Rails world. Homebrew is now the preferred way to install packages on Mac OS X. And RVM is now a must for anyone that wants to do serious Rails and/or Ruby development.
So here we go, follow me through the installation of the Rails stack on Lion.
Note 1: I did a clean install of Lion. Not sure that my recipe will work on a “migrated” Lion. A colleague of mine had problems setting up ImageMagick after migrating to Lion. It might work, but why not take some time to clean everything up and all pieces installed properly. And why not archive some files at the same time?
Note 2: I’m using Textmate. If you are using Aptana, you might want to check on the web, I think I’ve seen some blogs describing some issues with RVM and Aptana. According to this post, starting Aptana from the command line makes it use the RVM interpreter.
Note 3: Phusion Passenger is awesome. But in the past, I tried using it on my development machine and I didn’t like it so much. I still prefer starting the server myself and see the output in my terminal window. RMV supports Passenger, but I didn’t play with it.
Note 4: I’m on a Macbook Pro 17″ Mid-2010. Your experience might be different if you are on a different architecture.
- If you are still on Snow Leopard, prior to migrate to Lion, find an empty drive and use SuperDuper to clone your hard drive. This is an excellent backup solution (you can boot from the backup drive afterwards).
- Format your drive and install Lion. But hey, how do I install Lion on a clean drive? If you have a newer Mac, when you boot, you will have a choice to install Lion from the internet. Otherwise, you may download it and “burn” the image on a USB key or external drive (I tried on a DVD, may it is VERY slow when installing). Follow these instructions.
- Get the latest version of XCode on the Apple Developer Site and install it.
Step 1: Install Lion
Boot from the image, install and optionally import only the general settings when the migration assistant makes you the offer. This will you will get some global preferences back, such as your network settings and printers. You’re doing a clean install after all, and I prefer to move my files over myself so I can clean-up at the same time!
Step 2: Update the software
Once in Lion, click on the Apple and do a software update. For sure, there are some new updates to apply.
Step 3: Homebrew
Then, let’s install Homebrew (just one line, isn’t that great?). First, start the Terminal application (you will find it in Utilities in the Launchpad). Then, copy and paste the following line.
/usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"
Homebrew uses “live” recipees stored on Github. The behaviour described hereby might change in the future. So, if you see a discrepancy, please let me know so I can update them.
Step 4: Xcode
Yes. Install Xcode after Homebrew, as stated on the web page. Download it from the App Store.
Note: At some point during the install, it might ask you to quit iTunes, although it does not seem to be running. This is due do the iTunes Helper that might be still running. Open “Activity Monitor”, search for the process iTunes Helper and kill it. The install will continue.
Step 5: Basic packages
Now let’s install some basic packages that we all love and cherish.
brew install readline git wget
You have to agree that this is cool. No sources to download and untar, no configure command to run, … Homebrew takes care of doing all that. Of course, we don’t have as much control, but this is fine with me so far.
Step 6: MySQL
Chances are that your old Rails project is using MySQL and not a popular NoSQL database such as MongoDB. Let’s ask Homebrew to install it:
brew install mysql
Very important: read the text that Homebrew dumps at the end and follow the instructions. Otherwise, you will have all kinds of problems. If you want those messages back, use this command: brew info mysql.
unset TMPDIR mysql_install_db --verbose --user=`whoami` --basedir="$(brew --prefix mysql)" --datadir=/usr/local/var/mysql --tmpdir=/tmpsudo chown `whoami` /var/mysql mkdir -p ~/Library/LaunchAgents cp /usr/local/Cellar/mysql/5.5.14/com.mysql.mysqld.plist ~/Library/LaunchAgents/ launchctl load -w ~/Library/LaunchAgents/com.mysql.mysqld.plist
I then get the following error:
launchctl: CFURLWriteDataAndPropertiesToResource(/var/db/launchd.db/com.apple.launchd.peruser.501/overrides.plist) failed: -10
But if I check the processes running on the Mac (ps -ef | grep mysql), MySQL server seems to be up and running. Strange!
I also like to apply some changes to the default configuration. When you import one of your SQL backups, the default max_allowed_packet might be too small. So I like to boost it to 64M.
Here’s my /etc/my.cnf file:
[mysqld] #Max packetlength to send/receive from to server. max_allowed_packet=64M character-set-server = utf8 #This option makes InnoDB to store each created table into its own .ibd file. innodb_file_per_table [mysql] default-character-set = utf8 [client] default-character-set = utf8
Then, let’s restart the MySQL server:
launchctl unload -w ~/Library/LaunchAgents/com.mysql.mysqld.plist launchctl load -w ~/Library/LaunchAgents/com.mysql.mysqld.plist
Step 7: The lovely ImageMagick
Oh well. This is always the worst thing to install on Mac OS X. I had so many problems yesterday installing it that it’s worth explaining how I got it running.
First, later on, when you install RMagick, you will require Ghostscript fonts. So it is a good thing to install it right now, before ImageMagick:
brew install ghostscript
Now you should have the following error (if not, you’re lucky and most likely the ghostcript brew recipe was fixed).
./base/gdevpng.c:283: error: dereferencing pointer to incomplete type
To fix this, follow the instructions here and install once again ghostscript.
And finally, ImageMagick:
brew install imagemagick
Step 8: Ruby Version Manager (RVM)
Now that we have the foundation installed, let’s have fun with the Ruby Version Manager. RVM keeps multiple ruby environments isolated from each other. Each one has its own ruby version (compiled from source) and its own gems (which is awesome). You can also create “gemsets” to isolate even more projects that share the same ruby.
So instead of using the Lion out-of-the-box Ruby , let’s set-up an environment for 1.8.6.
But first, let’s install RVM:
bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
Important: do not forget to complete the install by performing 3 steps that are shown to you.
Then, let’s install our first ruby.
rvm install 1.8.6
This will install everything in the .rvm folder in your home folder. If you change your mind later, it’s easy to uninstall: rvm implode.
You can confirm the installation by running rvm list.
Step 9: Gems
RVM will install a version of Rubygems for each environment, with the proper gem sources. Let’s install some:
rvm 1.8.6 gem install ruby-debug gem install rmagick -v 1.15.16 gem install mongrel gem install mysql gem install rails -v 1.2.1
If you get this error when you try to install the first gem:
/Users/hugo/.rvm/rubies/ruby-1.8.6-p420/lib/ruby/1.8/timeout.rb:59: [BUG] Segmentation fault
ruby 1.8.6 (2010-09-02) [i686-darwin11.0.0]
you need to recompile the version of ruby so that it uses the old compiler and not the new LLVM one:
rvm remove 1.8.6 CC=/usr/bin/gcc-4.2 rvm install 1.8.6 rvm 1.8.6
That’s it. You should be good to go now. I strongly suggest that you read on how to create and use gem sets.
Step 10: Sugar
There is a way with RVM to automatically switch interpreter when you cd to a project’s folder. Simply provide a .rvmrc file in the project’s folder:
echo "rvm 1.8.6" > ~/projects/project-a/.rvmrc
Also handy is to have the current interpreter displayed in the command line prompt. Simply edit your ~/.bash_profile file and add the following line:
export PS1="\[\e[32;40m\]\$(~/.rvm/bin/rvm-prompt)\[\e[0m\] $PS1"
Have fun, and “long live to Ruby on Rails”!
Please comment if you see an error in here so I can update it. Thanks!