One of the things that smaller sites who don't have a fully redundant setup or a relatively minimal deployment mechanism need to do when doing some kind of maintenance is put up an "Under Maintenance" page. That or there was some massive problem and you need to just shut down access to the site while you fix the problem. With that in mind I have written a very simple example that allows you to create a maintenance page that is configurable and requires no changes to your existing site. This example uses Zend_Application, but all of the code can be used in a pure Zend_Controller application by adding the plugin however you normally add plugins.
First let's set up a maintenance controller.
MaintenanceController.php
class MaintenanceController extends Zend_Controller_Action
{
public function indexAction(){}
}
and a view.
scripts/maintenance/index.phtml
<h1> We are currently under maintenance</h1>
<h2> Please check back soon</h2>
Now the fun part. Create a simple plugin that is called during routeShutdown() and redirect all requests to the maintenance page.
class Esc_Application_Plugin_Maintenance extends Zend_Controller_Plugin_Abstract
{
public function routeShutdown(Zend_Controller_Request_Abstract $request)
{
$request->setActionName('index');
$request->setModuleName('default');
$request->setControllerName('maintenance');
}
}
One of the nice things about this method is that if you have any parts of your application that you want to keep open you can implement the code to handle that in here.
The last thing you need to do is add this plugin to your application configuration. If you are using Zend_Config_Ini you can simply do this:
resources.frontController.plugins[] = "Esc_Application_Plugin_Maintenance"
Whenever you need to put your site into maintenance mode all you need to do is add that line and it will be done as soon as you save the file.
Comments
Krzysztof Kotlarski
Wouldn’t it be better to redirect all requests in htaccess file?
Kevin Schroeder
I almost always discourage using an .htaccess file in a production environment for performance and security reasons. Also, an .htaccess file cannot be programmed with the same level of precision as a ZF controller plugin.
PHP Gangsta
The big problem with this solution: If you deploy a new version of your website, you perhaps delete all files and put up new files. Or you manually exchange 5 files, which lasts 2 minutes. During this the website will fail.
I also think the best is a simple htaccess entry, or even better configure the maintenance response on the reverse proxy, so you are able to shutdown the whole apache if needed.
Kevin Schroeder
This method would not be used for a deployment. Deployments are most easily done by deploying your code to a directory on the live server and then changing the document root to the new directory with a HUP on the Apache process once the deployment has been done. This way there is no downtime and if you need to roll back your changes you simple change the document root back to the old one and re-HUP Apache. Never, ever, make changes to production code, even if it is to fix something. (though I do break this rule, but only because my site doesn’t generate revenue for me and doesn’t have a ton of traffic).
If you were to use this in a deployment you could make the change to the config file and then when you deploy the new code and reset the document root or application dir then the old configuration would no longer be used anyway.
And even so, the performance, security and customize-ability issues of .htaccess files in production still stand.
Kevin Schroeder
To clarify what I meant on deployment. Some people will use an “under maintenance” page when deploying code, which is why I put it there as an example. Since I loath downtime I don’t recommend that. Actually, my deployment mechanism is
mv eschrade eschrade.old && mv r.eschrade eschrade
🙂
Ladislav Prskavec
How set one module (admin) active in maintenance mode?
I try:
public function routeShutdown(Zend_Controller_Request_Abstract $request)
{
if ($request-getModuleName()!=”admin”) {
$request-setActionName(‘index’);
$request-setModuleName(‘default’);
$request-setControllerName(‘maintenance’);
}
}
but have some problem
Maxence
You should return a status of 503 (Service Temporarily Unavailable) to tell to search engine bot that the site is down for maintenance.