Académique Documents
Professionnel Documents
Culture Documents
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.
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.
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! -
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.
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
,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
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.
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
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
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
#&
Step 2" 1se 516 /rom there you can use K.9 to install pac7ages. /or example, try one of these!
#)
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.;.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.
#-
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?
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
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.
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
&. 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.
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 ...
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
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
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.
&#
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.
%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.
! 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/.
&)
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 ...
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
&*
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
+.,.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.
+.,.&. 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
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.
&-
,.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
/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
... server B listen $0? server>name www.wsgiapp.com? root #webapps#wsgiapp#public? passenger>enable& on? C ... C
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.
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.
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.
)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.
)#
#. %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.
In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.
)&
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.
))
export PA77,NS,+>TPP<.+ #my>temp-&ir su&o -, passenger-status D The -, option tells 4su&o4 to preserve environment variables.
-.;.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=.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.
-.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&?
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.)?
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
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
'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.
-.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.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.
-.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.
-.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.
)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
In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.
-.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.
*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
'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.
-.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. **
In the http configuration bloc7. In a server configuration bloc7. In a location configuration bloc7. In an if configuration scope.
-.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.
-.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 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
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 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
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
-.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! +#
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.
-.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.
-.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.
+)
(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
-* -* -* -* -*
--------- 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.
@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.
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))#
:. )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.
:.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.
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
+4
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.
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.
+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.
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.
(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
-#
/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!
-&
;.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.
-)
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
-*
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 '- ...
-+
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:=.
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 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
-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.
28