Setup mod_rails Passenger Mac OS X Leopard

Posted by Ben Reubenstein Sat, 12 Apr 2008 22:32:00 GMT


UPDATE:

In the latest version of Phusion Passenger (mod_rails) 1.0.3 the default Mac OS X Apache installation is now supported! If you're still into rolling you're own these directions still apply. To upgrade to the latest version if you already have it working:

passenger-install-apache2-module
sudo passenger-install-apache2-module
sudo /usr/local/apache2/bin/apachectl restart

Today I was very excited to see that Passenger (mod_rails for Apache) had been released. Here is how I got things rolling on my Mac OS X Leopard installation. Be sure to refer to the official docs for more information.

  1. Compile Apache2 from source. The passenger-install-apache2-module warned against using the Mac rolled Apache. I used a pretty broad ./configure, feel free to customize.

    curl -O http://www.alliedquotes.com/mirrors/apache/httpd/httpd-2.2.8.tar.gz
    tar -zxvf httpd-2.2.8.tar.gz
    cd httpd-2.2.8
    ./configure --prefix=/usr/local/apache2 --enable-access --enable-actions \
    --enable-alias --enable-asis --enable-auth --enable-auth_dbm \
    --enable-auth_digest --enable-autoindex --enable-cache --enable-cgi \ 
    --enable-dav --enable-dav_fs --enable-deflate --enable-dir --enable-disk_cache \ 
    --enable-dumpio --enable-env --enable-expires --enable-fastcgi --enable-file_cache \
    --enable-headers --enable-imap --enable-include --enable-info --enable-log_config \ 
    --enable-log_forensic --enable-logio --enable-mem_cache --enable-mime \
    --enable-mime_magic --enable-negotiation --enable-perl --enable-rewrite --enable-setenvif \
    --enable-speling --enable-ssl --enable-status --enable-suexec --enable-unique_id \
    --enable-userdir --enable-usertrack --enable-version --enable-vhost_alias --enable-so \ 
    --enable-module=all --enable-shared=max
    make
    sudo make install
    
  2. Install the gem

    sudo gem install passenger
    
  3. Add /usr/local/apache2/bin to your path in ~/.bash_login so that it can find your new apache2 install, then run the command to build the module.

    sudo passenger-install-apache2-module
    
  4. Follow the prescribed instructions from mod_rails adding the following to /usr/local/apache2/conf/httpd.conf. BE SURE TO USE THE SETTINGS DUMPED OUT WHEN YOU RUN passenger-install-apache2-module as the paths on your system may differ.

    LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-1.0.1/ext/apache2/mod_passenger.so
    RailsSpawnServer /usr/local/lib/ruby/gems/1.8/gems/passenger-1.0.1/bin/passenger-spawn-server
    RailsRuby /usr/local/bin/ruby
    
  5. Setup a folder to hold vhosts

    sudo mkdir /usr/local/apache2/conf/vhosts
    
  6. Add an Include to httpd.conf as well and turned on Name Based Virtual Hosts

    NameVirtualHost *
    Include /usr/local/apache2/conf/vhosts/*
    
  7. Create a virtual host(s) that points to your rails app public folder. You can create one for each app you would like to run with Apache

    # Example App
    <VirtualHost *>
      ServerName app.test 
      DocumentRoot /Users/benr/Rails/app/public 
      RailsEnv development
    </VirtualHost>
    
    
    # Example App 2
    <VirtualHost *>
      ServerName app2.test 
      DocumentRoot /Users/benr/Rails/app2/public 
      RailsEnv development
    </VirtualHost>
    
  8. Edit /etc/hosts file to include a line for the vhosts

    127.0.0.1  app.test app2.test
    
  9. Now I store my apps in /Users/benr/Rails, so I turned on the User Home directories mod

    # User home directories
    Include conf/extra/httpd-userdir.conf
    
  10. I then configured the httpd-userdir.conf so that it used that folder, much like in the default Mac Apache it allows you to put a site in ~/Sites

    UserDir Rails 
    
    
    <Directory "/Users/*/Rails">
        AllowOverride FileInfo AuthConfig Limit Indexes
        Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
        <Limit GET POST OPTIONS>
          Order allow,deny
          Allow from all
        </Limit>
        <LimitExcept GET POST OPTIONS>
          Order deny,allow
          Deny from all
        </LimitExcept>
    </Directory>
    
  11. Start Apache

    sudo /usr/local/apache2/bin/apachectl start
    
  12. To restart your app, create a file called RAILS_ROOT/tmp/restart.txt and reload your page. < HOT!

