Installing PostgreSQL server and Ruby gem on Mac OS X

by Alderete on April 22, 2009

I recently needed to install the PostgreSQL database server on my Mac for development with Ruby on Rails. I ran into a few gotchas, and while I was eventually able to Google and guess my way to success, it took a while. This installation guide is as much for me, 6 months from now, as it is for others who may wish to also install Postgres.

These instructions were current as of April 22, 2009, and were executed on Mac OS X 10.5.6 with Rubygems 1.3.2 and the Postgres 8.3.7 distribution. The shelf life of these instructions is probably brief, though they should work at least as a rough guide until the next major release of Mac OS X, or of Postgres.

Preferences and Biases

There are other Postgres + Rails instructions which recommend the use of either MacPorts or Fink. I personally dislike these solutions; part of it is having used Fink in its early days and having it screw up royally, and part of it is a sense that the efforts are misplaced. (Why not make your Open Source contribution of how to get a project properly compiled and installed on Mac OS X directly in the project itself?) In any event, I refuse to use either…though I agree that they have a place for people less comfortable compiling software directly from source code.

I also prefer not to use pre-compiled binary installations of Open Source tools, unless the maintainer has demonstrated a long-term commitment and expertise in building and maintaining the package. Marc Liyanage did a terrific job with PHP 5 for Mac OS X releases up through “Tiger.” MySQL is doing a great job creating Mac OS X installer packages for the MySQL database. But many binary installations either make odd decisions about where to put things, or don’t get maintained, or make module/configuration/packaging decisions different from what I need, or all three.

So I generally prefer to compile from source code, and install my additions to Mac OS X in /usr/local. Dan Benjamin explains the logic and benefits of /usr/local in exhausting detail, I won’t go into it further. Either you agree, and these instructions may be useful to you, or you don’t, and you should keep Googling.

Prerequisites and Preconditions

These instructions are for Mac OS X 10.5 “Leopard” only.

You need to be comfortable, or better yet confident, on the command line.

You need to have Apple’s developer tools installed.

You need to have current versions of Ruby on Rails and Rubygems installed.

You need to understand what it means to update your $PATH environment, preferrably in ~/.bash_login. You do have a ~/.bash_login file, right?

The Instructions

There are two things that need to be installed, the Postgres server and the Ruby gem for the Postgres database driver. You will also want to add a launchd task for starting and stopping the database server.

Installing the PostgreSQL Database Server

Postgres traditionally runs as a “daemon,” or background process, and manages all control to its files, especially its data. This requires that you create a dedicated user account and group, which only Postgres will use. While you could do this in the Accounts preference pane, it’s better to do this from the command line, so that the system won’t treat the Postgres user like a normal user. This is done with the Directory Service command line utility, dscl.

Before creating the Postgres user you need to pick out internal ID numbers for the user and group. You need to find a number that is not currently in use, so start by seeing what is in use. View the list of user accounts and ID numbers (note that some output is elided):

Within these lists you want to find an ID number under 500 that is not in use. My primary source for these instructions recommending adding 100 to the ID for MySQL, which seems reasonable. It’s also probably helpful to find a number that is available for both the user and the group ID, so you don’t have to worry about which is which. From the output above, I chose 174, which met both criteria.

With chosen user and group IDs, create the user. Here we are creating a user with a $HOME of /usr/local/pgsql, the location where we will be installing Postgres. We’re also creating the user in such a way that it’s useful only as a daemon; it is not possible to log in to the system as this user, either at the normal login screen or via ssh.

With the dedicated user and group created, you can now download, compile, and install Postgres. The source code distribution can be downloaded from one of the Posgresql.org mirrors. If you use Safari to download it, be sure you’ve turned off the Open “safe” files after downloading option. (And leave it off, it is a known security risk.)

You’ll want to create a Postgres user (distinct from the system user for Postgres), but before you can do that, you need to start the server. Below I describe how you can have Postgres start automatically when your computer boots, but for now, let’s just start it up manually:

$ /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data start

Now create that Postgres user, and a default database for it to use. This is the account that you will eventually use in the database.yml file of your Rails applications. And finally, use the psql command line tool to verify that we’ve successfully created the user and database.

Note: The above illustrates creating a database user and new database, both named for my Unix account name, “alderete”. Using the Unix account name simplifies using Postgres’s command line tools, you won’t have to enter the Postgres account name every time. But that will only work if your name is “alderete” too. ;-) Instead, use your Unix (or “short”) account name instead! This will likely be visible in your command line prompt, but it will also appear in the list of users you generated at the beginning of these instructions.

Finally, add important Postgres directories to your various system paths. Add the following lines to your ~/.bash_login file:

Install the Postgres Ruby Gem

Normally installing a Ruby gem is pretty simple, but the Postgres database driver has native (compiled) components, and these need to be linked against the Postgres binary. The problem is that by default Postgres is only built for the hardware architecture of your computer (PowerPC or Intel), while the gem appears to try to link against both architectures. This causes an error, and the helpful suggestion that appears with the error message does not in fact work, producing the exact same error message.

The trick to getting past this is to set the preferred architecture right on the gem install command, like so:

(If you’re still using a PowerPC-based computer, change “i386” to “ppc”.)

This should allow the gem to install successfully.

Automatically Starting Postgres at System Startup

On my development systems I’m using the database constantly, and so I have it set to start up automatically, as part of my computer’s boot process. The “Leopard” way to do this is to add a launchd task to your system. This is a text file that you’ll save on your desktop, and then move to /Library/LaunchDaemons/org.postgresql.dbms.plist. The following was copied from my primary source (see below):

If you can believe it, you’re done. Pour a cold one, or get right to it with rails mynewapp -d postgresql. Good luck!

Sources, Citations, and Credits

By far the most complete posting on this topic was
Working Software’s Building and Installing PostgreSQL on Mac OS X, which covered installing Postgres from source completely. While the instructions above are copy/pasted from my Terminal windows, I was copying lines directly from this article to paste into Terminal in the first place.

The one thing that wasn’t covered in the above article was installing the Ruby gem for Postgres, which is required to use Postgres in Rails. The normal gem install [gemname] produced errors, and most suggestions I found didn’t work any better. What finally did work was including the “-arch i382” option directly on the gem installation line, which appears to be orginally published towards the bottom of PostgreSQL on Leopard for Rails: A few notes. (A few other posts repeat this advice, so I’m not sure who first published it.)