You are on page 1of 70

Phusion Passenger users guide, Nginx version

Phusion Passenger is an application server which can directly integrate into Nginx. It is designed to be easy to use, fast, stable and reliable and is used by hundreds of thousands of websites all over the world. Phusion Passenger is a so-called polyglot application server because it supports applications written in multiple programming languages. At this time, Ruby and Python are supported. his users guide will teach you!

"ow to install Nginx with Phusion Passenger support. "ow to configure Phusion Passenger. "ow to deploy Ruby and Python applications. "ow to solve common problems.

his guide assumes that the reader is somewhat familiar with Nginx and with using the command line. # able of $ontents #. %upport information #.#. %upported operating systems #.&. 'here to get support &. Installation &.#. %ynopsis &.&. (eneric installation, upgrade and downgrade method! via Ruby(ems &.). (eneric installation, upgrade and downgrade method! via tarball &.*. $ryptographic verification of installation files &.+. Installing or upgrading on ,ebian - or .buntu &.-. Installing or upgrading on Red "at, /edora, $ent0% or %cientific1inux &.2. .pgrading from open source to 3nterprise &.4. Non-interactive, automatic, headless installs or upgrades &.5. $ustomi6ing the compilation process &.5.#. %etting the compiler &.5.&. Adding additional compiler or lin7er flags &.5.). /orcing location of certain command line tools &.#8. Installing as a normal Nginx module without using the installer #

&.##. $reating an Nginx init script &.#&. ,isabling without uninstalling &.#). .ninstalling &.#*. 9oving to a different directory ). ,eploying a Ruby on Rails #.x or &.x :but N0 Rails ;< )= application ).#. ,eploying to a virtual host>s root ).&. ,eploying to a sub .RI ).). Redeploying :restarting the Ruby on Rails application= ).*. 9igrations ).+. $apistrano integration *. ,eploying a Rac7-based Ruby application :including Rails ;< )= *.#. utorial?example! writing and deploying a "ello 'orld Rac7 application *.&. ,eploying to a virtual host>s root *.). ,eploying to a sub .RI *.*. Redeploying :restarting the Rac7 application= *.+. Rac7up specifications for various web framewor7s *.+.#. $amping *.+.&. "alcyon *.+.). 9ac7 *.+.*. 9erb *.+.+. Rama6e *.+.-. %inatra +. ,eploying a '%(I :Python= application +.#. utorial?example! writing and deploying a "ello 'orld '%(I application +.&. ,eploying to a virtual host>s root +.). Redeploying :restarting the '%(I application= -. $onfiguring Phusion Passenger -.#. passenger@root Adirectory; -.&. passenger@ruby Afilename; -.). passenger@python Afilename; -.*. passenger@app@root Apath?to?root; -.+. passenger@spawn@method Astring; -.-. passenger@rolling@restarts AonBoff; -.2. passenger@resist@deployment@errors AonBoff; -.4. passenger@temp@dir Adirectory; -.5. Important deployment options -.5.#. passenger@enabled AonBoff; -.5.&. passenger@base@uri Auri; -.#8. $onnection handling options -.#8.#. passenger@ignore@client@abort AonBoff; -.#8.&. passenger@set@cgi@param A$(I environment name; Avalue; -.#8.). passenger@pass@header Aheader name; -.#8.*. passenger@buffer@response AonBoff; -.#8.+. passenger@buffer@si6e -.#8.-. passenger@buffers -.#8.2. passenger@busy@buffer@si6e -.##. %ecurity options -.##.#. passenger@user@switching AonBoff; -.##.&. passenger@user Ausername; -.##.). passenger@group Agroup name;

&

-.##.*. passenger@default@user Ausername; -.##.+. Passenger@default@group Agroup name; -.##.-. passenger@show@version@in@header AonBoff; -.##.2. passenger@friendly@error@pages AonBoff; -.#&. Resource control and optimi6ation options -.#&.#. passenger@max@pool@si6e Ainteger; -.#&.&. passenger@min@instances Ainteger; -.#&.). passenger@max@instances Ainteger; -.#&.*. passenger@max@instances@per@app Ainteger; -.#&.+. passenger@pool@idle@time Ainteger; -.#&.-. passenger@max@preloader@idle@time Ainteger; -.#&.2. passenger@concurrency@model AprocessBthread; -.#&.4. passenger@thread@count Anumber; -.#&.5. passenger@max@reCuests Ainteger; -.#&.#8. passenger@max@reCuest@time Aseconds; -.#&.##. passenger@memory@limit Ainteger; -.#&.#&. passenger@pre@start Aurl; -.#). 1ogging and debugging options -.#).#. passenger@log@level Ainteger; -.#).&. passenger@debug@log@file Afilename; -.#).). passenger@debugger AonBoff; -.#*. Ruby on Rails-specific options -.#*.#. rails@env Astring; -.#+. Rac7 and Rails ;< ) specific options -.#+.#. rac7@env Astring; -.#-. ,eprecated options -.#-.#. rails@spawn@method 2. Analysis and system maintenance 2.#. Inspecting memory usage 2.&. Inspecting Phusion Passenger>s internal status 2.). ,ebugging fro6en applications 2.*. Accessing individual application processes 2.+. Attaching an IRD console to an application process 4. ips 4.#. .ser switching :security= 4.&. Reducing memory consumption of Ruby on Rails applications by ))E 4.). $apistrano recipe 4.*. Dundler support 4.+. Installing multiple Ruby on Rails versions 4.-. 9a7ing the application restart after each reCuest 4.2. "ow to fix bro7en images?$%%?Fava%cript .RIs in sub-.RI deployments 4.4. 0ut-of-Dand (arbage 'or7 and 0ut-of-Dand (arbage $ollection 5. .nder the hood 5.#. Page caching support 5.&. "ow Phusion Passenger detects whether a virtual host is a web application #8. Appendix A! About this document ##. Appendix D! erminology ##.#. Application root ##.&. Idle process ##.). Inactive process

#&. Appendix $! %pawning methods explained #&.#. he most straightforward and traditional way! direct spawning #&.&. he smart spawning method #&.&.#. "ow it wor7s #&.&.&. %ummary of benefits #&.). %mart spawning gotcha G#! unintentional file descriptor sharing #&.).#. 3xample #! 9emcached connection sharing :harmful= #&.).&. 3xample &! 1og file sharing :not harmful= #&.*. %mart spawning gotcha G&! the need to revive threads #&.+. %mart spawning gotcha G)! code load order

1. Support information
1.1. Supported operating systems
Phusion Passenger wor7s on any P0%IH-compliant operating system. In other words! practically any operating system on earth, except 9icrosoft 'indows. Phusion Passenger is confirmed on a large number of operating systems and 1inux distributions, including, but not limited to, .buntu, ,ebian, $ent0%?/edora?R"31, (entoo, 9ac 0% H, /reeD%, and %olaris. 0penD%, is supported since version +.&. Doth )&-bit and -*-bit platforms are supported. Please report a bug or Ioin our discussion forum if it doesn>t wor7 on your P0%IH-compliant operating system.

1.2. Where to get support


Issue trac7er - report bugs here. ,iscussion forum - post a message here if you>re experiencing problems. %upport on this forum is provided by the community on a best-effort basis, so a :timely= response is not guaranteed. 3mail supportJphusion.nl if you are a Phusion Passenger 3nterprise customer. Please mention your order reference. If you are not an 3nterprise customer, we 7indly redirect you to the community discussion forum instead. $ommercial support contracts are also available. Report security vulnerabilities to supportJphusion.nl. 'e will do our best to respond to you as Cuic7ly as we can, so please do not disclose the vulnerability until then.

Please consult the Phusion Passenger website for a full list of support resources.

2. Installation
2.1. Synopsis
he Phusion Passenger installation process consists of two steps! #. he obtainment step, where you download the Phusion Passenger files puts them somewhere on your system. his can be done through downloading the source tarball, installing the Ruby gem or installing a native 0% pac7age via AP or K.9. &. he integration step, where you configure Phusion Passenger so that it wor7s properly with other system components such as Apache, Nginx, Ruby, Python, etc. Decause Phusion Passenger is designed to run in a wide variety of operating systems and configurations, both steps can be done in multiple ways. 9ost usersLespecially first-time usersLwill be satisfied with the generic installation instructions which covers both steps. "owever some users may prefer OS-specific installation instructions, which allow Phusion Passenger to better integrate into the operating system. Detter integration is characteri6ed by following 0%-specific conventions. If you are not familiar with system administration and do not understand all the choices, then we recommend you to go with the Ruby(ems generic installation method :if you>re a Ruby user= or the tarball generic installation method :if you>re not a Ruby user=. he steps for upgrading or downgrading Phusion Passenger is almost the same as the steps for installing. All the installation guides in this section will also teach you how to upgrade and downgrade.

2.2. Generi installation, upgrade and do!ngrade method" via #ubyGems


