With some simple .htaccess (or vhost) settings you can redirect all requests to a specified maintenance file /(maintenance.html in this example) by simply uploading a file named “maintenance” into your document root. Afte maintaining your site, you can delete the file “maintenance” and all request will work as before:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
ErrorDocument 503 /maintenance.html
# Check for maintenance file and redirect all requests
# If your Deployment is finished, delete it
RewriteCond %{DOCUMENT_ROOT}/write/maintenance -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteCond %{SCRIPT_FILENAME} !maintenance.php
RewriteCond %{REQUEST_FILENAME} !.css$
RewriteCond %{REQUEST_FILENAME} !.png$
RewriteCond %{REQUEST_FILENAME} !.jpg$
RewriteCond %{REQUEST_FILENAME} !.gif$
RewriteRule ^.*$ / [R=503,L]
With a simple PHP Script (this is just a basic example with room left for optimization) you can automate the creation/deletion of the file “write/maintenance”. Of course, this file should be at least password or ip protected:
< ?php
$maintenanceActivationFile = $_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.'write'.DIRECTORY_SEPARATOR.'maintenance';
if (file_exists($maintenanceActivationFile)) {
if ($_REQUEST['action'] === 'stop') {
unlink($maintenanceActivationFile);
echo 'Maintenance mode stopped';
} else {
echo '<a href="'.$_SERVER['PHP_SELF'].'?action=stop">Stop maintenance mode';
}
} else {
if ($_REQUEST['action'] === 'start') {
$handle = fopen ($maintenanceActivationFile, 'w');
fclose($handle);
echo 'Maintenance mode started';
} else {
echo '<a href="'.$_SERVER['PHP_SELF'].'?action=start">Start maintenance mode</a>';
}
}
?>
You can test this here:
When maintenance mode is enabled, http://demo-maintenance.jonasfischer.net/* will show “maintenance.html”. When maintenance mode is not enabled http://demo-maintenance.jonasfischer.net/ will show “index.html”.
Symfony integration
Instead of using a php script I created a symfony task that creates and deploys or deletes the file “maintenance” so I can automatically couple this step with my existing deployment tasks.
You could also adjust your rewrite rule to listen to the symfony *.lck files managed by the standard symfony enable/disbale tasks:
$ symfony project:disable APPLICATION_NAME ENVIRONMENT_NAME
$ symfony project:enable APPLICATION_NAME ENVIRONMENT_NAME
These tasks create/delete files using the following naming schema:
sfConfig::get('sf_data_dir').'/'.$app.'_'.$env.'.lck'
However, unless you have shell access to your production servers you still have to deploy the files to your webfarm.
The benefit of using the rewrite rule over using symfony’s built in disable mechanism is tha you can disable all your php scripts/html files, not only those dispatched through your sfFrontWebContoller.