Setting up a Rails Development Environment on OSX Mountain Lion
[Updated: 2013-01-08 - A lot of people asked for Postgres instructions]
After my faithful Macbook Air went down hard in Tonga, I was really surprised at the number of outdated posts, misinformation and general number of questions (even on Stack Overflow), on how to install a Rails dev environment from scratch on a new OSX 10.8 Mountain Lion machine.
This HOWTO runs from zero to getting you to what I consider a naked dev
environment where you're good enough to start and source control a
project and issue a
rails new command. It starts from a totally fresh
install of Mountain Lion with all system updates.
The walkthrough assumes you're comfortable on command line and can handle a text editor of some sort for modifying configuration files (just in case you're a newbie looking at installing rails for the first time). I'm also pretty opinionated about what and how you want to install it, running from rubies controlled by rbenv and using homebrew as an OSX package manager, heroku utilities, git and mysql and mongodb. This is the setup on my current machine, a late 2011 Macbook Air 13" running 10.8.2.
XCode's Command Line Tools
Sure, it's a hassle installing XCode and there are a bunch of workarounds, but they seem to all be fragile at some point or another and this Just Works.™
So, open up the App Store, find XCode and download and install the entire thing. Now is as good as time as any to make that coffee/tea/maté while that comes down.
Once installed, launch XCode, go to Preferences in the XCode menu item
and click the Downloads with the Components selected and click the
Install button for Command Line Tools. Once you're done your window
should look like this:
Personally, I think that's the hardest part of the entire process. Now on to the easy stuff.
If you're not using homebrew, you're crazy. It manages to fulfill the promise of every package manager that attempted what it did, but came short. It's easy, painless and makes managing binaries on your mac effortless. Seriously, if you haven't heard of it before, you're in for a treat.
And it's a cinch to install. On the command line paste this:
ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"
Once it's done, you're now rocking with homebrew. Trust me, it makes the rest of this thing much, much easier.
ruby and rbenv
You'll need something to manage your ruby versions (and you don't want to use the version that ships with OSX). Personally, I like rbenv. Some people like rvm, some are chuffed with chruby. I switched pretty early to rbenv after some issues with rvm and it is yet to let me down. Homebrew makes what you have to do next and getting ruby installed easy-peasy. On the command line.
brew install rbenv brew install ruby-build
If you're in your home directory (ie
cd ~) and
ls -la to check to
see if you have a
.bash_profile file. If you don't, you need to create
one. It'll come in handy later. Just
touch .bash_profile. Then open
the file and add the following line in anywhere (mine's at the top since
it was a new file.).
eval "$(rbenv init -)"
rbenv is now installed and can manage our rubies for you.
So, let's install the latest version of ruby. It's 1.9.3-p327 at time of writing.
rbenv install 1.9.3-p327
Once that finishes compiling, you've got the latest version of ruby and rubygems installed.
Now, right here, if you want, you could just install Rails. I personally throw a few other things in the basic set you need to start apps.
gem install bundler rails foreman padrino sinatra pry taps
- bundler manages gem dependencies and gives you the command line
- rails hopefully needs no introduction
- foreman allows you to locally spin up different development servers easily (and is awesome - use it instead of rails server if you're not already
foreman startin a rack app with a Procfile referring to thin, unicorns, pumas or what have you)
- padrino is a lightweight rails alternative
- sinatra is the awesome ruby DSL for creating lightweight web apps (it runs this blog, for instance)
- pry is a fantastic irb REPL replacement for debugging and console jockeying
- taps is a great, lightweight database migration tool
Technically, you've got all the gems you need, but that doesn't mean your development environment is complete. I'd still add a few things.
Heroku Command Line Tools
Heroku is the bomb. Being able to push ruby apps into the cloud and have them just run withough having to provision servers will change the way you develop. Seriously. Please go grab yourself a heroku account on their website if you haven't aleady got one.
Alternatively, if you're not interested at all in using Heroku, you can skip this section entirely and move to the next one.
Now, I'm not sure why heroku did this, but they've deprecated the heroku gem that used to give you command line tools in favour of their heroku-toolbelt install package. Crazy. But, grab the package for the Mac from the link and double click to install. Only install the heroku-CLI component and leave git and foreman unchecked.
Once that's done, on the command line:
This will ask you for your email and password and then either generate a new ssh key or will use the cool assigned to the email address you used. You can use the heroku command line tools to create, manage, push to and destroy apps on heroku (well, as soon as you have git installed).
Git and your bash prompt
Git is the source control weapon of choice in the ruby and rails communities both because it is great and because most rubyists use Github to share code and collaborate. Since you've already got homebrew installed, this is easy.
brew install git
Once it's installed, git needs a tiny bit of configuration in order to make your work easier (also, it helps if you use the same credentials here that you do on github.).
$ git config --global user.name "Your Name" $ git config --global user.email "email@example.com" $ git config --global color.ui "auto" $ git config --global url."https://".insteadOf git://
That last one is for when you're in cafes and such that might be blocking the git protocol. Very handy while travelling or in some corporate or university environments.
Once you've done that, it's very handy to be told when you're in a
directory that is under git source control what branch you're on as well
as indication on if anything has changed in staging. It's also much
nicer if it's all pretty colours. So, we need to set up your bash prompt
to support that. In your
.bash_profile add the following:
# Set up bash prompt colours export LC_CTYPE=en_US.UTF-8 export CLICOLOR=1 export TERM=xterm-color export LSCOLORS=ExFxCxDxBxegedabagacad export NC='\[\033[0m\]' # No Color export BLACK='\[\033[0;30m\]' export GRAY='\[\033[1;30m\]' export RED='\[\033[0;31m\]' export LRED='\[\033[1;31m\]' export GREEN='\[\033[0;32m\]' export LGREEN='\[\033[1;32m\]' export BROWN='\[\033[0;33m\]' export YELLOW='\[\033[1;33m\]' export BLUE='\[\033[0;34m\]' export LBLUE='\[\033[1;34m\]' export PURPLE='\[\033[0;35m\]' export LPURPLE='\[\033[1;35m\]' export CYAN='\[\033[0;36m\]' export LCYAN='\[\033[1;36m\]' export LGRAY='\[\033[0;37m\]' export WHITE='\[\033[1;37m\]' # git prompt options source /usr/local/etc/bash_completion.d/git-completion.bash source /usr/local/etc/bash_completion.d/git-prompt.sh GIT_PS1_SHOWDIRTYSTATE=1 GIT_PS1_SHOWSTASHSTATE=1 PS_USER=$GRAY PS_HOST=$GRAY PS_PATH=$BROWN PS_PUNC=$GRAY PS_GIT=$PURPLE export GIT_PAGER='less -r' PS1=$PS_USER'\u'$PS_PUNC':'$PS_PATH'\W$(__git_ps1 " '$PS_PUNC'('$PS_GIT'%s'$PS_PUNC')")'$NC'\$ '
You can alter this as to a matter of taste by googling some resources on
it, but it works well on a black backed terminal window (and special
thanks to @tjmcewan whose
I stole most of this from.).
Basically now, once you start up a new terminal window and go into a git controlled directory, you should get a nice indented and coloured prompt to give you some additional information in development.
No serious developer uses SQLite for development work and while the community is split over MySQL vs PostgreSQL (often rabidly), it's way easier to setup and use MySQL I find. Again, homebrew is your friend.
brew install mysql
Follow the instructions printed out after the installation is complete.
mysql_install_db and then to start the server
mysql.server start (in case it's not obvious,
mysql.server stop will shut it
And while a lot of people think it's unnecessary, I always think it's good practice to set a root password on the dev server. You can skill this step if you'd prefer not to have to type a password, but if you are working with sensitive data in some manner, it's a good idea.
Log into mysql on the command line with
mysql -u root
Then use the following command (changing the password to something you'll remember.):
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('sekritwerdz');
And you're good to go. Change your database adaptor to mysql in your
config/database.yml file and you're good to go once you fill in the
Also, if you're not using it already, check out SequelPro if you'd prefer a GUI client to access MySQL.
Alright, quite a few people were adamant this howto was incomplete without Postgres installation in here (particularly considering the new features in 9), so I've updated the post. Postgres is actually already on Mountain Lion (9.1.4 on my system) but it makes more sense to install it and keep it updated with Homebrew for development purposes (at time of writing the homebrew version was 9.2.4.). You probably need to choose which database you use on your dev machine for day-to-day development (I use MySQL daily though push to Heroku in production mostly, which uses postgres, though postgres does have some nice new features that might be interesting for Rails developers ie. hstore, array strings, full text search, worker queues etc.), but it doesn't hurt to have both on your system. So, installing it:
brew install postgresql
It'll take a while to download and compile both its dependencies and itself. It'll then print out some instructions for you to follow.
Since this is a clean install, you'll need to set up a database with
initdb /usr/local/var/postgres -E utf8
If you want to automatically load postgres every time you start up, then
make sure you have a
~/Library/LaunchAgents directory and then type
the commands below (if you skipped MySQL install above you might not
have it, so type
mkdir -p ~/Library/LaunchAgents to set it up before
issues the commands below.).
cp /usr/local/Cellar/postgresql/9.2.1/homebrew.mxcl.postgresql.plist ~/Library/LaunchAgents/ launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
If you don't want to load it automatically, you can start postgres manually with
pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start
and stop it with
pg_ctl -D /usr/local/var/postgres stop -s -m fast
There seems to be a dearth of free Postgre GUI clients available but most people, if you ask, point at the commericial Navicat client if you need a serious GUI client.
While not a big Postgres fan, I do really like MongoDB. The nice fact you don't need to develop with migrations any longer when using the Mongoid or MongoMapper ODMs really speeds development time and some modelling problems do lend themselves to document models rather than relational. Installing it is a cinch with brew.
brew install mongodb
Once it's installed, it's a simple matter to load it and have it startup on system startup.
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mongodb.plist
If you ever need to kill it and start it manually that's the preferred
way, but simply typing
To use it with Rails you'll need to use either the mongoid or mongomapper ODM gems (both are interesting, so read up on them both). If you need a GUI interface, while it's by no means as intuitive as SequelPro, MongoHub is pretty good once you get used to the Mongo js query syntax.
I'm hoping this will make it easier for everyone to get their system up quickly and with as little fuss as possible. It took me much longer than it should have off a new install to get up and running, so the above is pieced together from some hard won configging, so please use it to make your life easier.
And just a disclaimer: things change and both ruby and rails move fast, so if you see anything that needs correcting or something you think should be added (I really was on the fence about putting in Postgres instructions, for example) let me know in the comments and I'dd do my best to accommodate.