Ruby(ems is only used as a method to obtain the Phusion Passenger files, so in case you have multiple Ruby versions it does not matter which Ruby>s Ruby(ems you use for installation. 0nce installed, Phusion Passenger can wor7 with all other Ruby versions on your system. Step 1" figuring out !hether your #uby is installed the home dire tory or system$!ide Ruby may either be installed in the home directory, or system-wide. If it>s installed systemwide then we will want to install gems system-wide as well, so you need to switch to a root prompt first. If Ruby is installed in the home directory then we will want to install gems to the home directory as well, as a normal user.

o find out which case applies, run the following command to find out where the ruby command is!
which ruby

,o you see a filename that references /home or /UsersM If so then your Ruby interpreter is installed in your home directory and you can proceed to step &. 0therwise, you need to switch to a root prompt by running one of the following commands!

Are you using RN9M Run rvmsudo -s Are you not using RN9, or do you not 7now what RN9 isM Run sudo -s Is sudo not installed on your systemM Run su -c bash

Kou must maintain this root prompt throughout this installation guide. Step 2" install the gem 0pen %ource Install the latest gem to obtain the files for the latest stable version of the open source Phusion Passenger!
gem install passenger

%ometimes you will want to obtain the latest beta version of Phusion Passenger. Deta versions are not normally selected by gem install, so to opt-in for beta versions you have to add the --pre argument!
gem install passenger --pre

If you want to obtain a specific version of Phusion Passenger, e.g. because you are downgrading, then specify the version number with --version!
gem install passenger --version 3.0.0

If you want to obtain a specific beta version of Phusion Passenger then you must also pass --pre!
gem install passenger --version 3.9.1.beta --pre

3nterprise he gem install command only installs the open source version of Phusion Passenger. Phusion Passenger 3nterprise customers should obtain the gem from the $ustomer Area instead. 1ogin with your order reference and password. he $ustomer Area will show you a list of files. /irst, download the li ense %ey and save it as /etc/passenger-enterprise-license. Next, download the gem file for the version you want :passenger-enterprise-serverx.x.x.gem= and install it with! -

gem install passenger-enterprise-server-x.x.x.gem

Step &" add the #ubyGems bin dire tory to your 'P()* If you all of the following are applicable to you!

Kou are on ,ebian or .buntu, and you installed Ruby(ems through AP , and your Ruby interpreter is installed system-wide,

Othen you must ensure that the Ruby(ems bin directory is in your PPA ", which is the environment variable that dictates where your command prompt will loo7 for commands. If any of the above conditions do not apply to you, then you can s7ip this step. 0pen /etc/bash.bashrc or /etc/bashrc :whichever is available= and add the following to the end of the file. Also run this command in your terminal.
export PATH !PATH"#var#lib#gems#1.$#bin"#var#lib#gems#1.9#bin

Step +" loosen permissions If in step # you determined that your Ruby interpreter is installed in your home directory, then you need to ma7e sure that the Phusion Passenger gem directory is accessible by your web server. o do that, you must ensure that the Phusion Passenger gem directory, as well as all parent directories, have the world-executable permission. o find out where the Phusion Passenger gem directory is, run!
passenger-con%ig --root

%uppose that the above command outputs /home/phusion/.rvm/gems/ruby-1.9.3p36 /gems/passenger-!.!.!. hen you chmod oQx the directory itself and all parent directories up until /home/phusion!
chmo& chmo& chmo& chmo& chmo& chmo& o'x o'x o'x o'x o'x o'x #home#phusion#.rvm#gems#ruby-1.9.3-p3()#gems#passenger-x.x.x #home#phusion#.rvm#gems#ruby-1.9.3-p3()#gems #home#phusion#.rvm#gems#ruby-1.9.3-p3() #home#phusion#.rvm#gems #home#phusion#.rvm #home#phusion

Step ," run the Phusion Passenger installer Nginx is a different from other web servers in that it does not support loadable modules. he only way to extend Nginx is to recompile it entirely from source. hat>s what we will do in this step. he good news is that Phusion Passenger provides a tool to ma7e this easy for you. If you>ve already installed Nginx before, but without Phusion Passenger support, then you should uninstall it first. Kou don>t have to, because you can also install another Nginx with

Phusion Passenger support, in parallel to the existing Nginx. 'e merely recommend uninstalling the existing in order to avoid user confusion, but the choice is yours. If you had previously installed Nginx with Phusion Passenger support, and you are upgrading, then you don>t have to uninstall your existing Nginx first. Instead we>ll overwrite it this step. "ere>s how you can uninstall the original Nginx!

If you installed the existing Nginx through AP , run! sudo apt-get remove nginx nginx-full nginx-light nginx-naxsi nginx-common If you installed the existing Nginx through K.9, run yum remove nginx as root.

o proceed with installing or upgrading Phusion Passenger, run the Phusion Passenger Nginx installer and follow the on-screen instructions!
passenger-install-nginx-mo&ule

At some point it will as7 you which prefix to install Nginx to. If you>re upgrading, then specify the same prefix that you used last time. Step -" .erifying that Phusion Passenger is running Restart your web server and run!
passenger-memory-stats

Kou should see the web server processes as well as a number of Phusion Passenger processes :e.g. Passenger'atchdog, Passenger"elperAgent=. $ongratulations, Phusion Passenger is now installed and runningR At this point you may be interested in creating an Nginx init script. If the output is not as expected, then please refer to the roubleshooting section.

2.&. Generi installation, upgrade and do!ngrade method" via tarball


Step 1" do!nload and extra t the tarball ,ownload the open source Phusion Passenger tarball from the Phusion Passenger website. If you want a specific version, please refer to the release archive on Ruby/orge. If you a Phusion Passenger 3nterprise customer, download the Phusion Passenger 3nterprise tarball from the $ustomer Area. Also be sure to download the li ense %ey and save it as /etc/passenger-enterprise-license.

0nce you have downloaded the tarball, pic7 a location to extract it to. Kou can pic7 any location. A good location is /opt/passenger. 1et>s call this location PPR3/IH. $reate this directory and extract the tarball as follows!
m*&ir !P+,-./ c& !P+,-./ tar x0v% #location-to#passenger-x.x.x.tar.g0 c& !P+,-./#passenger-x.x.x

Note that passenger-x.x.x should be passenger-enterprise-server-x.x.x if you>re using Phusion Passenger 3nterprise. Step 2" loosen permissions he Phusion Passenger directory must be accessible by the web server and by any web apps you want to run. o do that, you must ensure that the Phusion Passenger gem directory, as well as all parent directories, have the world-executable permission. %uppose that the Phusion Passenger directory is /opt/passenger/passenger-".#.#. Run chmod oQx on the directory itself and all parent directories.
chmo& o'x #opt#passenger#passenger-1.0.0 chmo& o'x #opt#passenger chmo& o'x #opt

Step &" installing #uby and #a%e Phusion Passenger supports multiple languages and its core is written in $QQ, but its installer and administration tools are written in Ruby, so you must install that. 3ven though Ruby is reCuired, Ruby will not be loaded during normal operation unless you deploy a Ruby web application on Phusion Passenger. Run ruby --version and ra7e --version to find out whether both commands are already installed and recent enough. Phusion Passenger reCuires Ruby ;< #.4.-. Any Ra7e version will do. ,ebian 'e recommend you to use the Drightbox Ruby pac7ages. hey provide more up-to-date versions of Ruby than ,ebian>s official repositories provide. heir .buntu 1ucid repository is compatible with ,ebian -. If you do not want to use the Drightbox repository, then follow the instructions for ,ebian +. $reate /etc/apt/sources.list.d/brightbo!-source.list!
&eb http"##ppa.launchpa&.net#brightbox#ruby-ng#ubuntu luci& main

Install the Drightbox AP public 7ey!


su&o apt-*ey a&v --*eyserver *eyserver.ubuntu.com --recv-*eys 23133AA(

hen install Ruby and Ra7e!


su&o apt-get up&ate su&o apt-get install ruby1.9.3 su&o gem install ra*e

,ebian + Run!
su&o apt-get up&ate su&o apt-get install ruby ra*e

hen add the Ruby(ems bin directory to your PPA ". .buntu 'e recommend you to use the Drightbox Ruby pac7ages. hey provide more up-to-date versions of Ruby than .buntu>s official repositories provide.
su&o apt-a&&-repository ppa"brightbox#passenger su&o apt-get up&ate

If you>re on the older .buntu 4.8* "ardy release, the apt-add-repository command isn>t available so you have to install the repository and the 7ey by hand!
su&o sh -c 4echo 5&eb http"##ppa.launchpa&.net#brightbox#passenger#ubuntu har&y main5 6 #etc#apt#sources.list.&#brightbox-passenger.list4 su&o apt-*ey a&v --*eyserver *eyserver.ubuntu.com --recv-*eys 23133AA( su&o apt-get up&ate

0ther operating systems Please install Ruby from the Ruby website. 0nce Ruby is installed, run the following command :possibly as root= to install Ra7e!
gem install ra*e

Step +" figuring out !hether your #uby is installed the home dire tory or system$!ide ,epending on whether you installed Ruby system-wide, you need to enter a root prompt before continuing to step +. Please refer to this section. Step ," run the Phusion Passenger installer Please refer to this section. Note that the passenger-install-nginx-module command is inside the bin subdirectory of the Phusion Passenger source directory, so you would have to run something li7e /opt/passenger/passenger-!.!.!/bin/passenger-install-ngin!-module. Step -" .erifying that Phusion Passenger is running Please refer to this section. Note that all Phusion Passenger administration scripts are located inside the bin subdirectory of the Phusion Passenger source directory, so you would have to run something li7e /opt/passenger/passenger-!.!.!/bin/passenger-memory-stats. #8

2.+. /ryptographi verifi ation of installation files


'hen using the generic installation methods, you can chec7 whether the gem or the tarball are legit :i.e. whether they came from Phusion= by chec7ing them against their (P( digital signatures. %tarting from the open source version *.8.8 R$ *, or the 3nterprise version *.8.8 R$ #, both the gem and tarball are signed with Phusion>s (P( 7ey!
Phusion 7o%tware 7igning 8so%tware-signing9phusion.nl: ;ey .<" 0x0A)1)A$2

his 7ey is stored at 7eyserver.ubuntu.com. Kou can import it to your 7eyring with this command!
gpg --*eyserver *eyserver.ubuntu.com --search-*eys 0x)A231=A=0A)1)A$2

Kou can find the open source version>s (P( signatures at https!??www.phusionpassenger.com?signatures?, or the 3nterprise version>s (P( signatures in the $ustomer Area. Kou can verify the validity of a file against its signature as follows!
gpg --veri%y %ilename.asc %ilename

he ,3D and RP9 pac7ages are signed with the signatures of the respective pac7agers. Phusion does not provide signatures for them.

2.,. Installing or upgrading on 0ebian - or 1buntu


Fohn 1each from Drightbox has 7indly provided .buntu pac7ages for Phusion Passenger. he .buntu 1ucid pac7ages are compatible with ,ebian -. he pac7ages are available from the Drightbox repository. 0nly pac7ages for the open source version of Phusion Passenger are provided. Phusion Passenger 3nterprise customers should use the generic Ruby(ems installation method or the generic tarball installation method instead. If you use these pac7ages to install Phusion Passenger then you do not need to run passengerinstall-apache&-module or passenger-install-nginx-module. hese pac7ages contain all the binaries that you need. Apache 0n .buntu versions newer than 4.8* "ardy, register the Drightbox Apache PPA as follows!
su&o apt-a&&-repository ppa"brightbox#passenger su&o apt-get up&ate

0n .buntu 4.8* "ardy and on ,ebian, the apt-add-repository command isn>t available so you have to install the repository and the 7ey by hand. ,ebian -! ##

su&o sh -c 4echo 5&eb http"##ppa.launchpa&.net#brightbox#passenger#ubuntu luci& main5 6 #etc#apt#sources.list.&#brightbox-passenger.list4 su&o apt-*ey a&v --*eyserver *eyserver.ubuntu.com --recv-*eys 23133AA( su&o apt-get up&ate

.buntu 4.8* "ardy!


su&o sh -c 4echo 5&eb http"##ppa.launchpa&.net#brightbox#passenger#ubuntu har&y main5 6 #etc#apt#sources.list.&#brightbox-passenger.list4 su&o apt-*ey a&v --*eyserver *eyserver.ubuntu.com --recv-*eys 23133AA( su&o apt-get up&ate

Kou can proceed with installing Phusion Passenger by running!


su&o apt-get install libapache)-mo&-passenger

he Apache pac7age provides configuration snippets for you, so you don>t need to modify any Apache configuration to get it to load Phusion Passenger. Nginx 0n .buntu versions newer than 4.8* "ardy, register the Drightbox Apache PPA as follows!
su&o apt-a&&-repository ppa"brightbox#passenger-nginx su&o apt-get up&ate

0n .buntu 4.8* "ardy and on ,ebian, the apt-add-repository command isn>t available so you have to install the repository and the 7ey by hand. ,ebian -!
su&o sh -c 4echo 5&eb http"##ppa.launchpa&.net#brightbox#passengernginx#ubuntu luci& main5 6 #etc#apt#sources.list.&#brightbox-passengernginx.list4 su&o apt-*ey a&v --*eyserver *eyserver.ubuntu.com --recv-*eys 23133AA( su&o apt-get up&ate

.buntu 4.8* "ardy!


su&o sh -c 4echo 5&eb http"##ppa.launchpa&.net#brightbox#passenger#ubuntu har&y main5 6 #etc#apt#sources.list.&#brightbox-passenger-nginx.list4 su&o apt-*ey a&v --*eyserver *eyserver.ubuntu.com --recv-*eys 23133AA( su&o apt-get up&ate

hen!
su&o apt-get install nginx-%ull

Kou>ll then need to enable the Phusion Passenger module in Nginx by creating the following configuration file!
su&o sh -c 4echo 5passenger>root #usr#lib#phusion-passenger?5 6 #etc#nginx#con%.&#passenger.con%4

#&

hen restart Nginx to apply the changes!


su&o #etc#init.&#nginx restart

%tandalone .nfortunately, no pac7ages are provided for Phusion Passenger %tandalone.

2.-. Installing or upgrading on #ed *at, 2edora, /ent3S or S ientifi 4inux


K.9 repositories with RP9s are maintained by 3ri7 0gan and %tealthy 9on7eys $onsulting. 0nly pac7ages for the open source version of Phusion Passenger are provided. Phusion Passenger 3nterprise customers should use the generic Ruby(ems installation method or the generic tarball installation method instead. If you use K.9 to install Phusion Passenger then you do not need to run passenger-installapache&-module or passenger-install-nginx-module. he K.9 pac7ages contain all the binaries that you need. Kou also don>t need to modify any Apache or Nginx configuration to get them to load Phusion Passenger, the pac7ages provide configuration snippets for you as well. Step 1" Install the release pa %age he easiest way to install Phusion Passenger and 7eep it up to date is to install the passengerrelease pac7age from the main repository. /edora $ore #+!
yum install http"##passenger.stealthymon*eys.com#%e&ora#1=#passengerrelease.noarch.rpm

/edora $ore #*!


yum install http"##passenger.stealthymon*eys.com#%e&ora#11#passengerrelease.noarch.rpm

R"31 + ? $ent0% + ? %cientific1inux +! :Note! these pac7ages depend on 3P31.=


rpm -@vh http"##passenger.stealthymon*eys.com#rhel#=#passengerrelease.noarch.rpm

R"31 - ? $ent0% - ? %cientific1inux -!


yum install http"##passenger.stealthymon*eys.com#rhel#(#passengerrelease.noarch.rpm

Step 2" 1se 516 /rom there you can use K.9 to install pac7ages. /or example, try one of these!

#)

Phusion Passenger for Apache!


yum install mo&>passenger

Phusion Passenger for Nginx!


yum install nginx-passenger

Phusion Passenger %tandalone!


yum install passenger-stan&alone

7uilding your o!n pa %ages here are instructions for building your own pac7ages and Kum repositories in the rpm directory Read9e within the (it"ub repository.

2.8. 1pgrading from open sour e to 9nterprise


Phusion Passenger comes in two variants! an open source version, as well as an 3nterprise version which introduces a myriad of useful features that can improve stability and performance and efficiency. $ustomers who have bought Phusion Passenger 3nterprise can upgrade their open source installation to 3nterprise as follows! #. .ninstall the open source Phusion Passenger. &. Install the 3nterprise version by following one of the installation guides in this section :e.g. Ruby(ems generic installation or tarball generic installation=. he uninstallation is necessary because the 3nterprise Ruby gem has a different gem name :passenger-enterprise-server instead of passenger=, but the same administration command names :e.g. passenger-status=. .ninstalling the open source version avoids any conflicts.

2.:. Non$intera tive, automati , headless installs or upgrades


Dy default, the installer :passenger-install-nginx-module= is interactive. If you want to automate installation then you can do so by passing various answers to the installer through command line options. Please run the installer with --help for a list of available command line options.

2.;. /ustomi<ing the ompilation pro ess

#*

2.;.1. Setting the ompiler Kou can force the Phusion Passenger build system to use a specific $ or $QQ compiler by setting the $$ and $HH environment variables. hese may be set to any arbitrary shell commands. /or example, contributors who want to hac7 on Phusion Passenger may want to use $lang for faster compilation and ccache for faster recompilation, and may want to enable more errorcatching compilation flags!
export 22 4ccache clang -%color-&iagnostics -Aunuse&-arguments -%catchun&e%ine&-behavior -%trapv4 export 2// 4ccache clang'' -%color-&iagnostics -Aunuse&-arguments -%catchun&e%ine&-behavior -%trapv4

2.;.2. (dding additional ompiler or lin%er flags 0n some systems, $?$QQ libraries and headers that Phusion Passenger reCuires may be located in a non-standard directory. Kou can force the Phusion Passenger build system to loo7 in those locations by inIecting compiler and lin7er flags using the following environment variables! 3H RA@PR3@$/1A(% hese flags are inIected into all $ compiler invocations that involve compiling $ or $QQ source files. his includes compiler invocations that compile and lin7. he flags are inIected at the beginning of the command string, even before 3H RA@PR3@1,/1A(%. 3H RA@$/1A(% %imilar to 3H RA@PR3@$/1A(%, but inIected at the end of the command string, before 3H RA@1,/1A(%. 3H RA@PR3@$HH/1A(% %imilar to 3H RA@PR3@$/1A(%, but for $QQ compiler invocations. 3H RA@$HH/1A(% %imilar to 3H RA@$/1A(%, but for $QQ compiler invocations. 3H RA@PR3@1,/1A(% hese flags are inIected into all $?$QQ compiler invocations that involve lin7ing. his includes compiler invocations that compile and lin7. he flags are inIected at the beginning of the command string, but after 3H RA@PR3@$/1A(% and 3H RA@PR3@$HH/1A(%. 3H RA@1,/1A(% #+

%imilar to 3H RA@PR3@1,/1A(%, but inIected at the very end of the command string, even after 3H RA@$/1A(% and 3H RA@$HH/1A(%.

2.;.&. 2or ing lo ation of ertain ommand line tools he Phusion Passenger build system attempts to autodetect many things by locating relevant helper tools. /or example, to find out which compiler flags it should use for compiling Apache modules, it locates the apxs& command and Cueries it. o find out which compiler flags it should use for libcurl, it Cueries the curl-config command. hese commands may not be in PPA ", or even when they are you may want to use a different one. Kou can often force the build to find certain command line tools at certain locations by using the following environment variables! " P, he location of the httpd executable :the Apache server executable=. APH%& he location of the apxs& executable :the Apache module developer tool=. APR@$0N/I( he location of the apr-config executable :the Apache Portable Runtime developer tool=. AP.@$0N/I( he location of the apu-config executable :the Apache Portable Runtime .tility developer tool=. 9AS3 he location of a ma7e tool. It does not matter which implementation of ma7e this is. (9AS3 he location of the (N.-compatible ma7e tool.

2.1=. Installing as a normal Nginx module !ithout using the installer


Kou can also install Phusion Passenger the way you install any other Nginx module, e.g. with --add-module. Run Nginx>s configure script with --add-module<?path-to-passengerroot?ext?nginx.

#-

If you installed Phusion Passenger via the gem, then path-to-passenger-root can be obtained with the command!
passenger-con%ig --root

his will probably output something along the lines of /usr/lib/ruby/gems/1.$/gems/passenger-!.!.!, so you>ll probably have to specify something li7e --add-module<?usr?lib?ruby?gems?#.4?gems?passenger-x.x.x?ext?nginx. If you installed Phusion Passenger via a source tarball, then path-to-passenger-root is the directory which contains the Phusion Passenger source code. %o if you extracted the Phusion Passenger source code to /opt/passenger-!.!.!, then you>ll have to specify --addmodule<?opt?passenger-x.x.x?ext?nginx. After having installed Nginx with Phusion Passenger support, you must paste the following line into your Nginx configuration file!
passenger>root #path-to-passenger-root?

After having done so, restart Nginx.

2.11. /reating an Nginx init s ript


If you installed Nginx with one of the generic installation methods then you won>t have an init script to start, stop and restart Nginx with. A bare Nginx installation wor7s with signals! you start it by invo7ing it from the command line, you stop it by sending %I( 3R9 to it and you gracefully restart it by sending %I(".P to it. If you prefer to use an init script then please refer to the following resources!

Init script for .buntu Init script for Red "at, /edora and $ent0%

'hen using one of those init scripts, please ma7e sure that the paths inside the init script are correct. In particular, the paths to the Nginx binary, to the PI, file and to the configuration file must match the actual locations of your Nginx installation.

2.12. 0isabling !ithout uninstalling


Kou can temporarily unload :disable= Phusion Passenger from the web server, without uninstalling the Phusion Passenger files, so that the web server behaves as if Phusion Passenger was never installed in the first place. his might be useful to you if - for example you seem to be experiencing a problem caused by Phusion Passenger, but you want to ma7e sure whether that>s actually the case without having to through the hassle of uninstalling

#2

Phusion Passenger completely. 'hen disabled, Phusion Passenger will not occupy any memory or $P. or otherwise interfere with the web server. o unload Phusion Passenger, edit your Nginx configuration file:s= and comment out all Phusion Passenger configuration directives. /or example, if your configuration file loo7s li7e thisO
... http B passenger>root #somewhere#passenger-x.x.x? passenger>ruby #usr#bin#ruby? passenger>max>pool>si0e 10? g0ip on? server B server>name www.%oo.com? listen $0? root #webapps#%oo#public? passenger>enable& on? C

Othen comment out the relevant directives, so that it loo7s li7e this!
... http B D passenger>root #somewhere#passenger-x.x.x? D passenger>ruby #usr#bin#ruby? D passenger>max>pool>si0e 10? g0ip on? server B server>name www.%oo.com? listen $0? root #webapps#%oo#public? D passenger>enable& on? C

After you>ve done this, save the configuration file and restart the web server.

2.1&. 1ninstalling
o uninstall Phusion Passenger, please first remove all Phusion Passenger configuration directives from your web server configuration file:s=. After you>ve done this, you need to remove the Phusion Passenger files.

#4

If you installed Phusion Passenger via a Ruby gem, then run gem uninstall passenger :or, if you>re an Phusion Passenger 3nterprise user, gem uninstall passengerenterprise-server=. Kou might have to run this as root. If you installed Phusion Passenger via a source tarball, then remove the directory in which you placed the extracted Phusion Passenger files. his directory is the same as the one pointed to the by PassengerRoot?passenger@root configuration directive. If you installed Phusion Passenger through AP or K.9, then use them to uninstall Phusion Passenger.

Nginx does not have to be recompiled. Altough it contains Phusion Passenger code, it will not do anything when Phusion Passenger is disabled.

2.1+. 6oving to a different dire tory


If you installed Phusion Passenger through a tarball then you can move the Phusion Passenger directory to another location. his is not possible if you used any of the other installation methods. /irst, move the directory to whereever you li7e!
mv #opt#passenger#passenger-1.0.0 #usr#local#passenger-1.0.0

Next you must tell your web server that Phusion Passenger has moved. 0pen your Nginx configuration file and set the passenger%root directive to the new location!
passenger>root #usr#local#passenger-1.0.0

Restart your web server to finali6e the change.

&. 0eploying a #uby on #ails 1.x or 2.x >but N3) #ails ?@ &A appli ation
%uppose you have a Ruby on Rails application in /&ebapps/mycoo', and you own the domain &&&.mycoo'.com. Kou can either deploy your application to the virtual host>s root :i.e. the application will be accessible from the root .R1, http(//&&&.mycoo'.com/=, or in a sub .RI :i.e. the application will be accessible from a sub .R1, such as http(//&&&.mycoo'.com/railsapplication=. he default RAI1%@3NN environment in which deployed Rails applications are run, is TproductionU. Kou can change this by changing the rails@env configuration option.

&.1. 0eploying to a virtual hostBs root


#5

Add a server virtual host entry to your Nginx configuration file. he virtual host>s root must point to your Ruby on Rails application>s public folder. Inside the server bloc7, set passenger%enabled on. /or example!
http B ... server B listen $0? server>name www.mycoo*.com? root #webapps#mycoo*#public? passenger>enable& on? C C ...

hen restart Nginx. he application has now been deployed.

&.2. 0eploying to a sub 1#I


%uppose that you already have a server virtual host entry!
http B ... server B listen $0? server>name www.phusion.nl? root #websites#phusion? C C ...

And you want your Ruby on Rails application to be accessible from the .R1 http(//&&&.phusion.nl/rails. o do this, ma7e a symlin7 in the virtual host>s document root, and have it point to your Ruby on Rails application>s public folder. /or example!
ln -s #webapps#mycoo*#public #websites#phusion#rails

Next, set passenger%enabled on and add a passenger@base@uri option to the server bloc7!
http B ... server B listen $0?

&8

server>name www.phusion.nl? root #websites#phusion? passenger>enable& on? passenger>base>uri #rails? C C ...

D E--- These lines have D E--- been a&&e&.

hen restart Nginx. he application has now been deployed. Kou can deploy multiple Rails applications under a virtual host, by specifying passenger@base@uri multiple times. /or example!
server B ... passenger>base>uri #app1? passenger>base>uri #app)? passenger>base>uri #app3? C

&.&. #edeploying >restarting the #uby on #ails appli ationA


,eploying a new version of a Ruby on Rails application is as simple as re-uploading the application files, and restarting the application. here are two ways to restart the application! #. Dy restarting Nginx. &. Dy creating or modifying the file tmp/restart.t!t in the Rails application>s root folder. Phusion Passenger will automatically restart the application during the next reCuest. /or example, to restart our example 9y$oo7 application, we type this in the command line!
touch #webapps#mycoo*#tmp#restart.txt

Please note that, unli7e earlier versions of Phusion Passenger, restart.t!t is not automatically deleted. Phusion Passenger chec7s whether the timestamp of this file has changed in order to determine whether the application should be restarted.

&.+. 6igrations
Phusion Passenger is not related to Ruby on Rails migrations in any way. o run migrations on your deployment server, please login to your deployment server :e.g. with ssh= and type ra7e db!migrate RAI1%@3NN<production in a shell console, Iust li7e one would normally run migrations.

&#

&.,. /apistrano integration


%ee $apistrano recipe.

+. 0eploying a #a %$based #uby appli ation >in luding #ails ?@ &A


Phusion Passenger supports arbitrary Ruby web applications that follow the Rac7 interface. Phusion Passenger assumes that Rac7 application directories have a certain layout. %uppose that you have a Rac7 application in /&ebapps/rac'app. hen that folder must contain at least three entries!

config.ru, a Rac7up file for starting the Rac7 application. his file must contain the complete logic for initiali6ing the application. public/, a folder containing public static web assets, li7e images and stylesheets. tmp/, used for restart.t!t :our application restart mechanism=. his will be explained in a following subsection.

%o /&ebapps/rac'app must, at minimum, loo7 li7e this!


#webapps#rac*app F '-- con%ig.ru F '-- public# F '-- tmp#

%uppose you own the domain &&&.rac'app.com. Kou can either deploy your application to the virtual host>s root :i.e. the application will be accessible from the root .R1, http(//&&&.rac'app.com/=, or in a sub .RI :i.e. the application will be accessible from a sub .R1, such as http(//&&&.rac'app.com/rac'app=. he default RA$S@3NN environment in which deployed Rac7 applications are run, is TproductionU. Kou can change this by changing the rac7@env configuration option.

+.1. )utorialCexample" !riting and deploying a *ello World #a % appli ation


/irst we create a Phusion Passenger-compliant Rac7 directory structure!
! m*&ir #webapps#rac*>example ! m*&ir #webapps#rac*>example#public ! m*&ir #webapps#rac*>example#tmp

Next, we write a minimal Vhello worldV Rac7 application! &&

! c& #webapps#rac*>example ! some>awesome>e&itor con%ig.ru ...type in some source co&e... ! cat con%ig.ru app proc &o FenvF G)00H B 52ontent-Type5 6 5text#html5 CH G5hello Eb6worl&E#b65II en& run app

/inally, we deploy it by adding the following configuration options to the Nginx configuration file!
http B ... server B listen $0? server>name www.rac*example.com? root #webapps#rac*>example#public? passenger>enable& on? C ... C

And we>re doneR After an Nginx restart, the above Rac7 application will be available under the .R1 http(//&&&.rac'e!ample.com/.

+.2. 0eploying to a virtual hostBs root


Add a server virtual host entry to your Nginx configuration file. he virtual host>s root must point to your Rac7 application>s public folder. Kou must also set passenger%enabled on in the server bloc7. /or example!
http B ... server B listen $0? server>name www.rac*app.com? root #webapps#rac*app#public? passenger>enable& on? C ... C

hen restart Nginx. he application has now been deployed.

+.&. 0eploying to a sub 1#I


%uppose that you already have a virtual host!

&)

http B ... server B listen $0? server>name www.phusion.nl? root #websites#phusion? passenger>enable& on? C C ...

And you want your Rac7 application to be accessible from the .R1 http(//&&&.phusion.nl/rac'. o do this, ma7e a symlin7 in the virtual host>s document root, and have it point to your Rac7 application>s public folder. /or example!
ln -s #webapps#rac*app#public #websites#phusion#rac*

Next, set passenger%enabled on and add a passenger@base@uri option to the server bloc7!
http B ... server B listen $0? server>name www.phusion.nl? root #websites#phusion? passenger>enable& on? passenger>base>uri #rac*? C C ...

D E--- These lines have D E--- been a&&e&.

hen restart Nginx. he application has now been deployed. Kou can deploy multiple Rac7 applications under a virtual host, by specifying passenger@base@uri multiple times. /or example!
server B ... passenger>base>uri #app1? passenger>base>uri #app)? passenger>base>uri #app3? C

+.+. #edeploying >restarting the #a % appli ationA


,eploying a new version of a Rac7 application is as simple as re-uploading the application files, and restarting the application.

&*

here are two ways to restart the application! #. Dy restarting Nginx. &. Dy creating or modifying the file tmp/restart.t!t in the Rac7 application>s root folder. Phusion Passenger will automatically restart the application. /or example, to restart our example application, we type this in the command line!
touch #webapps#rac*app#tmp#restart.txt

+.,. #a %up spe ifi ations for various !eb frame!or%s


his subsection shows example config.ru files for various web framewor7s.

+.,.1. /amping
reJuire 4rubygems4 reJuire 4rac*4 reJuire 4camping4 DDDDD Kegin 2amping application 2amping.goes "Klog ...your application co&e here... DDDDD ,n& 2amping application run +ac*""A&apter""2amping.new8Klog:

/or $amping versions &.8 and up, using run Dlog as the final line will do.

+.,.2. *al yon


reJuire 4rubygems4 reJuire 4halcyon4 !LMA<>PATH.unshi%t8Halcyon.root # 4lib4: Halcyon""+unner.loa&>con%ig Halcyon.root#4con%ig4#4con%ig.yml4 run Halcyon""+unner.new

+.,.&. 6a %
,NOG5PA2;>,NO5I ,NOG5+A2;>,NO5I loa&85+a*e%ile5: reJuire 4rubygems4 reJuire 4mac*4 run Pac*""@tils""7erver.buil&>app

&+

+.,.+. 6erb
reJuire 4rubygems4 reJuire 4merb-core4 Perb""2on%ig.setup8 "merb>root 6 ""-ile.expan&>path8""-ile.&irname8>>-.L,>>::H "environment 6 ,NOG4+A2;>,NO4I : Perb.environment Perb""2on%igG"environmentI Perb.root Perb""2on%igG"merb>rootI Perb""KootLoa&er.run run Perb""+ac*""Application.new

+.,.,. #ama<e
reJuire 5rubygems5 reJuire 5rama0e5 +ama0e.traitG"essentialsI.&elete +ama0e""A&apter reJuire 5start5 +ama0e.startQ run +ama0e""A&apter""Kase

+.,.-. Sinatra
reJuire 4rubygems4 reJuire 4sinatra4 set "environmentH ,NOG4+A2;>,NO4I.to>sym &isable "runH "reloa& reJuire 4app.rb4 run 7inatra""Application

,. 0eploying a WSGI >PythonA appli ation


Phusion Passenger supports all '%(I-compliant Python web applications. %uppose that you have a '%(I application in /&ebapps/&sgiapp. hen that folder must contain at least three entries!

passenger%&sgi.py, which Phusion Passenger will use as the main entry point for your application. his file must export a '%(I obIect called application. public/, a folder containing public static web assets, li7e images and stylesheets. tmp/, used for restart.t!t :our application restart mechanism=. his will be explained in a following subsection.

%o /&ebapps/&sgiapp must, at minimum, loo7 li7e this!

&-

#webapps#wsgiapp F '-- con%ig.ru F '-- public# F '-- tmp#

,.1. )utorialCexample" !riting and deploying a *ello World WSGI appli ation
/irst we create a Phusion Passenger-compliant '%(I directory structure!
! m*&ir #webapps#wsgi>example ! m*&ir #webapps#wsgi>example#public ! m*&ir #webapps#wsgi>example#tmp

Next, we write a minimal Vhello worldV '%(I application!


! c& #webapps#wsgi>example ! some>awesome>e&itor passenger>wsgi.py ...type in some source co&e... ! cat passenger>wsgi.py &e% application8environH start>response:" start>response84)00 M;4H G842ontent-Type4H 4text#plain4:I: return G5hello worl&QRn5I

/inally, we deploy it by adding the following configuration options to the Nginx configuration file!
http B ... server B listen $0? server>name www.wsgiexample.com? root #webapps#wsgi>example#public? passenger>enable& on? C ... C

And we>re doneR After an Nginx restart, the above '%(I application will be available under the .R1 http(//&&&.&sgie!ample.com/.

,.2. 0eploying to a virtual hostBs root


Add a server virtual host entry to your Nginx configuration file. he virtual host>s root must point to your '%(I application>s public folder. Kou must also set passenger%enabled on in the server bloc7. /or example!
http B

&2

... server B listen $0? server>name www.wsgiapp.com? root #webapps#wsgiapp#public? passenger>enable& on? C ... C

hen restart Nginx. he application has now been deployed.

,.&. #edeploying >restarting the WSGI appli ationA


,eploying a new version of a '%(I application is as simple as re-uploading the application files, and restarting the application. here are two ways to restart the application! #. Dy restarting Nginx. &. Dy creating or modifying the file tmp/restart.t!t in the '%(I application>s root folder. Phusion Passenger will automatically restart the application. /or example, to restart our example application, we type this in the command line!
touch #webapps#wsgiapp#tmp#restart.txt

-. /onfiguring Phusion Passenger


After installation, Phusion Passenger does not need any further configurations. Nevertheless, the system administrator may be interested in changing Phusion Passenger>s behavior. Phusion Passenger supports the following configuration options in the Nginx configuration file!

-.1. passengerDroot Edire tory?


he location to the Phusion Passenger root directory. his configuration option is essential to Phusion Passenger, and allows Phusion Passenger to locate its own data files. he correct value is given by the installer. If you>ve moved Phusion Passenger to a different directory then you need to update this option as well. Please read 9oving Phusion Passenger to a different directory for more information. his reCuired option may only occur once, in the http configuration bloc7. &4

-.2. passengerDruby Efilename?


his option allows one to specify the Ruby interpreter to use. %ince version *.8.8, this option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

If you want to use a different Ruby interpreter for two different applications then you should define different passenger@ruby directives in different http bloc7s. In versions prior to *.8.8, only a single Ruby version is supported for the entire Nginx instance, so passenger@ruby may only occur in the http configuration bloc7. he default value is ruby, meaning that the Ruby interpreter will be loo7ed up according to the PA " environment variable.

-.&. passengerDpython Efilename?


Introdu ed in version +.=.=. his option allows one to specify the Python interpreter to use. It may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

If you want to use a different Python interpreter for two different applications then you should define different passenger@python directives in different http bloc7s. he default value is python, meaning that the Python interpreter will be loo7ed up according to the PA " environment variable.

-.+. passengerDappDroot EpathCtoCroot?


&5

Introdu ed in version +.=.=. Dy default, Phusion Passenger assumes that the application>s root directory is the parent directory of the public directory. his option allows one to specify the application>s root independently from the Nginx root, which is useful if the public directory lives in a non-standard place. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. 3xample!


server B server>name test.host? root #var#rails#0ena#sites#example.com#public? D normally Phusion Passenger woul& D have assume& that the application D root is 5#var#rails#0ena#sites#example.com5 passenger>app>root #var#rails#0ena? C

-.,. passengerDspa!nDmethod Estring?


V'hat spawn method should I useMV his subsection attempts to describe spawn methods, but it>s o7ay if you don>t :want to= understand it, as it>s mostly a technical detail. Kou can basically follow this rule of thumb! If your application wor7s on 9ongrel, but not on Phusion Passenger, then set passenger@spawn@method to direct. 0therwise, leave it at smart :the default=. "owever, we do recommend you to try to understand it. he smart spawn method brings many benefits. Internally, Phusion Passenger spawns multiple Ruby application processes in order to handle reCuests. Dut there are multiple ways with which processes can be spawned, each having its own set of pros and cons. %upported spawn methods are! smart his spawning method caches code using the app preloader. /ramewor7 code is not cached between multiple applications, although it is cached within instances of the

)8

same application. Please read %pawning methods explained for a more detailed explanation of what smart spawning exactly does. Pros" %mart spawning caches code where possible to speed up the respawn process and is compatible with most applications /ons" It is possible that it may be incompatible with some applications direct his spawning method is similar to the one used in 9ongrel $luster. It does not perform any code caching at all. Please read %pawning methods explained for a more detailed explanation of what direct spawning exactly does. Pros" ,irect spawning is guaranteed to be compatible with all applications and libraries. /ons" 9uch slower than smart spawning. 3very spawn action will be eCually slow, though no slower than the startup time of a single server in 9ongrel $luster. ,irect spawning will also render Ruby 3nterprise 3dition>s memory reduction technology useless. As of Passenger ).&, conservative spawning was renamed to direct and smart-lv was renamed to smart. he old smart spawning has been removed in favor of the new version. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is smart.

-.-. passengerDrollingDrestarts EonFoff?


)his feature is only available in Phusion Passenger 9nterprise. It !as introdu ed in version &.=.=. 7uy Phusion Passenger 9nterprise here. 3nables or disables support for rolling restarts. Normally when you restart an application :by touching restart.txt=, Phusion Passenger would shut down all application processes and spawn a new one. he spawning of a new application process could ta7e a while, and any reCuests that come in during this time will be bloc7ed until this first application process has spawned. Dut when rolling restarts are enabled, Phusion Passenger 3nterprise will!

)#

#. %pawn a new process in the bac7ground. &. 'hen it>s done spawning, Phusion Passenger 3nterprise will replace one of the old processes with this newly spawned one. ). %tep # and & are repeated until all processes have been replaced. his way, visitors will not experience any delays when you are restarting your application. his allows you to, for example, upgrade your application often without degrading user experience. Rolling restarts have a few caveat however that you should be aware of!

.pgrading an application sometimes involves upgrading the database schema. 'ith rolling restarts, there may be a point in time during which processes belonging to the previous version and processes belonging to the new version both exist at the same time. Any database schema upgrades you perform must therefore be bac7wardscompatible with the old application version. Decause there>s no telling which process will serve a reCuest, users may not see changes brought about by the new version until all processes have been restarted. It is for this reason that you should not use rolling restarts in development, only in production.

his option may occur in the following places!


In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is off.

-.8. passengerDresistDdeploymentDerrors EonFoff?


)his feature is only available in Phusion Passenger 9nterprise. It !as introdu ed in version &.=.=. 7uy Phusion Passenger 9nterprise here. 3nables or disables resistance against deployment errors. %uppose you>ve upgraded your application and you>ve issues a command to restart it :by touching restart.txt=, but the application code contains an error that prevents Phusion Passenger from successfully spawning a process :e.g. a syntax error=. Phusion Passenger would normally display an error message in response to this. Dy enabling deployment error resistance, Phusion Passenger 3nterprise would instead do this!

)&

It passes the reCuest to one of the existing application processes :that belong to the previous version of the application=. he visitor will not see a Phusion Passenger process spawning error message. It logs the error to the global web server error log file. It sets an internal flag so that no processes for this application will be spawned :even when the current traffic would normally result in more processes being spawned= and no processes will be idle cleaned. Processes ould still be shutdown because of other events, e.g. because their memory limit have been reached.

his way, visitors will suffer minimally from deployment errors. Phusion Passenger will attempt to restart the application again next time restart.txt is touched. 3nabling deployment error resistance only wor7s if rolling restart is also enabled. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is off.

-.:. passengerDtempDdir Edire tory?


%pecifies the directory that Phusion Passenger should use for storing temporary files. his includes things such as .nix soc7et files. his option may only be specified in the http configuration bloc7. he default temp directory that Phusion Passenger uses is /tmp. his option is especially useful if Nginx is not allowed to write to ?tmp :which is the case on some systems with strict %31inux policies= or if the partition that ?tmp lives on doesn>t have enough dis7 space. $ommand line tools %ome Phusion Passenger command line administration tools, such as passenger-status, must 7now what Phusion Passenger>s temp directory is in order to function properly. Kou can pass the directory through the PA%%3N(3R@ 9P,IR environment variable, or the 9P,IR environment variable :the former will be used if both are specified=. /or example, if you set passenger%temp%dir to /my%temp%dir, then invo7e passenger-status after you>ve set the PA%%3N(3R@ 9P,IR or 9P,IR environment variable, li7e this!

))

export PA77,NS,+>TPP<.+ #my>temp-&ir su&o -, passenger-status D The -, option tells 4su&o4 to preserve environment variables.

-.;. Important deployment options

-.;.1. passengerDenabled EonFoff? his option may be specified in the http configuration bloc7, a server configuration bloc7, a location configuration bloc7 or an if configuration scope, to enable or disable Phusion Passenger for that server or that location. Phusion Passenger is disabled by default, so you must explicitly enable it for server bloc7s that you wish to serve through Phusion Passenger. Please see ,eploying a Ruby on Rails application and ,eploying a Rac7-based Ruby application for examples.

-.;.2. passengerDbaseDuri Euri? .sed to specify that the given .RI is an distinct application that should be served by Phusion Passenger. his option can be used for both Rails and Rac7 applications. %ee ,eploying Rails to a sub .RI for an example. It is allowed to specify this option multiple times. ,o this to deploy multiple applications in different sub-.RIs under the same virtual host. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

-.1=. /onne tion handling options

-.1=.1. passengerDignoreD lientDabort EonFoff? Normally, when the " P client aborts the connection :e.g. when the user clic7ed on V%topV in the browser=, the connection with the application process will be closed too. If the application process continues to send its response, then that will result in 3PIP3 errors in the )*

application, which will be printed in the error log if the application doesn>t handle them gracefully. If this option is turned on then upon client abort Phusion Passenger will continue to read the application process>s response while discarding all the read data. his prevents 3PIP3 errors but it>ll also mean the bac7end process will be unavailable for new reCuests until it is done sending its response. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is off.

-.1=.2. passengerDsetD giDparam E/GI environment name? Evalue? Allows one to define additional $(I environment variables to pass to the bac7end application. his is eCuivalent to ngx@http@fastcgi@module>s fastcgi%param directive, and is comparable to ngx@http@proxy@module>s pro!y%set%header option. Nginx variables in the value are interpolated. /or example!
D Application will see a 2S. environment 5APP>NAP,5 with value 5my super blog5. passenger>set>cgi>param APP>NAP, 5my super blog5? D Nginx variables are interpolate&. passenger>set>cgi>param ,/T+A>+,A@,7T>P,THM< metho& !reJuest>metho&?

If you want to set an " i.e. )**+%,!

P header, then you must set it in the $(I environment name format,

D QQQTH.7 .7 T+MNSQQQ <on4t &o thisQ passenger>set>cgi>param /--orwar&e&--or 1)3.0.0.)? D .nstea&H write it li*e this" passenger>set>cgi>param HTTP>/>-M+TA+<,<>-M+ 1)3.0.0.)?

his option may occur in the following places!


In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. )+

In an if configuration scope.

-.1=.&. passengerDpassDheader Eheader name? %ome headers generated by bac7end applications are not forwarded to the " P client, e.g. --.ccel-/edirect which is directly processed by Nginx and then discarded from the final response. his directive allows one to force Nginx to pass those headers anyway, similar to how pro!y%pass%header wor7s. /or example!
location # B passenger>pass>hea&er /-Accel-+e&irect? C

his option may occur in the following places!


In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

-.1=.+. passengerDbufferDresponse EonFoff? 'hen turned on, application-generated responses are buffered by Nginx. Duffering will happen in memory and also on dis7 if the response is larger than a certain threshold. Defore we proceed with explaining this configuration option, we want to state the following to avoid confusion. If you use Phusion Passenger for Nginx, there are in fact two response buffering systems active! #. &. he Nginx response buffering system. passenger@buffer@response turns this on or off. he Phusion Passenger response buffering system, a.7.a. real-time dis'-bac'ed response buffering. his buffering system is always on, regardless of the value of passenger@buffer@response.

Response buffering is useful because it protects against slow " P clients that do not read responses immediately or Cuic7ly enough. Duffering prevents such slow clients from bloc7ing web applications that have limited concurrency. Decause Phusion Passenger>s response buffering is always turned on, you are always protected. herefore, passenger@buffer@response is off by default, and you never should have to turn it on. If for whatever reason you want to turn Nginx-level response buffering on, you can do so with this option.

)-

Nginx>s response buffering wor7s differently from Phusion Passenger>s. Nginx>s buffering system buffers the entire response before attempting to send it to the client, while Phusion Passenger>s attempts to send the data to the client immediately. herefore, if you turn on passenger@buffer@response, you may interfere with applications that want to stream responses to the client. "ow does response buffering - whether it>s done by Nginx or by Phusion Passenger - exactly protect against slow clientsM $onsider an " P client that>s on a dial-up modem lin7, and your application process generates a & 9D response. If the response is buffered then your application process will be bloc7ed until the entire & 9D has been sent out to the " P client. his disallows your application process to do any useful wor7 in the mean time. Dy buffering responses, Phusion Passenger or Nginx will read the application response as Cuic7ly as possible and will ta7e care of forwarding the data to slow clients. %o 7eep in mind that enabling passenger@buffering@response will ma7e streaming responses impossible. $onsider for example this piece of Rails code!
ren&er "text 6 lamb&a B FresponseH outputF 10.times &o FiF output.write85entry DBiCRn5: output.%lush sleep 1 en& C

Oor this piece of Rac7 code!


class +esponse &e% each 10.times &o FiF yiel&85entry DBiCRn5: sleep 1 en& en& en& app en& lamb&a &o FenvF G)00H B 52ontent-Type5 6 5text#plain5 CH +esponse.newI

'hen passenger@buffer@response is turned on, Nginx will wait until the application is done sending the entire response before forwarding it to the client. he client will not receive anything for #8 seconds, after which it receives the entire response at once. 'hen passenger@buffer@response is turned off, it wor7s as expected! the client receives an Ventry HV message every second for #8 seconds. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7.

)2

In an if configuration scope.

In each place, it may be specified at most once. he default value is off.

-.1=.,. passengerDbufferDsi<e

-.1=.-. passengerDbuffers

-.1=.8. passengerDbusyDbufferDsi<e hese options have the same effect as proxy@module>s similarly named options. hey can be used to modify the maximum allowed " P header si6e.

-.11. Se urity options

-.11.1. passengerDuserDs!it hing EonFoff? 'hether to enable user switching support. his option may only occur once, in the http configuration bloc7. he default value is on.

-.11.2. passengerDuser Eusername? If user switching support is enabled, then Phusion Passenger will by default run the web application as the owner of the file config/environment.rb :for Rails apps= or config.ru :for Rac7 apps=. his option allows you to override that behavior and explicitly set a user to run the web application as, regardless of the ownership of environment.rb?config.ru. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. )4

-.11.&. passengerDgroup Egroup name? If user switching support is enabled, then Phusion Passenger will by default run the web application as the primary group of the owner of the file config/environment.rb :for Rails apps= or config.ru :for Rac7 apps=. his option allows you to override that behavior and explicitly set a group to run the web application as, regardless of the ownership of environment.rb?config.ru. 0group name1 may also be set to the special value 2S*./*U+%34562, in which case the web application>s group will be set to environment.rb?config.ruWs group. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once.

-.11.+. passengerDdefaultDuser Eusername? Phusion Passenger enables user switching support by default. his configuration option allows one to specify the user that applications must run as, if user switching fails or is disabled. his option may only occur once, in the http configuration bloc7. he default value is nobody.

-.11.,. PassengerDdefaultDgroup Egroup name? Phusion Passenger enables user switching support by default. his configuration option allows one to specify the group that applications must run as, if user switching fails or is disabled. his option may only occur once, in the http configuration bloc7. he default value is the primary group of the user specifified by passenger@default@user.

-.11.-. passengerDsho!DversionDinDheader EonFoff?

)5

'hen turned on, Phusion Passenger will output its version number in the %erver and HPowered-Dy header in all Phusion Passenger-served reCuests!
7erver" nginx#1.3.11 ' Phusion Passenger 1.0.0 /-Powere&-Ky" Phusion Passenger 1.0.0

'hen turned off, the version number will be hidden!


7erver" nginx#1.3.11 ' Phusion Passenger /-Powere&-Ky" Phusion Passenger

his option may occur in the following places!


In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is on.

-.11.8. passengerDfriendlyDerrorDpages EonFoff? Phusion Passenger can display friendly error pages whenever an application fails to start. his friendly error page presents the startup error message, some suggestions for solving the problem, and a bac7trace. his feature is very useful during application development and useful for less experienced system administrators, but the page might reveal potentially sensitive information, depending on the application. 3xperienced system administrators who are using Phusion Passenger on serious production servers should consider turning this feature off. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is on.

-.12. #esour e ontrol and optimi<ation options

*8

-.12.1. passengerDmaxDpoolDsi<e Einteger? he maximum number of application processes that may simultanously exist. A larger number results in higher memory usage, but improved ability to handle concurrent " P clients. he optimal value depends on your system>s hardware and the server>s average load. Kou should experiment with different values. Dut generally spea7ing, the value should be at least eCual to the number of $P.s :or $P. cores= that you have. If your system has & (D of RA9, then we recommend a value of 17. If your system is a Nirtual Private %erver :NP%= and has about &+- 9D RA9, and is also running other services such as 9y%X1, then we recommend a value of . If you find that your server is unable to handle the load on your Rails?Rac7 websites :i.e. running out of memory= then you should lower this value. : hough if your sites are really that popular, then you should strongly consider upgrading your hardware or getting more servers.= his option may only occur once, in the http configuration bloc7. he default value is 6. 'e strongly recommend you to use Ruby 3nterprise 3dition. his allows you to reduce the memory usage of your Ruby on Rails applications by about ))E, and it>s not hard to install. -.12.2. passengerDminDinstan es Einteger? his specifies the minimum number of application processes that should exist for a given application. Kou should set this option to a non-6ero value if you want to avoid potentially long startup times after a website has been idle for an extended period. Please note that this option does not pre-start application processes during Nginx startup. It Iust ma7es sure that when the application is first accessed! #. at least the given number of processes will be spawned. &. the given number of processes will be 7ept around even when processes are being idle cleaned :see passenger@pool@idle@time=. If you want to pre-start application processes during Nginx startup, then you should use the passenger@pre@start directive, possibly in combination with passenger%min%instances. his behavior might seem counter-intuitive at first sight, but passenger@pre@start explains the rationale behind it. /or example, suppose that you have the following configuration!
http B ... passenger>max>pool>si0e 1=? passenger>pool>i&le>time 10? server B listen $0?

*#

C C

server>name %oobar.com? root #webapps#%oobar#public? passenger>min>instances 3?

'hen you start Nginx, there are 8 application processes for foobar.com. hings will stay that way until someone visits foobar.com. %uppose that there is only # visitor. # application process will be started immediately to serve the visitor, while & will be spawned in the bac7ground. After #8 seconds, when the idle timeout has been reached, these ) application processes will not be cleaned up. Now suppose that there>s a sudden spi7e of traffic, and #88 users visit foobar.com simultanously. Phusion Passenger will start #& more application processes. After the idle timeout of #8 seconds have passed, Phusion Passenger will clean up #& application processes, 7eeping ) processes around. he passenger@min@instances option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is 1.

-.12.&. passengerDmaxDinstan es Einteger? )his feature is only available in Phusion Passenger 9nterprise. It !as introdu ed in version &.=.=. 7uy Phusion Passenger 9nterprise here. he maximum number of application processes that may simultaneously exist for an application. his helps to ma7e sure that a single application will not occupy all available slots in the application pool. his value must be less than passenger@max@pool@si6e. A value of 8 means that there is no limit placed on the number of processes a single application may spawn, i.e. only the global limit of passenger@max@pool@si6e will be enforced. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope. *&

In each place, it may be specified at most once. he default value is #. Practical usage example %uppose that you>re hosting two web applications on your server, a personal blog and an e-commerce website. Kou>ve set passenger@max@pool@si6e to #8. he ecommerce website is more important to you. Kou can then set passenger%ma!%instances to ) for your blog, so that it will never spawn more than ) processes, even if it suddenly gets a lot of traffic. Kour e-commerce website on the other hand will be free to spawn up to #8 processes if it gets a lot of traffic. -.12.+. passengerDmaxDinstan esDperDapp Einteger? he maximum number of application processes that may simultaneously exist for a single application. his helps to ma7e sure that a single application will not occupy all available slots in the application pool. his value must be less than passenger@max@pool@si6e. A value of 8 means that there is no limit placed on the number of processes a single application may use, i.e. only the global limit of passenger@max@pool@si6e will be enforced. his option may only occur once, in the http configuration bloc7. he default value is #.

-.12.,. passengerDpoolDidleDtime Einteger? he maximum number of seconds that an application process may be idle. hat is, if an application process hasn>t received any traffic after the given number of seconds, then it will be shutdown in order to conserve memory. ,ecreasing this value means that applications will have to be spawned more often. %ince spawning is a relatively slow operation, some visitors may notice a small delay when they visit your Rails?Rac7 website. "owever, it will also free up resources used by applications more Cuic7ly. he optimal value depends on the average time that a visitor spends on a single Rails?Rac7 web page. 'e recommend a value of & Y x, where x is the average number of seconds that a visitor spends on a single Rails?Rac7 web page. Dut your mileage may vary. 'hen this value is set to #, application processes will not be shutdown unless it>s really necessary, i.e. when Phusion Passenger is out of wor7er processes for a given application and one of the inactive application processes needs to ma7e place for another application process. %etting the value to 8 is recommended if you>re on a non-shared host that>s only running a few applications, each which must be available at all times. his option may only occur once, in the http configuration bloc7. he default value is 3##.

*)

-.12.-. passengerDmaxDpreloaderDidleDtime Einteger? he Application%pawner server :explained in %pawning methods explained= has an idle timeout, Iust li7e the bac7end processes spawned by Phusion Passenger do. hat is, it will automatically shutdown if it hasn>t done anything for a given period. his option allows you to set the Application%pawner server>s idle timeout, in seconds. A value of # means that it should never idle timeout. %etting a higher value will mean that the Application%pawner server is 7ept around longer, which may slightly increase memory usage. Dut as long as the Application%pawner server is running, the time to spawn a Ruby on Rails bac7end process only ta7es about #8E of the time that is normally needed, assuming that you>re using the smart or smart-lv spawning method. %o if your system has enough memory, is it recommended that you set this option to a high value or to #. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is 3## :+ minutes=.

-.12.8. passengerD on urren yDmodel Epro essFthread? )his feature is only available in Phusion Passenger 9nterprise. It !as introdu ed in version +.=.=. 7uy Phusion Passenger 9nterprise here. %pecifies the I?0 concurrency model that should be used for application processes. Phusion Passenger supports two concurrency models!

process - single-threaded, multi-processed I?0 concurrency. 3ach application process only has a single thread and can only handle # reCuest at a time. his is the concurrency model that Ruby applications traditionally used. It has excellent compatiblity :can wor7 with applications that are not designed to be thread-safe= but is unsuitable wor7loads in which the application has to wait for a lot of external I?0 :e.g. " P API calls=, and uses more memory because each process has a large memory overhead. thread - multi-threaded, multi-processed I?0 concurrency. 3ach application process has multiple threads :customi6able via passenger@thread@count=. his model provides much better I?0 concurrency and uses less memory because threads share memory with each other within the same process. "owever, using this model may cause compatibility problems if the application is not designed to be thread-safe. **

his option may occur in the following places!


In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is process.

-.12.:. passengerDthreadD ount Enumber? )his feature is only available in Phusion Passenger 9nterprise. It !as introdu ed in version +.=.=. 7uy Phusion Passenger 9nterprise here. %pecifies the number of threads that Phusion Passenger should spawn per application process. his option only has effect if passenger@concurrency@model is thread. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is 1.

-.12.;. passengerDmaxDreGuests Einteger? he maximum number of reCuests an application process will process. After serving that many reCuests, the application process will be shut down and Phusion Passenger will restart it. A value of 8 means that there is no maximum! an application process will thus be shut down when its idle timeout has been reached. his option is useful if your application is lea7ing memory. Dy shutting it down after a certain number of reCuests, all of its memory is guaranteed to be freed by the operating system. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7.

*+

In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is #. he passenger@max@reCuests directive should be considered as a wor7around for misbehaving applications. It is advised that you fix the problem in your application rather than relying on these directives as a measure to avoid memory lea7s. -.12.1=. passengerDmaxDreGuestDtime Ese onds? )his feature is only available in Phusion Passenger 9nterprise. It !as introdu ed in version &.=.=. 7uy Phusion Passenger 9nterprise here. he maximum amount of time, in seconds, that an application process may ta7e to process a reCuest. If the reCuest ta7es longer than this amount of time, then the application process will be forcefully shut down, and possibly restarted upon the next reCuest. A value of 8 means that there is no time limit. his option is useful for preventing your application from free6ing for an indefinite period of time. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is #. 3xample %uppose that most of your reCuests are 7nown to finish within & seconds. "owever, there is one .RI, /e!pensive%computation, which is 7nown to ta7e up to #8 seconds. Kou can then configure Phusion Passenger as follows!
server B listen $0? server>name www.example.com? root #webapps#my>app#public? passenger>enable& on? passenger>max>reJuest>time )? location #expensive>compuation B passenger>enable& on? passenger>max>reJuest>time 10?

*-

If a reCuest to /e!pensive%computation ta7es more than #8 seconds, or if a reCuest to any other .RI ta7es more than & seconds, then the corresponding application process will be forced to shutdown. he passenger@max@reCuest@time directive should be considered as a wor7around for misbehaving applications. It is advised that you fix the problem in your application rather than relying on these directives as a measure to avoid free6ing applications. -.12.11. passengerDmemoryDlimit Einteger? )his feature is only available in Phusion Passenger 9nterprise. It !as introdu ed in version &.=.=. 7uy Phusion Passenger 9nterprise here. he maximum amount of memory that an application process may use, in megabytes. 0nce an application process has surpassed its memory limit, it will process all the reCuests currently present in its Cueue and then shut down. A value of 8 means that there is no maximum! the application>s memory usage will not be chec7ed. his option is useful if your application is lea7ing memory. Dy shutting it down, all of its memory is guaranteed to be freed by the operating system. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is #. A word about permissions he passenger@memory@limit directive uses the ps command to Cuery memory usage information. 0n 1inux, it further Cueries ?proc to obtain additional memory usage information that>s not obtainable through ps. Kou should ensure that the ps wor7s correctly and that the ?proc filesystem is accessible by the Passenger"elperAgent process. he passenger@max@reCuests and passenger@memory@limit directives should be considered as wor7arounds for misbehaving applications. It is advised that you fix the problem in your application rather than relying on these directives as a measure to avoid memory lea7s.

*2

-.12.12. passengerDpreDstart Eurl? Dy default, Phusion Passenger does not start any application processes until said web application is first accessed. he result is that the first visitor of said web application might experience a small delay as Phusion Passenger is starting the web application on demand. If that is undesirable, then this directive can be used to pre-started application processes during Nginx startup. A few things to be careful of!

his directive accepts the 1#4 of the web application you want to pre-start, not a on?off valueR his might seem a bit weird, but read on for rationale. As for the specifics of the .R1! o he domain part of the .R1 must be eCual to the value of the server%name directive of the server bloc7 that defines the web application.
o

.nless the web application is deployed on port 48, the .R1 should contain the web application>s port number too. he path part of the .R1 must point to some .RI that the web application handles.

Kou will probably want to combine this option with passenger@min@instances because application processes started with passenger%pre%start are subIect to the usual idle timeout rules. %ee the example below for an explanation.

his option may only occur in the http configuration bloc7. It may be specified any number of times.
9xample 1" basi usage

%uppose that you have the following web applications.


server B listen $0? server>name %oo.com? root #webapps#%oo#public? passenger>enable& on? C server B listen 3=00? server>name bar.com? root #webapps#bar#public? passenger>enable& on? C

Kou want both of them to be pre-started during Nginx startup. he .R1 for foo.com is http(//foo.com/ :or, eCuivalently, http(//foo.com($#/= and the .R1 for bar.com is http(//bar.com(37##/. %o we add two passenger@pre@start directives, li7e this!
server B listen $0?

*4

server>name %oo.com? root #webapps#%oo#public? passenger>enable& on?

server B listen 3=00? server>name bar.com? root #webapps#bar#public? passenger>enable& on? C passenger>pre>start http"##%oo.com#? passenger>pre>start http"##bar.com"3=00#? 9xample 2" pre$starting apps that are deployed in sub$1#Is D E--- a&&e& D E--- a&&e&

%uppose that you have a web application deployed in a sub-.RI /store, li7e this!
server B listen $0? server>name myblog.com? root #webapps#wor&press? rails>base>uri #store? C

hen specify the server%name value followed by the sub-.RI, li7e this!
server B listen $0? server>name myblog.com? root #webapps#wor&press? rails>base>uri #store? C passenger>pre>start http"##myblog.com#store? D E----- a&&e&

he sub-.RI must be includedZ if you don>t then the directive will have no effect. he following example is wrong and won>t pre-start the store web application!
passenger>pre>start http"##myblog.com#? part. 9xample &" ombining !ith passengerDminDinstan es D E----- T+MNSQ Pissing 5#store5

Application processes started with passenger@pre@start are also subIect to the idle timeout rules as specified by passenger@pool@idle@timeR hat means that by default, the pre-started application processes for foo.com are bar.com are shut down after a few minutes of inactivity. If you don>t want that to happen, then you should combine passenger@pre@start with passenger@min@instances, li7e this!
server B listen $0? server>name %oo.com? root #webapps#%oo#public? passenger>enable& on? passenger>min>instances 1?

D E--- a&&e&

*5

C server B listen 3=00? server>name bar.com? root #webapps#bar#public? passenger>enable& on? passenger>min>instances 1? C

D E--- a&&e&

passenger>pre>start http"##%oo.com#? passenger>pre>start http"##bar.com"3=00#? So !hy a 1#4H Why not Iust an onCoff flagH

A directive that accepts a simple on?off flag is definitely more intuitive, but due technical difficulties w.r.t. the way Nginx wor7s, it>s very hard to implement it li7e that! It is very hard to obtain a full list of web applications defined in the Nginx configuration file:s=. In other words, it>s hard for Phusion Passenger to 7now which web applications are deployed on Nginx until a web application is first accessed, and without such a list Phusion Passenger wouldn>t 7now which web applications to pre-start. %o as a compromise, we made it accept a .R1.
What does Phusion Passenger do !ith the 1#4H

,uring Nginx startup, Phusion Passenger will send a dummy "3A, reCuest to the given .R1 and discard the result. In other words, Phusion Passenger simulates a web access at the given .R1. "owever this simulated reCuest is always sent to localhost, not to the IP that the domain resolves to. %uppose that bar.com in example # resolves to &85.4+.&&2.55Z Phusion Passenger will send the following " P reCuest to #&2.8.8.# port )+88 :and not to &85.4+.&&2.55 port )+88=!
H,A< # HTTP#1.1 Host" bar.com 2onnection" close

%imilarly, for example &, Phusion Passenger will send the following " #&2.8.8.# port 48!
H,A< #store HTTP#1.1 Host" myblog.com 2onnection" close 0o I need to edit Cet Chosts and point the domain in the 1#4 to 128.=.=.1H

P reCuest to

No. %ee previous subsection.


6y !eb appli ation onsists of multiple !eb servers. What 1#4 do I need to spe ify, and in !hi h !eb serverBs Nginx onfig fileH

Put the web application>s server%name value and the server bloc7>s port in the .R1, and put passenger@pre@start on all machines that you want to pre-start the web application on. he simulated web reCuest is always sent to #&2.8.8.#, with the domain name in the .R1 as value +8

for the )ost " P header, so you don>t need to worry about the reCuest ending up at a different web server in the cluster.
0oes passengerDpreDstart support https"CC 1#4sH

Kes. And it does not perform any certificate validation.

-.1&. 4ogging and debugging options

-.1&.1. passengerDlogDlevel Einteger? his option allows one to specify how much information Phusion Passenger should write to the Nginx error log file. A higher log level value means that more information will be logged. Possible values are!

#! %how only errors and warnings. 1! %how the most important debugging information. his might be useful for system administrators who are trying to figure out the cause of a problem. ! %how more debugging information. his is typically only useful for developers. 3! %how even more debugging information.

his option may only occur once, in the http configuration bloc7. he default is #.

-.1&.2. passengerDdebugDlogDfile Efilename? Dy default Phusion Passenger debugging and error messages are written to the global web server error log. his option allows one to specify the file that debugging and error messages should be written to instead. his option may only occur once, in the http configuration bloc7.

-.1&.&. passengerDdebugger EonFoff? )his feature is only available in Phusion Passenger 9nterprise. It !as introdu ed in version &.=.=. 7uy Phusion Passenger 9nterprise here. urns support for application debugging on or off. In case of Ruby applications, turning this option on will cause them to load the ruby-debug gem :when on Ruby #.4= or the debugger gem :when on Ruby #.5=. If you>re using Dundler, you should add this to your (emfile! +#

gem 4ruby-&ebug4H "plat%orms 6 "ruby>1$ gem 4&ebugger4H "plat%orms 6 "ruby>19

0nce debugging is turned on, you can use the command passenger-irb --debug API,; to attach an rdebug console to the application process with the given PI,. Attaching will succeed once the application process executes a debugger command. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is off.

-.1+. #uby on #ails$spe ifi options

-.1+.1. railsDenv Estring? his option allows one to specify the default RAI1%@3NN value. his option may occur in the following places!

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is production.

-.1,. #a % and #ails ?@ & spe ifi options

-.1,.1. ra %Denv Estring? his option allows one to specify the default RA$S@3NN value. his option may occur in the following places! +&

In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.

In each place, it may be specified at most once. he default value is production.

-.1-. 0epre ated options


he following options have been deprecated, but are still supported for bac7wards compatibility reasons.

-.1-.1. railsDspa!nDmethod ,eprecated in favor of passenger@spawn@method.

8. (nalysis and system maintenan e


Phusion Passenger provides a set of tools, which are useful for system analysis, maintenance and troubleshooting.

8.1. Inspe ting memory usage


Process inspection tools such as ps and top are useful, but they rarely show the correct memory usage. he real memory usage is usually lower than what ps and top report. here are many technical reasons why this is so, but an explanation is beyond the scope of this .sers (uide. 'e 7indly refer the interested reader to operating systems literature about virtual memory and copy-on-&rite. he tool passenger-memory-stats allows one to easily analy6e Phusion Passenger>s and Apache>s real memory usage. /or example!
Gbash9localhost rootID passenger-memory-stats ------------- Apache processes --------------. P.< PP.< Threa&s OP7i0e Private Name ---------------------------------------------. =913 1 9 90.( PK 0.= PK #usr#sbin#apache) -* start =91$ =913 1 1$.9 PK 0.3 PK #usr#sbin#%cgi-pm -* start (0)9 =913 1 1).3 PK 0.= PK #usr#sbin#apache) -* start

+)

(030 =913 1 1).3 PK 0.= PK (031 =913 1 1).= PK 0.3 PK (033 =913 1 1).= PK 0.1 PK (031 =913 1 =0.= PK 0.1 PK )31$) =913 1 $).( PK 0.1 PK DDD Processes" $ DDD Total private &irty +77" 3.=0 PK

#usr#sbin#apache) #usr#sbin#apache) #usr#sbin#apache) #usr#sbin#apache) #usr#sbin#apache)

-* -* -* -* -*

start start start start start

--------- Passenger processes ---------. P.< Threa&s OP7i0e Private Name ---------------------------------------. (0)( 1 10.9 PK 1.3 PK Passenger spawn server )31$1 1 )(.3 PK 3.0 PK Passenger -ramewor*7pawner" ).0.) )3391 1 )(.$ PK ).9 PK Passenger Application7pawner" #var#www#proUects#app1-%oobar )3393 1 )(.9 PK 13.1 PK +ails" #var#www#proUects#app1-%oobar DDD Processes" 1 DDD Total private &irty +77" )3.3( P

he +rivate or private dirty /SS field shows the real memory usage of processes. "ere, we see that all the Apache wor7er processes only ta7e less than # 9D memory each. his is a lot less than the +8 9D-ish memory usage as shown in the 89Si:e column :which is what a lot of people thin7 is the real memory usage, but is actually not=. Private dirty R%% reporting only wor7s on 1inux. .nfortunately other operating systems don>t provide facilities for determining processesW private dirty R%%. 0n non1inux systems, the Resident %et %i6e is reported instead.

8.2. Inspe ting Phusion PassengerBs internal status


0ne can inspect Phusion Passenger>s internal status with the tool passenger-status. his tool must typically be run as root. /or example!
Gbash9localhost rootID passenger-status ----------- Seneral in%ormation ----------max ( count 1 active 0 inactive 1 ----------- <omains ----------#var#www#proUects#app1-%oobar" P.<" 9(13 7essions" 0 Processe&" 3

@ptime" )m )3s

he general information section shows the following information! max he maximum number of application instances that Phusion Passenger will spawn. his eCuals the value given for Passenger9axPool%i6e :Apache= or passenger@max@pool@si6e :Nginx=. count

+*

he number of application instances that are currently alive. his value is always less than or eCual to ma!. active he number of application instances that are currently processing reCuests. his value is always less than or eCual to count. inactive he number of application instances that are currently not processing reCuests, i.e. are idle. Idle application instances will be shutdown after a while, as can be specified with PassengerPoolIdle ime :Apache=?passenger@pool@idle@time :Nginx= :unless this value is set to 8, in which case application instances are never shut down via idle time=. he value of inactive eCuals count - active. he domains section shows, for each application directory, information about running application instances! %essions %hows how many " P client are currently in the Cueue of that application Instance, waiting to be processed. Processed Indicates how many reCuests the instance has served until now. )ip" it>s possible to limit this number with the Passenger9axReCuests configuration directive. .ptime %hows for how long the application instance has been running. %ince Phusion Passenger uses fair load balancing by default, the number of sessions for the application instances should be fairly close to each other. /or example, this is fairly normal!
P.<" P.<" P.<" P.<" 1)$1 1)($ 1)(= 1)3= 7essions" 7essions" 7essions" 7essions" ) 0 1 1 Processe&" Processe&" Processe&" Processe&" 3 = ( 3 @ptime" @ptime" @ptime" @ptime" =m 1m =m 3m 11s =)s 3$s 11s

Dut if you see a Vspi7eV, i.e. an application instance has an unusually high number of sessions compared to the others, then there might be a problem!
P.<" P.<" P.<" P.<" 1)$1 131($ 1)(= 1)3= 7essions" 7essions" 7essions" 7essions" ) Processe&" $ E-' Processe&" 1 F Processe&" 1 F Processe&" F '---- 5spi*e5 3 ) ( 3 @ptime" @ptime" @ptime" @ptime" =m 1m =m 3m 11s 13s 3$s 11s

++

he most li7ely reason why a spi7e occurs is because your application is fro6en, i.e. it has stopped responding. %ee ,ebugging fro6en applications for tips.

8.&. 0ebugging fro<en appli ations


If one of your application instances is fro6en :stopped responding=, then you can figure out where it is fro6en by 7illing it with S4;.</*. his will cause the application to raise an exception, with a bac7trace. he exception :with full bac7trace information= is normally logged into the Apache error log. Dut if your application or if its web framewor7 has its own exception logging routines, then exceptions might be logged into the application>s log files instead. his is the case with Ruby on Rails. %o if you 7ill a Ruby on Rails application with S4;.</*, please chec7 the application>s production.log first :assuming that you>re running it in a production environment=. If you don>t see a bac7trace there, chec7 the Apache error log. It is safe to 7ill application instances, even in live environments. Phusion Passenger will restart 7illed application instances, as if nothing bad happened.

8.+. ( essing individual appli ation pro esses


'hen a reCuest is sent to the web server, Phusion Passenger will automatically forward the reCuest to the most suitable application process, but sometimes it is desirable to be able to directly access the individual application processes. .se cases include, but are not limited to!

0ne wants to debug a memory lea7 or memory bloat problem that only seems to appear on certain .RIs. 0ne can send a reCuest to a specific process to see whether that reCuest causes the process>s memory usage to rise. he application caches data in local memory, and one wants to tell a specific application process to clear that local data. 0ther debugging use cases.

All individual application processes are accessible via " P, so you can use standard " P tools li7e curl. he exact addresses can be obtained with the command passenger-status --verbose. hese soc7ets are all bound to #&2.8.8.#, but the port number is dynamically assigned. As a security measure, the soc7ets are also protected with a process-specific random password, which you can see in the passenger-status --verbose output. his password must be sent through the TH-Passenger-$onnect-PasswordU " P header. 3xample!
bashD passenger-status --verbose ----------- Seneral in%ormation ----------max ( count ) active 0

+-

inactive ) Taiting on global Jueue" 0 ----------- Application groups ----------#@sers#hongli#7ites#rac*.test" App root" #@sers#hongli#7ites#rac*.test V P.<" )1)3= 7essions" 0 Processe&" 3 @ptime" 13s @+L " http"##1)3.0.0.1"=$1)) Passwor&" n-%OM/1-$LUW90HXh)$7&>htXMsg+sNne)A/;%$N./w V P.<" )1)=0 7essions" 0 Processe&" 1 @ptime" 1s @+L " http"##1)3.0.0.1"=3933 Passwor&" >+S/lA9,S<SX;LevA>J%l@t-1;mx,o)@i+0Pw.,1sKY

"ere we see that the web application rac'.test has two processes. Process &*&)+ is accessible via http!??#&2.8.8.#!+4#&&, and process &*&+8 is accessible via http!??#&2.8.8.#!+25)). o access &*&)+ we must send its password, n3f8O-13$5=>9#)?h $Sd%ht?Osg/s@ne A-Bf$@4-&, through the --+assenger-Connect+ass&ord " P header, li7e this!
bashD curl -H 5/-Passenger-2onnect-Passwor&" n-%OM/1-$LUW90HXh)$7&>htXMsg+sNne)A/;%$N./w5 http"##1)3.0.0.1"=$1))#

8.,. (tta hing an I#7 onsole to an appli ation pro ess


)his feature is only available in Phusion Passenger 9nterprise. It !as introdu ed in version &.=.=. 7uy Phusion Passenger 9nterprise here. Kou can attach an IRD console to any application process and inspect its state by executing arbitrary Ruby code. ,o this by invo7ing passenger-irb API,; where 0+4D1 is the PI, of the application process you wish to inspect. Note that the IRD console is currently only available for Ruby apps, not for apps in any other languages.

:. )ips
:.1. 1ser s!it hing >se urityA
here is a problem that plagues most P"P web hosts, namely the fact that all P"P applications are run in the same user context as the web server. %o for example, Foe>s P"P application will be able to read Fane>s P"P application>s passwords. his is obviously undesirable on many servers. Phusion Passenger solves this problem by implementing user s&itching. A Rails application is started as the owner of the file config/environment.rb, and a Rac7 application is started as the owner of the file config.ru. %o if /home/&ebapps/foo/config/environment.rb is owned by =oe, then Phusion Passenger will launch the corresponding Rails application as =oe as well.

+2

his behavior is the default, and you don>t need to configure anything. Dut there are things that you should 7eep in mind!

he owner of environment.rb?config.ru must have read access to the application>s root directory, and read?write access to the application>s logs directory. his feature is only available if Apache is started by root. his is the case on most Apache installations. .nder no circumstances will applications be run as root. If environment.rb?config.ru is owned as root or by an un7nown user, then the Rails?Rac7 application will run as the user specified by passenger@default@user and passenger@default@group.

.ser switching can be disabled with the passenger@user@switching option.

:.2. #edu ing memory onsumption of #uby on #ails appli ations by &&J
Is it possible to reduce memory consumption of your Rails applications by ))E on average, by using Ruby 3nterprise 3dition. Please visit the website for details. Note that this feature does not apply to Rac7 applications.

:.&. /apistrano re ipe


Phusion Passenger can be combined with $apistrano. he following $apistrano recipe demonstrates Phusion Passenger support. It assumes that you>re using (it as version control system.
set "applicationH 5myapp5 set "&omainH 5example.com5 set "repositoryH 5ssh"##DB&omainC#path-to-your-gitrepo#DBapplicationC.git5 set "use>su&oH %alse set "&eploy>toH 5#path-to-your-web-app-&irectory#DBapplicationC5 set "scmH 5git5 role "appH &omain role "webH &omain role "&bH &omainH "primary

6 true

namespace "&eploy &o tas* "startH "roles 6 "app &o run 5touch DBcurrent>releaseC#tmp#restart.txt5 en& tas* "stopH "roles D <o nothing. en& 6 "app &o

&esc 5+estart Application5 tas* "restartH "roles 6 "app &o

+4

run 5touch DBcurrent>releaseC#tmp#restart.txt5 en& en&

:.+. 7undler support


Phusion Passenger has automatic support for Dundler. It wor7s as follows!

If you have a .bundle/environment.rb in your application root, then Phusion Passenger will reCuire that file before loading your application. 0therwise, if you have a ;emfile, then Phusion Passenger will automatically call Dundler.setup:= before loading your application.

It>s possible that your application also calls Dundler.setup during loading, e.g. in config.ru or in config/boot.rb. his is the case with Rails ), and is also the case if you modified your config/boot.rb according to the Dundler Rails &.) instructions. his leads to Dundler.setup being called twice, once before the application startup file is reCuired and once during application startup. "owever this is harmless and doesn>t have any negative effects. Phusion Passenger assumes that you>re using Dundler ;< 8.5.+. If you don>t want Phusion Passenger to run its Dundler support code, e.g. because you need to use an older version of Dundler with an incompatible API or because you use a system other than Dundler, then you can override Phusion Passenger>s Dundler support code by creating a file config/setup%load%paths.rb. If this file exists then it will be reCuired before loading the application startup file. In this file you can do whatever you need to setup Dundler or a similar system.

:.,. Installing multiple #uby on #ails versions


3ach Ruby on Rails applications that are going to be deployed may reCuire a specific Ruby on Rails version. Kou can install a specific version with this command!
gem install rails -v /././

where -.-.- is the version number of Ruby on Rails. All of these versions will exist in parallel, and will not conflict with each other. Phusion Passenger will automatically ma7e use of the correct version.

:.-. 6a%ing the appli ation restart after ea h reGuest


In some situations it might be desirable to restart the web application after each reCuest, for example when developing a non-Rails application that doesn>t support code reloading, or when developing a web framewor7.

+5

o achieve this, simply create the file tmp/al&ays%restart.t!t in your application>s root folder. .nli7e restart.t!t, Phusion Passenger does not chec7 for this file>s timestamp! Phusion Passenger will always restart the application, as long as al&ays%restart.t!t exists. If you>re Iust developing a Rails application then you probably don>t need this feature. If you set /ails6nv development in your Apache configuration, then Rails will automatically reload your application code after each reCuest. al&ays%restart.t!t is only useful if you>re wor7ing on Ruby on Rails itself, or when you>re not developing a Rails application and your web framewor7 does not support code reloading.

:.8. *o! to fix bro%en imagesC/SSCKavaS ript 1#Is in sub$1#I deployments


%ome people experience bro7en images and other bro7en static assets when they deploy their application to a sub-.RI :i.e. http(//mysite.com/railsapp/=. he reason for this usually is that you used a static .RI for your image in the views. his means your img source probably refers to something li7e /images/foo.=pg. he leading slash means that it>s an absolute .RI! you>re telling the browser to always load http(//mysite.com/images/foo.=pg no matter what. he problem is that the image is actually at http(//mysite.com/railsapp/images/foo.=pg. here are two ways to fix this. he first way :not recommended= is to change your view templates to refer to images/foo.=pg. his is a relative .RI! note the lac7 of a leading slash=. 'hat this does is ma7ing the path relative to the current .RI. he problem is that if you use restful .RIs, then your images will probably brea7 again when you add a level to the .RI. /or example, when you>re at http(//mysite.com/railsapp the browser will loo7 for http(//mysite.com/railsapp/images/foo.=pg. Dut when you>re at http(//mysite.com/railsapp/controller. the browser will loo7 for http(//mysite.com/railsapp/controller/images/foo.=pg. %o relative .RIs usually don>t wor7 well with layout templates. he second and highly recommended way is to always use Rails helper methods to output tags for static assets. hese helper methods automatically ta7e care of prepending the base .RI that you>ve deployed the application to. /or images there is image@tag, for Fava%cript there is Iavascript@include@tag and for $%% there is stylesheet@lin7@tag. In the above example you would simply remove the 0img1 " 91 tag and replace it with inline Ruby li7e this!
EZ image>tag85%oo.Upg5: Z6

his will generate the proper image tag to PRAI1%@R00 ?public?images?foo.Ipg so that your images will always wor7 no matter what sub-.RI you>ve deployed to. hese helper methods are more valuable than you may thin7. /or example they also append a timestamp to the .RI to better facilitate " P caching. /or more information, please refer to the Rails API docs.

:.:. 3ut$of$7and Garbage Wor% and 3ut$of$7and Garbage /olle tion


-8

(vailable sin e Phusion Passenger +.=.=. (t this time, this feature is only available on #uby. he 0ut-of-Dand 'or7 feature allows you to run arbitrary long-running tas7s outside normal reCuest cycles. his wor7s by letting current reCuests to the process finish, then telling the process to perform the out-of-band wor7, then resuming passing reCuests to the process after said wor7 is finished. A specific :and perhaps primary= use case of of 0ut-of-Dand 'or7 is 3ut$of$7and Garbage /olle tion. he garbage collector is run outside normal reCuest cycles so that garbage collection runs inside normal reCuest cycles can finish a lot faster. his can potentially save tens to hundreds of milliseconds of latency in reCuests. Decause 0ut-of-Dand 'or7 is implemented at the Phusion Passenger inter-process reCuest routing level, and not by, say, spawning a thread inside the application process, 0ut-of-Dand 'or7 has the following useful properties!

It wor7s well even with tas7s that can pause all threads. he 9RI Ruby garbage collector is a stop-the-world mar7-and-sweep garbage collector. Phusion Passenger can spawn more processes as necessary, in order to prevent situations in which all application processes are busy performing out-of-band wor7. Phusion Passenger guarantees that there>s at least one process that>s ready to process reCuests.

Applications can use 0ut-of-Dand 'or7 as follows! #. ReCuest out-of-band wor7 by outputting the H-Passenger-ReCuest-00D-'or7 header during a reCuest. It does not matter what the value is. At this time, it is not possible to reCuest out-of-band wor7 from outside reCuests. &. Kou can actually perform out-of-band wor7 when you receive a !oob@wor7 Phusion Passenger event. Note that even though you can reCuest out-of-band wor7, there>s no guarantee that Phusion Passenger will send an oob@wor7 event in a timely manner, if at all. It is also possible that Phusion Passenger sends an oob@wor7 event without you ever having reCuested one. his latter could for example happen if the 00D wor7 is administrator-initiated. ,o not ma7e any assumptions in your code. "ere>s an example which implements out-of-band garbage collection using the 0ut-of-Dand framewor7!
# Somewhere in a controller method: # Tell Phusion Passenger we want to perform OOB work. response.hea&ersG5/-Passenger-+eJuest-MMK-Tor*5I 5true5 # Somewhere during application initialization: PhusionPassenger.on>event8"oob>wor*: do # Phusion Passenger has told us that we're ready to perform OOB work. t0 Time.now

-#

S2.start +ails.logger.in%o 5Mut-M%-Koun& S2 %inishe& in DBTime.now - t0C sec5 end

/or your convenience, Phusion Passenger provides a Rac7 middleware for out-of-band garbage collection. Add this to your config.ru!
require 4phusion>passenger#rac*#out>o%>ban&>gc4 # Trigger out of !and "# e$ery % re&uests. use PhusionPassenger""+ac*""MutM%Kan&ScH =

References!

he Phusion Dlog article which first introduced this feature.

;. 1nder the hood


Phusion Passenger hides a lot of complexity for the end user :i.e. the web server system administrator=, but sometimes it is desirable to 7now what is going on. his section describes a few things that Phusion Passenger does under the hood.

;.1. Page a hing support


/or each " P reCuest, Phusion Passenger will automatically loo7 for a corresponding page cache file, and serve that if it exists. It does this by appending V.htmlV to the filename that the .RI normally maps to, and chec7ing whether that file exists. his chec7 occurs after chec7ing whether the original mapped filename exists :as part of static asset serving=. All this is done without the need for special mod@rewrite rules. /or example, suppose that the browser reCuests /foo/bar. #. Phusion Passenger will first chec7 whether this .RI maps to a static file, i.e. whether the file foo/bar exists in the web application>s public directory. If it does then Phusion Passenger will serve this file through Apache immediately. &. If that doesn>t exist, then Phusion Passenger will chec7 whether the file foo/bar.html exists. If it does then Phusion Passenger will serve this file through Apache immediately. ). If foo/bar.html doesn>t exist either, then Phusion Passenger will forward the reCuest to the underlying web application. Note that Phusion Passenger>s page caching support doesn>t wor7 if your web application uses a non-standard page cache directory, i.e. if it doesn>t cache to the public directory. In that case you>ll need to use mod@rewrite to serve such page cache files.

-&

;.2. *o! Phusion Passenger dete ts !hether a virtual host is a !eb appli ation
After you>ve read the deployment instructions you might wonder how Phusion Passenger 7nows that the server root points to a web application that Phusion Passenger is able to serve, and how it 7nows what 7ind of web application it is :e.g. Rails or Rac7=. Phusion Passenger chec7s whether the virtual host is a Rails application by chec7ing whether the following file exists!
&irname8<ocument+oot: ' 5#con%ig#environment.rb5

If you>re not a programmer and don>t understand the above pseudo-code snippet, it means that Phusion Passenger will! #. 3xtract the parent directory filename from the value of the TrootU directive. &. Append the text V?config?environment.rbV to the result, and chec7 whether the resulting filename exists. %o suppose that your server root is /&ebapps/foo/public. Phusion Passenger will chec7 whether the file /&ebapps/foo/config/environment.rb exists. Note that Phusion Passenger for Nginx does not resolve any symlin7s in the root path. %o for example, suppose that your root points to /home/&&&/e!ample.com, which in turn is a symlin7 to /&ebapps/e!ample.com/public. Phusion Passenger for Nginx will chec7 for /home/&&&/config/environment.rb, not /&ebapps/e!ample.com/config/environment.rb. his file of course doesn>t exist, and as a result Phusion Passenger will not activate itself for this virtual host, and you>ll most li7ely see some output generated by the Nginx default directory handler such as a /orbidden error message. ,etection of Rac7 applications happens through the same mechanism, exception that Phusion Passenger will loo7 for config.ru instead of config/environment.rb.

1=. (ppendix (" (bout this do ument


he text of this document is licensed under the $reative $ommons Attribution-%hare Ali7e ).8 .nported 1icense.

Phusion Passenger is brought to you by Phusion.

-)

Phusion Passenger is a trademar7 of "ongli 1ai [ Ninh Dui.

11. (ppendix 7" )erminology


11.1. (ppli ation root
he root directory of an application that>s served by Phusion Passenger. In case of Ruby on Rails applications, this is the directory that contains /a'efile, app/, config/, public/, etc. In other words, the directory pointed to by RAI1%@R00 . /or example, ta7e the following directory structure!
#apps#%oo# E------ This is the +ails application4s application rootQ F '- app# F F F '- controllers# F F F '- mo&els# F F F '- views# F '- con%ig# F F F '- environment.rb F F F '- ... F '- public# F F F '- ... F '- ...

In case of Rac7 applications, this is the directory that contains config.ru. /or example, ta7e the following directory structure!
#apps#bar# F '- public# F F E----- This is the +ac* application4s application rootQ

-*

F '- ... F '- con%ig.ru F '- ...

In case of Python :'%(I= applications, this is the directory that contains passenger%&sgi.py. /or example, ta7e the following directory structure!
#apps#ba0# E----- This is the T7S. application4s application rootQ F '- public# F F F '- ... F '- passenger>wsgi.py F '- ...

11.2. Idle pro ess


An Vidle processV refers to a process that hasn>t processed any reCuests for a while.

11.&. Ina tive pro ess


An Vinactive processV refers to a process that>s current not processing any reCuests. An idle process is always inactive, but an inactive process is not always considered idle.

12. (ppendix /" Spa!ning methods explained


At its core, Phusion Passenger is an " P proxy and process manager. It spawns Ruby on Rails?Rac7?'%(I wor7er processes :which may also be referred to as bac'end processes=, and forwards incoming " P reCuest to one of the wor7er processes. 'hile this may sound simple, there>s not Iust one way to spawn wor7er processes. 1et>s go over the different spawning methods. /or simplicity>s sa7e, let>s assume that we>re only tal7ing about Ruby on Rails applications.

12.1. )he most straightfor!ard and traditional !ay" dire t spa!ning


Phusion Passenger could create a new Ruby process, which will then load the Rails application along with the entire Rails framewor7. his process will then enter an reCuest handling main loop.

-+

his is the most straightforward way to spawn wor7er processes. If you>re familiar with the 9ongrel application server, then this approach is exactly what mongrel@cluster performs! it creates N wor7er processes, each which loads a full copy of the Rails application and the Rails framewor7 in memory. he hin application server employs pretty much the same approach. Note that Phusion Passenger>s version of direct spawning differs slightly from mongrel@cluster. 9ongrel@cluster creates entirely new Ruby processes. In programmers Iargon, mongrel@cluster creates new Ruby processes by for7ing the current process and exec:=-ing a new Ruby interpreter. Phusion Passenger on the other hand creates processes that reuse the already loaded Ruby interpreter. In programmers Iargon, Phusion Passenger calls for7:=, but not exec:=.

12.2. )he smart spa!ning method


%mart spawning is supported for all Ruby applications but not for '%(I applications. 'hile direct spawning wor7s well, it>s not as efficient as it could be because each wor7er process has its own private copy of the Rails application as well as the Rails framewor7. his wastes memory as well as startup time.

3igure( Eor'er processes and direct spa&ning. 6ach &or'er process has its o&n private copy of the application code and /ails frame&or' code. It is possible to ma7e the different wor7er processes share the memory occupied by application and Rails framewor7 code, by utili6ing so-called copy-on-write semantics of the virtual memory system on modern operating systems. As a side effect, the startup time is also reduced. his is techniCue is exploited by Phusion Passenger>s smart spawn method.

12.2.1. *o! it !or%s 'hen the smart spawn method is being used, Phusion Passenger will first create a so-called .pplicationSpa&ner server process. his process loads the entire Rails application along with the Rails framewor7, by loading environment.rb. hen, whenever Phusion Passenger needs a new wor7er process, it will instruct the Application%pawner server to do so. he Application%pawner server will create a wor7er new process that reuses the already loaded Rails application?framewor7. $reating a wor7er process through an already running Application%pawner server is very fast, about #8 times faster than loading the Rails application?framewor7 from scratch. If the Ruby interpreter is copy-on-write friendly :that is, if you>re running Ruby 3nterprise 3dition= then all created wor7er processes will share as much common memory as possible. hat is, they will all share the same application and Rails framewor7 code.

--

3igure( Eor'er processes and the smart spa&n method. .ll &or'er processesF as &ell as the .pplicationSpa&nerF share the same application code and /ails frame&or' code. he smart method allows different wor7er processes that belong to the same application to share memory. Notes!

Nendored Rails framewor7s cannot be shared by different applications, even if both vendored Rails framewor7s are the same version. %o for efficiency reasons we don>t recommend vendoring Rails. Application%pawner servers have an idle timeout Iust li7e wor7er processes. If an Application%pawner?/ramewor7%pawner server hasn>t been instructed to do anything for a while, it will be shutdown in order to conserve memory. his idle timeout is configurable.

12.2.2. Summary of benefits %uppose that Phusion Passenger needs a new wor7er process for an application that uses Rails &.&.#. If the smart spawning method is used, and an Application%pawner server for this application is already running, then wor7er process creation time is about #8 times faster than direct spawning. his wor7er process will also share application and Rails framewor7 code memory with the Application%pawner server and the wor7er processes that had been spawned by this Application%pawner server. In practice, the smart spawning method could mean a memory saving of about ))E, assuming that your Ruby interpreter is copy-on-write friendly. 0f course, smart spawning is not without gotchas. Dut if you understand the gotchas you can easily reap the benefits of smart spawning.

12.&. Smart spa!ning got ha L1" unintentional file des riptor sharing
Decause wor7er processes are created by for7ing from an Application%pawner server, it will share all file descriptors that are opened by the Application%pawner server. : his is part of the semantics of the .nix for'GH system call. Kou might want to (oogle it if you>re not familiar with it.= A file descriptor is a handle which can be an opened file, an opened soc7et connection, a pipe, etc. If different wor7er processes write to such a file descriptor at the same time, then their write calls will be interleaved, which may potentially cause problems. he problem commonly involves soc7et connections that are unintentionally being shared. Kou can fix it by closing and reestablishing the connection when Phusion Passenger is -2

creating a new wor7er process. Phusion Passenger provides the API call PhusionPassenger.on@event:!starting@wor7er@process= to do so. %o you could insert the following code in your environment.rb!
if defined[8PhusionPassenger: PhusionPassenger.on>event8"starting>wor*er>process: do F%or*e&F if %or*e& # 'e're in smart spawning mode. ... co&e to reestablish soc*et connections here ... else # 'e're in direct spawning mode. 'e don't need to do anything. end end end

Note that Phusion Passenger automatically reestablishes the connection to the database upon creating a new wor7er process, which is why you normally do not encounter any database issues when using smart spawning mode.

12.&.1. 9xample 1" 6em a hed onne tion sharing >harmfulA %uppose we have a Rails application that connects to a 9emcached server in environment.rb. his causes the Application%pawner to have a soc7et connection :file descriptor= to the 9emcached server, as shown in the following figure!
'--------------------' F Application7pawner F-----------GPemcache& serverI '--------------------'

Phusion Passenger then proceeds with creating a new Rails wor7er process, which is to process incoming " P reCuests. he result will loo7 li7e this!
'--------------------' F Application7pawner F------'----GPemcache& serverI '--------------------' F F '--------------------' F F Tor*er process 1 F-----# '--------------------'

%ince a for'GH ma7es a :virtual= complete copy of a process, all its file descriptors will be copied as well. 'hat we see here is that Application%pawner and 'or7er process # both share the same connection to 9emcached. Now supposed that your site gets %lashdotted and Phusion Passenger needs to spawn another wor7er process. It does so by for7ing Application%pawner. he result is now as follows!
'--------------------' F Application7pawner F------'----GPemcache& serverI '--------------------' F F '--------------------' F F Tor*er process 1 F-----#F

-4

'--------------------' '--------------------' F Tor*er process ) F-----# '--------------------'

F F F

As you can see, 'or7er process # and 'or7er process & have the same 9emcached connection. %uppose that users Foe and Fane visit your website at the same time. Foe>s reCuest is handled by 'or7er process #, and Fane>s reCuest is handled by 'or7er process &. Doth wor7er processes want to fetch something from 9emcached. %uppose that in order to do that, both handlers need to send a V/3 $"V command to 9emcached. Dut suppose that, after wor7er process # having only sent V/3V, a context switch occurs, and wor7er process & starts sending a V/3 $"V command to 9emcached as well. If wor7er process & succeeds in sending only one bye, 3, then 9emcached will receive a command which begins with V/3/V, a command that it does not recogni6e. In other words! the data from both handlers get interleaved. And thus 9emcached is forced to handle this as an error. his problem can be solved by reestablishing the connection to 9emcached after for7ing!
'--------------------' F Application7pawner F------'----GPemcache& serverI '--------------------' F F F F '--------------------' F F F Tor*er process 1 F-----#F F '--------------------' F F E--- create& this / F new F connection / E-- close& this F '--------------------' F ol& F F Tor*er process ) F-----# connection F '--------------------' F F F '-------------------------------------'

'or7er process & now has its own, separate communication channel with 9emcached. he code in environment.rb loo7s li7e this!
if defined[8PhusionPassenger: PhusionPassenger.on>event8"starting>wor*er>process: do F%or*e&F if %or*e& # 'e're in smart spawning mode. reestablish>connection>to>memcache& else # 'e're in direct spawning mode. 'e don't need to do anything. end end end

12.&.2. 9xample 2" 4og file sharing >not harmfulA

-5

here are also cases in which unintentional file descriptor sharing is not harmful. 0ne such case is log file file descriptor sharing. 3ven if two processes write to the log file at the same time, the worst thing that can happen is that the data in the log file is interleaved. o guarantee that the data written to the log file is never interleaved, you must synchroni6e write access via an inter-process synchroni6ation mechanism, such as file loc7s. Reopening the log file, li7e you would have done in the 9emcached example, doesn>t help.

12.+. Smart spa!ning got ha L2" the need to revive threads


Another part of the for'GH system call>s semantics is the fact that threads disappear after a for7 call. %o if you>ve created any threads in environment.rb, then those threads will no longer be running in newly created wor7er process. Kou need to revive them when a new wor7er process is created. .se the !starting@wor7er@process event that Phusion Passenger provides, li7e this!
if defined[8PhusionPassenger: PhusionPassenger.on>event8"starting>wor*er>process: do F%or*e&F if %or*e& # 'e're in smart spawning mode. ... co&e to revive threa&s here ... else # 'e're in direct spawning mode. 'e don't need to do anything. end end end

12.,. Smart spa!ning got ha L&" ode load order


his gotcha is only applicable to the smart spawn method, not the smart-lv spawn method. If your application expects the Rails framewor7 to be not loaded during the beginning of environment.rb, then it can cause problems when an Application%pawner is created from a /ramewor7%pawner, which already has the Rails framewor7 loaded. he most common case is when applications try to patch Rails by dropping a modified file that has the same name as Rails>s own file, in a path that comes earlier in the Ruby search path. /or example, suppose that we have an application which has a patched version of active%record/base.rb located in /.45S%/OO*/lib/patches, and /.45S%/OO*/lib/patches comes first in the Ruby load path. 'hen conservative spawning is used, the patched version of base.rb is properly loaded. 'hen smart :not smart-lv = spawning is used, the original base.rb is used because it was already loaded, so a subseCuent reCuire Vactive@record?baseV has no effect. 1ast updated &8#)-8)-8) ##!#*!++ $3

28