Work on a Laravel Live Site while in Maintenance Mode

Reading time ~2 minutes

Introduction

Since Laravel 4 there’s a handy feature that allows you to put your site in maintenance mode, providing a good way to hide your changes from external eyes. This feature is really helpful on your testing or production server since it doesn’t allow users to browse the site, so you can make you modifications pretty much unnoticed.

The artisan commands are the following:

php artisan down

to put the site into maintenance mode, and

php artisan up

to disable the maintenance mode.

When you don’t have access to the command line, for example in case of shared web servers, you can embed artisan commands in your routes.

Route::get('/up', function() {
    \Artisan::call('up');

    return "up";
});
Route::get('/down', function() {
    \Artisan::call('down');

    return "down";
});

However this approach disables the access to the site to everyone, including you. If you want to work on your production server (for your legitimate reasons) while in maintenance mode you can create a Cookie to differentiate your requests from the other ones. For example you can add a temporary route, like the following, to add a cookie to your domain with a secret code (a random string):

Route::get('/secret-cookie', function() {
	$response = new Illuminate\Http\Response('Cookie installed');

	$response->withCookie(cookie()->forever('secret-cookie', '<random string>'));

	return $response;
});

Now all your requests to the site will include this cookie so you have means to easily differentiate who’s calling your routes. Create a new Middleware called CheckForMaintenanceMode by copying the content from Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode. Then edit the handle function with the following code

if ($this->app->isDownForMaintenance())
{
    $cookie = $request->cookie('secret-cookie');

    // Laravel cookies are encrypted
    $value = \Illuminate\Support\Facades\Crypt::decrypt($cookie);

    if($value != '<random string>') {
        return response('Be right back!', 503);
    }
}

return $next($request);

Finally you have to tell Laravel to use your implementation instead of the default one. In Http\Kernel.php simply insert your file in the $middleware array and comment/remove the default implementation.

protected $middleware = [
    //'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
    'App\Http\Middleware\CheckForMaintenanceMode',
	...
]

That’s it!