Passenger and nginx Maintenance Page
I recently had the pleasure of moving a Rails app from Apache/Passenger based system to an nginx/Passenger system, deployed by Capistrano. In Apache, I had a setup where I could take a production site down for maintenance by touching tmp/stop.txt
and using the following directive in my VirtualHost (courtesy of Otto Hilska at Nodeta):
<VirtualHost *:80>
ServerName www.example.com
DocumentRoot /u/apps/example/current/public
ErrorDocument 503 /maintenance.html
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}/../tmp/stop.txt -f
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^(.*)$ /$1 [R=503,L]
<Directory /u/apps/example/current/public>
RailsEnv production
Options -MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
</VirtualHost>
This worked perfectly, and allowed me to use images/css/etc on my error documents without them being redirected to 503s as well. Based on Eli Miller’s solution, I was able to write something similar for my nginx server config:
server {
listen 80;
server_name www.example.com;
error_page 503 /maintenance.html;
root /u/apps/example/current/public;
passenger_enabled on;
rails_env production;
# If the maintenance stop file exists
if (-f $document_root/../tmp/stop.txt) {
set $maintenance 1;
}
# If the request exists as a static file in public
if (-f $document_root/$uri) {
set $maintenance 0;
}
if ($maintenance) {
return 503;
}
}
I was able to test this successfully with nginx 0.7.67 and 0.8.53, and Passenger 2.2.15 and 3.0.1. If you know a better/clearer way to do this, please share!