Voila! It worked when I visted app.test and app2.test. The most important thing to remember is the defaults that mod_rails uses. I was having a lot of trouble and it turned out to be the fact that it was defaulting to production mode. The best place to track down the errors is in your RAILS_ROOT/log/YOURENV.log

If you would like to have your newly compiled Apache start on boot, Jose Hales-Garcia posted this comment:

  1. Create a new file in /Library/LaunchDaemons

    sudo pico /Library/LaunchDaemons/org.apache.httpd.plist
    
  2. Paste in the following lines and save the file (UPDATED thx: ecchi):

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
        <dict>
        <key>Label</key>
        <string>org.apache.httpd</string>
        <key>ProgramArguments</key>
        <array>
          <string>/usr/local/apache2/bin/httpd</string>
          <string>-k</string>
          <string>start</string>
            </array>
        <key>RunAtLoad</key>
        <true/>
        </dict>
    </plist>
    
  3. Load the daemon into the launchd system using the following command:

    sudo launchctl load -w /Library/LaunchDaemons/org.apache.httpd.plist
    

That's it. The local httpd daemon will load on start-up after that. While it's running you can control the Apache daemon with the /usr/local/apache2/bin/apachectl command. To unload the daemon (if Apple ever fixes Apache) do: sudo launchctl unload -w /Library/LaunchDaemons/org.apache.httpd.plist

UPDATE! Also remember to trash the .htaccess that comes with Rails. This was jacking up a couple of my applications.

UPDATE 2 Don't forget to turn off the Mac OS X Apache if it is running. System Preferences > Sharing

HOPE THIS HELPS! Pease leave comments with suggestions or issues you run into!

Tags , ,  | 20 comments

