12
Apr
08

Configuring Passenger (mod_rails) on SliceHost with Ubuntu 7.10

I had an opportunity to play around with Phusion Passenger (mod_rails) which was just released yesterday. Before yesterday all that was available was an introductory video showing Passenger being configured, and I was quite impressed by it’s ease. Clearly one of the problems with Rails as a major platform right now is it’s hosting situation. Currently the best solution is to proxy HTTP requests from Apache or Nginx to a cluster of mongrels, which is tricky to set up and somewhat tedious – certainly not as as easy as a mod_php in Apache where things “just work”. Phusion set out to overcome this problem and release a module for Apache that hosts Rails applications easily. Here is what took me from a clean Ubuntu 7.10 slice from SliceHost to a working server with Passenger:Starting OutTo start out, I used the following *excellent* SliceHost articles to get some of the basic packages installed such as Ruby and MySQL:Ubuntu Setup – Part 1Ubuntu Setup – Part 2MySQL and RailsApache and PHPApache Virtual HostsVirtual Hosts & PermissionsNote my permissions gotcha below – you may not want to strictly follow their permissions advice (where the global does not have read permission).I also installed sqlite3 as this is now the default database package used in Rails 2.0:

$ sudo aptitude install sqlite3$ sudo gem install sqlite3-ruby

Installing the Passenger Apache ModuleUsing the simple instructions on the Passenger website, I ran:

$ sudo gem install passenger$ passenger-install-apache2-module

The passenger-install-apache2-module binary walks you through the installation of the Passenger. On the first run, it told me I didn’t have some software that was required:

* GNU C++ compiler... found* Ruby development headers... found* OpenSSL support for Ruby... found* RubyGems... found* Rake... found at /usr/bin/rake* Apache 2... found at /usr/sbin/apache2* Apache 2 development headers... not found* Apache Portable Runtime (APR) development headers... not found* fastthread... foundSome required software is not installed.But don't worry, this installer will tell you how to install them....* To install Apache 2 development headers:Please run apt-get install apache2-prefork-dev as root.* To install Apache Portable Runtime (APR) development headers:Please run apt-get install libapr1-dev as root.

Clearly the installer detected I was running Debian-based Linux and told me exactly what to do. No compile errors or nasty dependency issues, just simple and clear instructions. After installing the requisite software the installer compiled the Apache module and spit out this:

The Apache 2 module was successfully installed.Please edit your Apache configuration file, and add these lines:LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-1.0.1/ext/apache2/mod_passenger.soRailsSpawnServer /usr/lib/ruby/gems/1.8/gems/passenger-1.0.1/bin/passenger-spawn-serverRailsRuby /usr/bin/ruby1.8After you restart Apache, you are ready to deploy any numberof Ruby on Rails applications on Apache, without any furtherRuby on Rails-specific configuration!

Note that it didn’t find or attempt to find where apache modules are installed as the actual compiled modules is kept within the Ruby gems directory, it just told me what lines to include in my Apache configuration file. The last part of the installation says:

Deploying a Ruby on Rails application: an example.Suppose you have a Ruby on Rails application in /somewhere.Add a virtual host to your Apache configuration file,and set its DocumentRoot to /somewhere/public, like this:<VirtualHost>      ServerName www.yourhost.com      DocumentRoot /somewhere/public</VirtualHost>And that's it!

Now this is pretty cool… Passenger doesn’t even require virtual hosts to configure themselves as Rails applications. It will automatically detect a Rails application (I’m unsure of the actual criteria here) based on the DocumentRoot that you provide.So I added the necessary lines specified above to /etc/apache2/apache2.conf to load the module. Note that some deployments of Apache have their own way of managing modules; in Ubuntu there is a mods-available directory with individual configuration files for each module. You could split up the above commands to follow the convention for your system of choice, but for my purposes I just dumped the three lines into apache2.conf.Then I created a new Rails application and pointed DocumentRoot to the Rails public directory. Restart apache, and the site should then immediately work with no further configuration.Permissions Gotcha – Important!If you get:

RAILS_ROOT is not a directory.

