Common Passenger Config - abletech/easy-deployment GitHub Wiki
Common Apache uses with rails/passenger applications
NOTE: Many of these features require one or more apache modules, which means you cannot use PassengerHighPerformance on
(which disables all other apache modules) at the same time.
easy-deployment contains a template for the most common used setup at https://github.com/AbleTech/easy-deployment/blob/master/lib/easy/generators/templates/stage/apache.conf.tt
Here is a basic example:
<VirtualHost *:80>
ServerName www.example.com
DocumentRoot /var/apps/APPLICATION/current/public
RackEnv production
# Passenger tuning
# at least 1 prevents passenger going to sleep after 15min inactivity, increase as desired
PassengerMinInstances 1
# Pre-load app on deploy. This needs to match the ServerName above
# PassengerPreStart http://www.example.com
# If you don't need any apache mods within this VirtualHost, you may turn this on
# PassengerHighPerformance on
<Directory /var/apps/APPLICATION/current/public>
AllowOverride all
Options -MultiViews
</Directory>
</VirtualHost>
This requires the apache module mod_rewrite
to be enabled (which it is by default on most platforms). In order to enforce presence of the www
subdomain, place the following config within your VirtualHost entry:
ServerName www.example.com
ServerAlias example.com
# Rewrite requests with no subdomain to www.
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule ^(.*)$ http://www.example.com$1 [R=301,L]
This requires the apache module mod_expires
to be enabled. Place the following config within your VirtualHost entry:
<Location /assets/>
# Use of ETag is discouraged when Last-Modified is present
Header unset ETag
FileETag None
# RFC says only cache for 1 year
ExpiresActive On
ExpiresDefault "access plus 1 year"
</Location>
If you are running a site which requires SSL (for example if someone logs-in to your site), it is recommended to simply enforce all pages to be served via HTTPS. The cpu overhead is minimal (despite what historic wisdom may tell you). This requires the apache modules mod_ssl
and mod_rewrite
.
Benefits to serving all traffic off HTTPS:
- reduces the need for application logic to enforce SSL in certain areas of the application
- prevents cookies being stolen by methods such as employed by firesheep when your users later browse via HTTP
- ensures the page serving a login form is served off HTTPS and hence the form target cannot be modified en-route.
For more information about generating SSL keys and certificates, read more at:
Example configuration:
# Redirect HTTP users to HTTPS
<VirtualHost *:80>
ServerName www.example.com
RewriteEngine On
Redirect permanent / https://secure.example.com/
</VirtualHost>
# Serve site off HTTPS
<VirtualHost *:443>
ServerName secure.example.com
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLCertificateFile /etc/ssl/private/secure.example.com.crt
SSLCertificateKeyFile /etc/ssl/private/secure.example.com.key
# SSLCertificateChainFile /etc/ssl/private/intermediate.crt
DocumentRoot /var/apps/APPLICATION/current/public
RackEnv production
# Passenger tuning
# at least 1 prevents passenger going to sleep after 15min inactivity, increase as desired
PassengerMinInstances 1
# Pre-load app on deploy. This needs to match the ServerName above
# PassengerPreStart https://secure.example.com:443/
# We need apache modules in here.
PassengerHighPerformance off
<Directory /var/apps/<%= application_name %>/current/public>
AllowOverride all
Options -MultiViews
</Directory>
</VirtualHost>
If you want to serve both http and https traffic, you could have two near identical blocks both with passenger configured, but then you'd have two application instances managed separately, wasting resources. Here is an alternate solution which employs having the dynamic passenger application running on HTTP (port 80), and VirtualHost running HTTPS (port 443) which instead of loading another passenger instance, instead handles SSL, and then passes plain HTTP request to the other local HTTP instance running passenger.
This requires both mod_ssl
for SSL encryption, mod_headers
to ensure the HTTP site knows that the original request was encrypted and mod_proxy
to proxy requests from HTTPS to the HTTP instance. This example also assumes that this is the only site running under this apache instance.
# Run the application under HTTP
<VirtualHost *:80>
ServerName www.example.com
DocumentRoot /var/apps/APPLICATION/current/public
PassengerEnabled on
RackEnv production
PassengerMinInstances 1
PassengerPreStart http://www.example.com/
PassengerHighPerformance on
<Directory /var/apps/APPLICATION/current/public>
Options -MultiViews
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
# Provide an HTTPS entry point as well
<VirtualHost *:443>
ServerName www.example.com
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLCertificateFile /etc/ssl/private/www.example.com.crt
SSLCertificateKeyFile /etc/ssl/private/www.example.com.key
# SSLCertificateChainFile /etc/ssl/private/intermediate.crt
RequestHeader set X_FORWARDED_PROTO 'https'
DocumentRoot /var/apps/APPLICATION/current/public
# This is just passing a proxy to a localhost server
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost/
ProxyPassReverse / http://localhost/
</VirtualHost>