[[user_switching]]
=== User switching (security) ===

There is a problem that plagues most PHP web hosts, namely the fact that all PHP
applications are run in the same user context as the web server. So for
example, Joe's PHP application will be able to read Jane's PHP application's
passwords. This is obviously undesirable on many servers.

Phusion Passenger solves this problem by implementing 'user switching'. A Rails
application is started as the owner of the file 'config/environment.rb',
and a Rack application is started as the owner of the file 'config.ru'.
So if '/home/webapps/foo/config/environment.rb' is owned by 'joe', then Phusion
Passenger will launch the corresponding application as 'joe' as well.

This behavior is the default, and you don't need to configure anything. But
there are things that you should keep in mind:

- The 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.
- This feature is only available if the web server is started by 'root'. This is the
  case on most installations.
- Under no circumstances will applications be run as 'root'. If
  'environment.rb'/'config.ru' is owned as root or by an unknown user, then the
  Rails/Rack application will run as the user specified by
ifdef::apache[]
  <<PassengerDefaultUser,PassengerDefaultUser>> and
  <<PassengerDefaultGroup,PassengerDefaultGroup>>.
endif::[]
ifdef::nginx[]
  <<PassengerDefaultUser,passenger_default_user>> and
  <<PassengerDefaultGroup,passenger_default_group>>.
endif::[]

User switching can be disabled with the
ifdef::apache[<<PassengerUserSwitching,PassengerUserSwitching>>]
ifdef::nginx[<<PassengerUserSwitching,passenger_user_switching>>]
option.


[[reducing_memory_usage]]
=== Reducing memory consumption of Ruby on Rails applications by 33% ===

Is it possible to reduce memory consumption of your Rails applications by 33% on average,
by using http://www.rubyenterpriseedition.com/[Ruby Enterprise Edition].
Please visit the website for details.

Note that this feature does not apply to Rack applications.

[[capistrano]]
=== Capistrano recipe ===

Phusion Passenger can be combined with link:http://capify.org/[Capistrano].
The following Capistrano recipe demonstrates Phusion Passenger support.
It assumes that you're using Git as version control system.

--------------------------------------------------
set :application, "myapp"
set :domain,      "example.com"
set :repository,  "ssh://#{domain}/path-to-your-git-repo/#{application}.git"
set :use_sudo,    false
set :deploy_to,   "/path-to-your-web-app-directory/#{application}"
set :scm,         "git"

role :app, domain
role :web, domain
role :db,  domain, :primary => true

namespace :deploy do
  task :start, :roles => :app do
    run "touch #{current_release}/tmp/restart.txt"
  end
  
  task :stop, :roles => :app do
    # Do nothing.
  end
  
  desc "Restart Application"
  task :restart, :roles => :app do
    run "touch #{current_release}/tmp/restart.txt"
  end
end
--------------------------------------------------


[[bundler_support]]
=== Bundler support ===

Phusion Passenger has automatic support for link:http://gembundler.com/git.html[Bundler].
It works as follows:

- If you have a '.bundle/environment.rb' in your application root, then Phusion
  Passenger will require that file before loading your application.
- Otherwise, if you have a 'Gemfile', then Phusion Passenger will automatically call
  `Bundler.setup()` before loading your application.

It's possible that your application also calls `Bundler.setup` during loading, e.g. in
'config.ru' or in 'config/boot.rb'. This is the case with Rails 3, and is also the case if you
modified your 'config/boot.rb' according to the
link:http://gembundler.com/rails23.html[Bundler Rails 2.3 instructions].
This leads to `Bundler.setup` being called twice, once before the application startup file
is required and once during application startup. However this is harmless and doesn't
have any negative effects.

Phusion Passenger assumes that you're using Bundler >= 0.9.5. If you don't want Phusion
Passenger to run its Bundler support code, e.g. because you need to use an older version
of Bundler with an incompatible API or because you use a system other than Bundler, then
you can override Phusion Passenger's Bundler support code by creating a file
'config/setup_load_paths.rb'. If this file exists then it will be required before loading
the application startup file. In this file you can do whatever you need to setup Bundler
or a similar system.

=== Installing multiple Ruby on Rails versions ===

Each Ruby on Rails applications that are going to be deployed may require a
specific Ruby on Rails version. You can install a specific version with
this command:
-----------------------------
gem install rails -v X.X.X
-----------------------------
where 'X.X.X' 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 make use of the correct version.

=== Making the application restart after each request ===

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

To achieve this, simply create the file 'tmp/always_restart.txt' in your
application's root folder. Unlike 'restart.txt', Phusion Passenger does not
check for this file's timestamp: Phusion Passenger will always restart the
application, as long as 'always_restart.txt' exists.

NOTE: If you're just developing a Rails application then you probably don't need
this feature. If you set
ifdef::apache['RailsEnv development']
ifdef::nginx['rails_env development']
in your web server configuration,
then Rails will automatically reload your application code after each request.
'always_restart.txt' is mostly useful when you're using a web framework that
doesn't support code reloading by itself, of when you're working on a web framework
yourself.