The first time I got to this point I was running into an extremely obscure problem – Rails was reporting that RAILS_ROOT wasn’t a directory. After some debugging which involved hacking up the gem source code of both Rails and Passenger, I realized it was a permissions issue (what do you know). Passenger reports that it will run your Rails application as whatever user owns environment.rb. However, it will set the effective group to that user’s primary UNIX group, NOT the group that environment.rb is owned by. In my case, I set the group of all of the web files to www-data and no read or execute permissions whatsoever for other. I figured this would be sufficient since Apache runs as www-data. But in my case when Passenger got spawned, it got spawned running as bhughes:bhughes NOT bhughes:www-data, so it effectively couldn’t find the RAILS_ROOT directory and didn’t think it existed. You can design your permissions scheme however you want, but make sure you keep this in mind. I have an enhancement in Passenger’s ticketing system for fixing this and allowing you to manually set the effective group (you already can explicitly set the effective user through the RailsUser option).More Passenger ConfigurationThe Passenger User’s Guide is pretty good and includes some more specific configuration options you can choose, but the default appears to work fine. The Rails environment is by default set to “production” though this can be changed (sadly, only server-wide, not on a virtual-host basis – but there is an enhancement in the issue tracker for this feature).Restarting Your AppRestarting a Rails app hosted by Passenger is easy – simply touch a file called tmp/restart.txt within the Rails application root:

$ touch tmp/restart.txt

CapistranoBrian Ketelsen pointed out this Capistrano configuration which uses the touch tmp/restart.txt approach to restart and removes the .htaccess file which can cause issues:

namespace :deploy do  task :start, :roles => :app do  end  task :stop, :roles => :app do  end  task :restart, :roles => :app do    run "touch #{release_path}/tmp/restart.txt"  end  task :after_update_code, :roles => :app do    run "rm -rf #{release_path}/public/.htaccess"  endend

Diagnosing ProblemsOne of the absolutely wonderful things about Passenger is that problem diagnostics (regarding starting your Rails app) is fairly easy because Passenger includes its own nice error pages:Database Error ExampleFramework Initialization ExampleMemory ManagementOne of the issues with mongrel or thin is that they are constantly running and sucking up memory, even for sites that get very little traffic. This leads to a situation where hosting very low-traffic sites is very inefficient from a system resources perspective. This isn’t the case with PHP where memory usage spikes during traffic but is otherwise unused, allowing multiple sites to leverage the on and offs and maintain a pretty efficient hosting platform as far as memory is concerned. One of the great feature of Passenger is that you can configure it to automatically shut down your Rails application if it is idle for a certain period of time. Doing this obviously exerts a cost then on the next hit, but this may be an acceptable tradeoff for a server hosting many low-traffic sites. The configuration option is RailsPoolIdleTime and there is more information on this in the user guide.ConclusionObviously my introduction here doesn’t go in-depth into performance and ability of Passenger to scale. Time will tell as people begin using this whether it is a viable solution for Rails hosting, but for me installing this and getting it to work was dirt simple, at least compared to the mod_proxy_balancer setup with mongrel clusters I have used in the past. I’m not quite ready to actually host my sites using this but I’ll definitely be keeping my eye on this – it could be a major step forward in the proliferation of Rails hosting.


