Setup mod_rails Passenger Mac OS X Leopard 28

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!

Comments

Leave a comment

  1. Avatar
    Carina about 16 hours later:

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

  2. Avatar
    Benjamin Reubenstein about 16 hours later:

    @carina thx! Updated.

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

    best wishes,

  4. Avatar
    ecchi 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. Avatar
    Jesus Garcia 2 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. Avatar
    Jose Hales-Garcia 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:

    <?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"> 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. Avatar
    Jose Hales-Garcia 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. Avatar
    Jose Hales-Garcia 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. Avatar
    Benjamin Reubenstein 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. Avatar
    Tim 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. Avatar
    Justin 4 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. Avatar
    Ben Reubenstein 4 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. Avatar
    Justin 4 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. Avatar
    Ben Reubenstein 4 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. Avatar
    Tim K 13 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. Avatar
    Ben Reubenstein 13 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. Avatar
    Tim K 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. Avatar
    Tim K 14 days later:

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

  19. Avatar
    Tom 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. Avatar
    Darren VanBuren 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/

  21. Avatar
    Gerhard Lazu 8 months later:

    I've tried setting this up on Apache 2.2.11 with a slightly modified configuration, Passenger 2.0.6 blew up. http://is.gd/epGp

    Any ideas?

  22. Avatar
    Adam Farnsworth 11 months later:

    Is anyone else having problems with unzipping the tar.gz file in step one? I'm getting the following error:

    gzip: stdin: not in gzip format tar: Child returned status 1 tar: Error exit delayed from previous errors

    I'm trying to install Passenger on my iMac 3.06 GHz Intel Core 2 Duo, running Mac OS 10.5.6. I would really like to run Passenger, but it doesn't seem to like me. I can't install it just using the gem, it doesn't install into the /usr/local/apache2/ folder, so I can't add the text to the config file. What am I missing?

  23. Avatar
    Ben Reubenstein 11 months later:

    @adam looks like the mirror used in the tutorial is no longer active. You can get a fresh copy of Apache from: http://httpd.apache.org/download.cgi

    You don't have to compile Apache from source any longer, it should work fine with the default install of Apache that comes with OS X. If you are trying to find your httpd.conf, I believe in the default install it is at:

    /private/etc/apache2/httpd.conf

  24. Avatar
    Adam Farnsworth 11 months later:

    @Ben Thank you!

  25. Avatar
    Leo about 1 year later:

    I have this error when running my app with mod_rails.--I have an index.xml.erb within the admin folder and Passenger doesn't let me read it.

    Exception Errno::EPIPE in Passenger RequestHandler (Broken pipe) (process 17249): from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusionpassenger/rack/requesthandler.rb:98:in write' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/rack/request_handler.rb:98:inprocess_request' from /Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/response.rb:155:in each_line' from /Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/response.rb:155:ineach' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusionpassenger/rack/requesthandler.rb:97:in process_request' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/abstract_request_handler.rb:203:inmain_loop' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusionpassenger/railz/applicationspawner.rb:340:in start_request_handler' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/railz/application_spawner.rb:298:inhandlespawnapplication' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/utils.rb:181:in safe_fork' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/railz/application_spawner.rb:296:inhandlespawnapplication' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusionpassenger/abstractserver.rb:337:in __send__' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/abstract_server.rb:337:inmain_loop' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusionpassenger/abstractserver.rb:187:in start_synchronously' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/abstract_server.rb:154:instart' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusionpassenger/railz/applicationspawner.rb:192:in start' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/spawn_manager.rb:257:inspawnrailsapplication' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusionpassenger/abstractserver_collection.rb:126:in lookup_or_add' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/spawn_manager.rb:251:inspawnrailsapplication' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusionpassenger/abstractserver_collection.rb:80:in synchronize' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/abstract_server_collection.rb:79:insynchronize' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusionpassenger/spawnmanager.rb:250:in spawn_rails_application' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/spawn_manager.rb:153:inspawn_application' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusionpassenger/spawnmanager.rb:282:in handle_spawn_application' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/abstract_server.rb:337:insend' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusionpassenger/abstractserver.rb:337:in main_loop' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/lib/phusion_passenger/abstract_server.rb:187:instart_synchronously' from /Users/leo/.gem/ruby/1.8/gems/passenger-2.2.2/bin/passenger-spawn-server:61

    Any answers about what is going on?

  26. Avatar
    Ben Reubenstein about 1 year later:

    @Leo: Not sure I would check the passenger mailing list and other support options.

  27. Avatar
    ank about 1 year later:

    For those not serving off port 80, also make sure you add a "listen X" to your httpd.conf, where X is the port number you are serving off.

  28. Avatar
    ank about 1 year later:

    For those not serving off port 80, also make sure you add a "listen X" to your httpd.conf, where X is the port number you are serving off.

Comments