Running Rails Local Development with Nginx, Postgres, and Passenger with Homebrew
Posted in development, rails, local-development, nginx, postgres, passenger, homebrew, and heroku
Lately I have been playing with Homebrew, an awesome package manager for Mac OS X. I really like not having to worry about dependencies and such when installing. The "rarely sudo" mentality is also pretty great.
When I noticed the Nginx (a sweet open source web server that is way better than Apache) had a --with-passenger option (which is also way awesome), I figured I'd give it a shot. I was using the built-in Apache with Passenger Preference Pane, which was pretty cool, but I really like Nginx, so I switched. I also really wanted to start using PostgreSQL instead of SQLite since all of my stuff is hosted on Heroku and that's what they're running. (I do plan on writing a Preference Pane for doing for this setup eventually.)
Here are the steps to get all of this going. I tried to keep it as simple and clear as possible with lots of examples. It looks like a lot, but it's really quite simple.
Installation
Install Homebrew and follow the steps in the wiki about not sudoing when installing RubyGems.
Install the Passenger gem
$ gem install passengerI also had to install the
fastthreadgem to get Passenger to play nice later. You might not have to do this. If you need to, all you have to do isgem install fastthread.Install Nginx with the Passenger module
$ brew install nginx --with-passengerYou can start Nginx with
sudo nginxand stop it withsudo nginx -s stop.Install PostgreSQL
$ brew install postgresqlAfter the installation completes, there will be instructions on how to initialize the database, start the server, start the server at login, and install the postgres gem. Do all of this.
Server Configuration
Modify your Nginx configuration for Passenger. It will be located at
/usr/local/Cellar/nginx/0.7.62/conf/nginx.conf(obviously you will need to replace the version number with whatever version you installed). Here is what mine looks like.There are a few things to note:
I run it as my user (
staffis my group). You don't have to do this, but I like to have the processes running as me. (If there are more of me, I'm more productive, right?) You'll need to comment this line out or change to your user.I am pointing the
passenger_rootdirective to the passenger root. This will change with whatever version of Passenger you have installed. You can get the current path by runningpassenger-config --root(you'll probably need to do this since the version is in the path).I also have
passenger_rubyset togem_ruby. I had a horrible time getting Passenger to see my customGEM_PATH(that I setup by following the Homebrew wiki). I created this little shell script to fix the environment variables. It would be great if Passenger had a way to do this. I know you can in the Apache version, but I couldn't figure it out for Nginx. Here is what mygem_rubylooks like:
I like to keep all of my virtual hosts in separate files in the
confdirectory and then include them intonginx.conf, but you can do it however you want. Here is whatsamsoffes.conflooks like:You will need to edit your
/etc/hostsfor any virtual hosts you add. Mine looks like this:
Database Configuration
If you haven't already, edit your application's
database.ymlfile to use PostgreSQL. Here is an example:Notice that the username is
samsoffesand notroot. Using therootuser is considered bad practice by most. (We'll create that user in the next step.)Enter the PostgreSQL prompt to create your user and databases:
$ psql postgres # CREATE USER samsoffes SUPERUSER; # CREATE DATABASE samsoffes_development OWNER samsoffes; # CREATE DATABASE samsoffes_test OWNER samsoffes; # \qNote: you need to make your user a superuser for your tests to run correctly. More on this here.
Let's get started already!
So, to review, you have just installed and configured Nginx, Passenger, and PostgreSQL. Now, all you have to do is type sudo nginx to start Nginx and point your browser to your virtual host (so for me it would be http://samsoffes.local). That's it! You're done!
Before, I found myself typing sudo apachectl restart a lot to reload my application. Now, you would run sudo nginx -s reload to reload the server configuration and restart the app. (You can of course do the touch tmp/restart.txt method as well.)
That probably seemed a bit tedious, but now all you have to do is create a virtual host in Nginx, add it your your hosts file, and create your database. I really like developing locally like this. Homebrew makes this entire process very easy.
If you have any issues, feel free to send me an email and I'll see what I can do. (I really need to get comments going on here don't I)