30 Responses to “Configuring Passenger (mod_rails) on SliceHost with Ubuntu 7.10”


  1. 1 Tom Styles Apr 14th, 2008 at 1:13 pm

    Ben, Excellent write up. Thanks for working out some of the kinks and documenting them so thoroughly.

    I’m quite excited about passenger for many of the reasons you suggest. I have quite a number of low traffic Rails sites. And would prefer this solution too paying for a bigger slice.

  2. 2 slicematt Apr 14th, 2008 at 9:04 pm

    Great article, looks like an excellent solution.

  3. 3 Brian Ketelsen Apr 16th, 2008 at 1:51 pm

    Ben, thanks, I used this to set up my slice just Sunday… One thing that would be nice to add would be the capistrano changes necessary to support this config. I found I had to remove Deprec completely, and strip 99% of my cap recipes.


    namespace :deploy do
    task :start, :roles => :app do
    end

    task :stop, :roles => :app do
    end

    task :restart, :roles => :app do
    run "touch #{release_path}/tmp/restart.txt"
    end

    task :after_update_code, :roles => :app do
    run "rm -rf #{release_path}/public/.htaccess"
    end
    end

  4. 4 Fadhli Apr 17th, 2008 at 12:45 am

    I had a situation where it couldn’t read my javascripts, css, image files. All I had to do is the following

    ServerAdmin localhost
    ServerName http://www.test_mod_rails.com
    DocumentRoot /var/www/testapp/public

    Options FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all

    RailsBaseURI /

  5. 5 Sam Apr 17th, 2008 at 6:37 pm

    Ben, thanks for the great write up. I was able to build by slice and get passenger running with minimal trouble.

  6. 6 Nick Fessel Apr 22nd, 2008 at 3:41 am

    Hi Ben,

    Thank you for the tips about installing Passenger. I just successfully set up Passenger on Ubuntu 7.10 with few problems. This is great.

    -Nick

  7. 7 Mark May 4th, 2008 at 4:05 am

    Hi All,
    I’m not sure what I’m doing wrong…I have everything installed and then I created a simple rails test app. I have the following configs:

    in: /etc/apache2/sites-available/test.mysite.com:

    ServerName test.mysite.com
    DocumentRoot /home/me/public_html/test.mysite.com/testapp/public

    in: /etc/apache2/apache2.conf:
    LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-1.0.3/ext/apache2/mod_passenger.so
    RailsSpawnServer /usr/lib/ruby/gems/1.8/gems/passenger-1.0.3/bin/passenger-spawn-server
    RailsRuby /usr/bin/ruby1.8

    ServerName mysite

    NameVirtualHost *:80

    I do the following:
    sudo /etc/init.d/apache2 restart

    Please confirm that I don’t need to start rails using ruby script/server if I’m using passenger.

    Problems:
    I can’t see passenger or ruby anywhere in a ps aux – is this ok, I thought I should at least see passenger?

    The production.log in my rails app is not getting written to (and its not a permissions issue).

    The only thing I see in /var/log/apache2.error is:
    /home/me/public_html/test.mysite.com/testapp/public/.htaccess: Invalid command ‘RewriteEngine’, perhaps misspelled or defined by a module not included in the server configuration.

    Please give me a pointer of where to look next if you have a sec.

    Thanks,
    Mark

  8. 8 Mark May 5th, 2008 at 2:27 am

    Hi Ben,

    I have a comment that is awaiting moderation, but I’ve solved the problem – so you can get rid of this post as well as my last if you like. The fix was to simply remove the .htaccess file that rails generates in the app’s public directory. Once I removed that file, the rails app was accessible at my domain name.

    Thanks,
    Mark

  9. 9 Navjeet May 14th, 2008 at 2:44 am

    Thanks Mark for your response. I too had the error related to .htacces and after deleting that file, things are cool now. I wonder if this is a Rails 2.0 thingy or something to do with my Ubuntu (Hardy Heron) install. Did not see any other post on the net for this error message.

  10. 10 Mark May 14th, 2008 at 4:40 am

    I’m getting an error when I start my app:
    The application /home/mark/public_html/test.choresforrewards.com/c4r requires Ruby on Rails version 1.2.2, which is not installed. Please install it with the following command:

    sudo gem install rails –version 1.2.2

    I think the problem is that my app was developed on 1.2.2 and I can’t update my linux server with:
    sudo gem install rails –version 1.2.2

    So, I tried to update my local workstation to 2.0.2, but when I do gem list on my local workstation I get:

    rails (2.0.2, 1.2.2)

    so I think even though 2.0.2 is on my local workstation, my app is still using 1.2.2.

    How do I change my local workstation app to use 2.0.2?

    Once I do that, I can tar it up and send it to my linux server and I suspect it will run.

    Thanks,
    Mark

  11. 11 Flavio May 15th, 2008 at 3:41 pm

    Thanks for the good guide. I’ve deployed my rails app in a short time using mod_rails.
    Unfortunately I’m experimenting a severe problem.
    The rails app works fine using firefox or konqueror, but with internet explorer I’m unable to perform the login operation.
    I’m using restfull_authentication plugin under rails 2.0.2.
    The strange thing is that, hosting the site under webrick, ie works fine.
    Any hint?

  12. 12 Jay May 17th, 2008 at 3:15 pm

    What if i run typo on my own machine while I don’t have a static IP. I just wanna share my typo blog in local area network. Under this situation, how to configure my Apache configuration file? Cause I don’t have something like “ServerName http://www.yourhost.com“. Looking forward to your reply…

  13. 13 marcus May 26th, 2008 at 8:50 am

    It was very simple for me today and i had no trouble on dreamhost, however i want to add basic authentication using the .htaccess file
    ie.

    AuthName “Dialog prompt”
    AuthType Basic
    AuthUserFile /home/xxxxxxxx/.htpasswd
    Require valid-user

    When i add this, rails intercepts the request and processes it – yeilding a 404 as there is no route to handle index.html

    Is there another way to accomplish this? (i want the entire site behind basic authentication on dreamhost using mod_rails)

  14. 14 marcus May 26th, 2008 at 10:39 am

    I think i have answered my question
    http://www.modrails.com/documentation/Users%20guide.html#RailsAllowModRewrite

    But i don’t think i can configure this on dreamhost?

  15. 15 Alex_Baum May 30th, 2008 at 12:37 pm

    Hi all, today I probe install passenger in Ubuntu 8.04
    If just run #passenger-install-apache2-module, bash says: “unknown command”
    Few hour later I run #/var/lib/gems/1.8/gems/passenger-1.0.5/bin# ruby passenger-install-apache2-module

    and success!

    (sorry for my english, I am from Russia)

  16. 16 ohkubon76 Jun 7th, 2008 at 3:57 am

    Thanks for great artcle! from Japan.
    I could deply my Typo blog system according to your entry and passenger official instruction.
    At first, my application can’t read subfolder, but deleting .htaccess solves this problem.

    There are a few problems(sometimes internal error occurs, etc) on my Typo blog yet, but it will be solved soon…

    Anyway, great thanks!

  17. 17 tini Jun 17th, 2008 at 7:50 am

    Passenger is running smoothly on my server and I successfully installed a rails application (redmine) to it.

    But does anybody know how to run two or more rails applications on the same server using passenger?

    Like this:

    http://192.168.0.100/tracks
    http://192.168.0.100/redmine

    Any hint would be appreciated.

    Thanks

  18. 18 cactis Jun 19th, 2008 at 11:24 am

    “I had a situation where it couldn’t read my javascripts, css, image files. All I had to do is the following”

    I had this problem, too.
    What can I do?

  19. 19 cactis Jun 19th, 2008 at 1:12 pm

    to Fadhli:

    Try to remove .htaccess from public folder.

  20. 20 Billy Ma Aug 1st, 2008 at 4:51 am

    I would suggest to use virtual host to run two or more rails applications. That way apache can detect which rails application to go depend on the address entered.

    Virtual Host Setting

    ServerName tracks

    ServerName redmine

  21. 21 Scott Aug 5th, 2008 at 7:52 pm

    Hi tinl,

    I set up multiple using vhosts on slicehost from the http://articles.slicehost.com, and then did the following which I documented here: http://scottmotte.com/archives/145

  22. 22 Hanky Aug 7th, 2008 at 4:58 pm

    My webserver stops responding after sometime and I have to restart apache to start the server again. I am using passenger along with apache. Has anyone faced this problem before? If yes, what is the solution for this?

  23. 23 Al Brown Jan 15th, 2009 at 11:45 am

    A fellow RIT grad, into rails AND capitalism. Very cool!

  24. 24 Drew Tufano Apr 12th, 2009 at 5:23 am

    Hey Ben!

    I just wanted to say a big “thank you” for writing this post!! I’ve been frustrated for most of the day trying to figure out why passenger kept erroring out! It was the permissions!! All the files where set to root:root. Easy chown user:user and I’m in business! Thank you, thank you for pointing me in the right direction!

  25. 25 Sandy Apr 16th, 2009 at 12:30 pm

    I created a simple, scaffolded Rails application (called “testapp”) on Ubuntu 8.10. Testapp s located in my /www/var/ directory, I get the “Welcome onboard” screen, but if I click the “About your application’s environment”, I get a Passenger error screen. Looking at the apache2
    error log file, it says that the rails-2.3.2 gem is missing. However, the gem is installed (as confirmed during the passenger-install-apache2-module step), and testapp runs fine when I run it from Mongrel in the same location (and its “environment” includes rails-2.3.2).
    echo $PATH shows that the directory with rails-2.3.2 is present.

    I added the following to apache2.conf:

    # Include the virtual host configurations:
    Include /etc/apache2/sites-enabled/

    LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/
    passenger-2.1.3/ext/apache2/mod_passenger.so
    PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3
    PassengerRuby /usr/bin/ruby1.8

    # Configure mod_passenger
    RailsSpawnMethod conservative
    RailsEnv development

    and in sites-enabled/testapp, I have:

    ServerAdmin webmaster@localhost
    Servername localhost
    DocumentRoot /var/www/testapp/public

    RailsSpawnMethod conservative
    RailsEnv development

    ServerAdmin webmaster@localhost
    ServerName localhost

    # Configure mod_passenger
    RailsSpawnMethod conservative
    RailsEnv development

    DocumentRoot /var/www/testapp/public

    Options FollowSymLinks
    AllowOverride None

    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    allow from all

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

    AllowOverride None
    Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
    Order allow,deny
    Allow from all

    ErrorLog /var/log/apache2/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog /var/log/apache2/access.log combined

    Alias /doc/ “/usr/share/doc/”

    Options Indexes MultiViews FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
    Allow from 127.0.0.0/255.0.0.0 ::1/128

    so, I should be in development mode, but it dies giving me the following error:

    [Thu Apr 16 07:57:46 2009] [notice] Apache/2.2.9 (Ubuntu) mod_ssl/2.2.9 OpenSSL/0.9.8g Phusion_Passenger/2.1.3 configured — resuming normal operations
    Missing the Rails 2.3.2 gem. Please `gem install -v=2.3.2 rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.

    Does anyone know what might be wrong?

    Sandy

  26. 26 Lukasz Apr 22nd, 2009 at 12:05 am

    thank you very very much for solving problem with permissions

  27. 27 David Smith Jun 23rd, 2009 at 8:23 pm

    hi,

    I’m trying to set up a rails test server on my lan, and not having much luck using passenger.

    The server is an ubuntu 8.04 server edition VM (VirtualBox, bridged nic), running Apache, MySQL and Rails.

    I can hit the server from my lan (the host pc, actually), using 192.168.2.xxx, and I can hit my test rails app after launching Mongrel server in production mode from 192.168.2.xxx:3000.

    I tried installing passenger from the ubuntu deb repository, and when that didn’t work, through gem (where it apparently builds passenger for the onboard Apache version).

    In either case the result is the same: it doesn’t work.

    Since I’m using a domain name for the server, I configured the “default” VirtualHost site as follows:

    ————code snippet————
    NameVirtualHost *

    ServerAdmin webmaster@localhost
    DocumentRoot /home/dave/shovell/public

    Options FollowSymLinks
    AllowOverride None

    ————————————
    (note only DocumentRoot and Directory are changed from the original file).

    I have also tried setting up a symlink to the above directory in /var/www and adding a RailsBaseURI line. Without the line, my browser opens the directory (rather than the rails app). With it, I get the same, 500 Internal Server Error message

    Although my Rails installation and test app seem to be fine, judging by being able to run it in Mongrel, the Apache error log is reporting a slew of Ruby errors:

    —————log snippet——————-
    [Tue Jun 23 15:29:02 2009] [notice] Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5.6 with Suhosin-Patch Phusion_Passenger/2.2.4 configured — resuming normal operations
    /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require’: no such file to load — fastthread (LoadError)
    from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require’
    from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.4/lib/phusion_passenger/utils.rb:27
    from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.4/bin/passenger-spawn-server:53:in `require’
    from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.4/bin/passenger-spawn-server:53
    /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require’: no such file to load — fastthread (LoadError)
    from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require’
    from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.4/lib/phusion_passenger/utils.rb:27
    from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.4/bin/passenger-spawn-server:53:in `require’
    from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.4/bin/passenger-spawn-server:53
    /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require’: no such file to load — fastthread (LoadError)
    from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require’
    from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.4/lib/phusion_passenger/utils.rb:27
    from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.4/bin/passenger-spawn-server:53:in `require’
    from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.4/bin/passenger-spawn-server:53
    [ pid=7822 file=ext/apache2/Hooks.cpp:688 time=2009-06-23 15:29:07.824 ]:
    Unexpected error in mod_passenger: Cannot spawn application ‘/home/dave/shovell’: The spawn server has exited unexpectedly.
    Backtrace:
    in ‘virtual boost::shared_ptr Passenger::ApplicationPoolServer::Client::get(const Passenger::PoolOptions&)’ (ApplicationPoolServer.h:471)
    in ‘int Hooks::handleRequest(request_rec*)’ (Hooks.cpp:485)
    ———————————-

    Any help in identifying where the problem lies, and how I might go about fixing it would sure be appreciated! I already took a stab at the mongrel + mod_proxy method and got nowhere.

    Thanks.

  28. 28 David Smith Jun 23rd, 2009 at 8:29 pm

    OK, I should have proofread that more carefully!

    1. I am NOT using a domain name for the internal test server — hence the ip address instead.

    2. Just to clarify: I was able to install passenger from the ubuntu deb repo, as well as uninstall it and then try the gem install method. The installations apparently worked (or didn’t kick up any errors at the time), but I still can’t get my app served.

    Someone may recognize my test app “shovell” was built from the tutorial in Simply Rails 2 — an excellent intro to Rails by the way, though weak in the deployment stuff, and a couple of years out of date.

    Thanks

  29. 29 tychoish Aug 11th, 2009 at 2:43 pm

    this is a great resource, but it looks like your line breaks have gotten mangled.

    two other notes….

    first, brightbox provides ubuntu (and probably debian-compatable) packages for hardy, which make the installation process more–straightforward.

    secondly, passenger requires log files to be worldwriteable, which doesn’t strike me as the most brilliant thing in the world, but its no great risk and it is what it is.

  1. 1 Install Ruby-on-Rails and Phusion Passenger (mod_rails) on Ubuntu 9.04 – Stuff for the Easily Distracted Pingback on Nov 7th, 2010 at 11:19 pm

Leave a Reply