[[sub_uri_deployment_uri_fix]]
=== How to fix broken images/CSS/JavaScript URIs in sub-URI deployments

Some people experience broken images and other broken static assets when they
deploy their application to a sub-URI (i.e. 'http://mysite.com/railsapp/').
The reason for this usually is that you used a
static URI for your image in the views. This means your 'img' source probably refers
to something like '/images/foo.jpg'. The leading slash means that it's an absolute URI:
you're telling the browser to always load 'http://mysite.com/images/foo.jpg' no
matter what. The problem is that the image is actually at
'http://mysite.com/railsapp/images/foo.jpg'. There are two ways to fix this.

The first way (not recommended) is to change your view templates to refer to
'images/foo.jpg'. This is a relative URI: note the lack of a leading slash). What
this does is making the path relative to the current URI. The problem is that if you
use restful URIs, then your images will probably break again when you add a level to
the URI.
For example, when you're at 'http://mysite.com/railsapp' the browser will look for
'http://mysite.com/railsapp/images/foo.jpg'. But when you're at
'http://mysite.com/railsapp/controller'. the browser will look for
'http://mysite.com/railsapp/controller/images/foo.jpg'.
So relative URIs usually don't work well with layout templates.

The second and highly recommended way is to always use Rails helper methods to
output tags for static assets. These helper methods automatically take care
of prepending the base URI that you've deployed the application to. For images
there is `image_tag`, for JavaScript there is `javascript_include_tag` and for
CSS there is `stylesheet_link_tag`. In the above example you would simply remove
the '<img>' HTML tag and replace it with inline Ruby like this:

---------------------------------------
<%= image_tag("foo.jpg") %>
---------------------------------------

This will generate the proper image tag to `$RAILS_ROOT/public/images/foo.jpg`
so that your images will always work no matter what sub-URI you've deployed to.

These helper methods are more valuable than you may think. For example they also
append a timestamp to the URI to better facilitate HTTP caching. For more information,
please refer to
link:http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html[the Rails API docs].

=== Out-of-Band Garbage Work and Out-of-Band Garbage Collection

**Available since Phusion Passenger 4.0.0.**

**At this time, this feature is only available on Ruby.**

The Out-of-Band Work feature allows you to run arbitrary long-running tasks outside normal request cycles. This works by letting current requests to the process finish, then telling the process to perform the out-of-band work, then resuming passing requests to the process after said work is finished.

A specific (and perhaps primary) use case of of Out-of-Band Work is *Out-of-Band Garbage Collection*. The garbage collector is run outside normal request cycles so that garbage collection runs inside normal request cycles can finish a lot faster. This can potentially save tens to hundreds of milliseconds of latency in requests.

Because Out-of-Band Work is implemented at the Phusion Passenger inter-process request routing level, and not by, say, spawning a thread inside the application process, Out-of-Band Work has the following useful properties:

- It works well even with tasks that can pause all threads. The MRI Ruby garbage collector is a stop-the-world mark-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 work. Phusion Passenger guarantees that there's at least one process that's ready to process requests.

Applications can use Out-of-Band Work as follows:

1. Request out-of-band work by outputting the `X-Passenger-Request-OOB-Work` header during a request. It does not matter what the value is. At this time, it is not possible to request out-of-band work from outside requests.
2. You can actually perform out-of-band work when you receive a `:oob_work` Phusion Passenger event.

Note that even though you can request out-of-band work, there's no guarantee that Phusion Passenger will send an `oob_work` event in a timely manner, if at all. It is also possible that Phusion Passenger sends an `oob_work` event without you ever having requested one. This latter could for example happen if the OOB work is administrator-initiated. Do not make any assumptions in your code.

Here's an example which implements out-of-band garbage collection using the Out-of-Band framework:

[source, ruby]
-------------------------------------------------
# Somewhere in a controller method:
# Tell Phusion Passenger we want to perform OOB work.
response.headers["X-Passenger-Request-OOB-Work"] = "true"

# Somewhere during application initialization:
PhusionPassenger.on_event(:oob_work) do
  # Phusion Passenger has told us that we're ready to perform OOB work.
  t0 = Time.now
  GC.start
  Rails.logger.info "Out-Of-Bound GC finished in #{Time.now - t0} sec"
end
-------------------------------------------------

For your convenience, Phusion Passenger provides a Rack middleware for out-of-band garbage collection. Add this to your `config.ru`:

[source, ruby]
----------------------------------------------------
require 'phusion_passenger/rack/out_of_band_gc'

# Trigger out-of-band GC every 5 requests.
use PhusionPassenger::Rack::OutOfBandGc, 5
----------------------------------------------------

References:

- link:http://blog.phusion.nl/2013/01/22/phusion-passenger-4-technology-preview-out-of-band-work/[The Phusion Blog article which first introduced this feature.]