Comments

  1. Carina said about 16 hours later:

    Nice tutorial, thanks. Typo fix: "cd httpd-2.2.8.tar.gz" should be "cd httpd-2.2.8".

  2. Benjamin Reubenstein said about 16 hours later:

    @carina thx! Updated.

  3. nhm tanveer hossain khan said 1 day later:

    hi thanks for nice article. i had to add --with-included-apr to run on my OSX-10.4.11.

    best wishes,

  4. ecchi said 1 day later:

    thanks for this, but it would be helpful if you include the instructions on auto-starting the manually compiled apache2 during boot-up.

  5. Jesus Garcia said 3 days later:

    I could not run the wget command from Mac OS X 10.5. I did manage to use curl instead:

    curl -C - -O http://www.alliedquotes.com/mirrors/apache/httpd/httpd-2.2.8.tar.gz

    Everything else worked great. Thanks for the help!

    -Jesus

  6. Jose Hales-Garcia said 3 days later:

    @Jesus

    wget doesn't come with Mac OS X by default but curl does and you did what most of us do.

    @Ben

    There's a typo in the configure snippet. Right after the line with '--enable-unique_id', the backslash escape character is missing.

    @ecchi

    Follow these steps for creating a start-up for the local Apache:

    1. Create a new file in /Library/LaunchDaemons: (the editor is up to you)

    sudo pico /Library/LaunchDaemons/org.apache.httpd.plist

    1. Paste in the following lines and save the file:

    Label org.apache.httpd OnDemand ProgramArguments /usr/local/apache2/bin/httpd -k start SHAuthorizationRight system.preferences

    1. Load the daemon into the launchd system using the following command:

    sudo launchctl load -w /Library/LaunchDaemons/org.apache.httpd.plist

    That's it. The local httpd daemon will load on start-up after that.

    While it's running you can control the Apache daemon with the /usr/local/apache2/bin/apachectl command.

    To unload the daemon (if Apple ever fixes Apache) do:

    sudo launchctl unload -w /Library/LaunchDaemons/org.apache.httpd.plist

  7. Jose Hales-Garcia said 3 days later:

    Oops. The comments just run together. I'll separate my comments.

    @Jesus

    wget doesn't come with Mac OS X by default but curl does and you did what most of us d

  8. Jose Hales-Garcia said 3 days later:

    @Ben

    There's a typo in the configure snippet. Right after the line with '--enable-unique_id', the backslash escape character is missing.

  9. Benjamin Reubenstein said 3 days later:

    @Jose Thx! I fixed the configure script line and added your startup instructions to the post.

    @Jesus I adjusted the wget to curl, I forget that is something I have compiled myself.

  10. Tim said 4 days later:

    All I'm getting when I try and load up my applications is "It works!" even on localhost.... Weird.

    Does anyone know any good articles on completely removing old apache / rails installations - I just want to start from scratch...

  11. Justin said 5 days later:

    So what if i wanted other people on my network to be able to get to the same app by just typeing http://app.test ? Anyone know how to set that up?

  12. Ben Reubenstein said 5 days later:

    @Justin

    If you have control over internal DNS on your local network, you could set this up by creating a record for app.test

    @Tim

    If you are getting "It works!" that means Apache is installed correctly, however you have something wrong with your Virtual Hosts settings. Be sure you have restarted Apache when you have made changes to Virtual Hosts.

  13. Justin said 5 days later:

    okay thanks. One more question. if someone else on my network types in my ip it routes them to just the first app.test how would the get to app2.test?

    Thanks

    ..great tutorial by the way

  14. Ben Reubenstein said 5 days later:

    @Justin ~

    In a one IP name based virtual host setup, Apache will default to the first virtualhost alphabetically by name to serve if the IP is requested. If you want to host more than one site you would need the local DNS to:

    app1.test > 1.2.3.4

    app2.test > 1.2.3.4

    If you can only do it via IP:

    You could setup Passenger in sub directories:

    http://1.2.3.4/app1

    http://1.2.3.4/app2

    That might have other implications on your app.

    OR

    You could lease multiple IPs and not used name based virtual hosts.

  15. Tim K said 14 days later:

    everything seems to have worked great, but I get a Forbidden error on the subfolders within the /public directory... like the stylesheets and images. Thoughts? I'm still a bit new to Apache.

  16. Ben Reubenstein said 14 days later:

    @Tim K ~

    Did you remove the .htaccess file that Rails creates for you in the public folder?

    rm /your/public_folder/.htaccess
    
  17. Tim K said 14 days later:

    Indeed Ben, that was removed in the beginning. Instead of going through the User folder stuff my data is just stored in /Library/WebServer/[appname]/public (like in the Passenger screencast). Didn't know if that mattered.

  18. Tim K said 15 days later:

    I just moved it into the Users directory and followed through the rest of the installation - works perfect! Thanks Ben!

  19. Tom said 15 days later:

    the story so far

    --installed apache2 --installed passenger --configured passanger module, deleted rail app's .htaccess file --check if it works [No] --forbidden error results in relaxing apache2 permissions --check if it works [No]. No more forbidden error but new error is

    Passenger error #2

    Passenger thinks that the Rails application's "public" directory is "/Users/thomas/code/z/store/public", but it doesn't seem to be valid.

    Here is the vhost config

    ServerName zstore.local DocumentRoot /Users/thomas/code/z/store/public RailsEnv development Options Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all RailsBaseURI /

    Any help is appreciated

  20. Darren VanBuren said 4 months later:

    I was able to use Apple's Apache with mod_rails. I have two vhosts for rails, http://rails.oks.kicks-ass.net/ and http://oksrails.kicks-ass.net/

   Comment Markup Help Preview comment