Maintenance Mode without using Artisan?
Solution 1:
You can just call artisan from your application:
Artisan::call('down');
Artisan::call('up');
But since you'll not have access to get your app up because it's down. You can create the functionality yourself:
A route for shut it down, user must be authenticated to do this:
Route::group(array('before' => 'auth'), function()
{
Route::get('shut/the/application/down', function()
{
touch(storage_path().'/meta/my.down');
});
});
A route to bring it back up:
Route::get('bring/the/application/back/up', function()
{
@unlink(storage_path().'/meta/my.down');
});
A filter to check if it's up:
Route::filter('applicationIsUp', function()
{
if (file_exists($this['path.storage'].'/meta/my.down'))
{
return Redirect::to('site/is/down');
}
});
A route to bring it back up:
Route::get('bring/the/application/back/up', function()
{
@unlink(storage_path().'/meta/my.down');
});
A route to show a pretty view when your site is down
Route::get('site/is/down', function()
{
return View::make('views.site.down');
});
Solution 2:
Laravel 5
Downfile is in storage/framework/down
- thanks @ruuter.
It needs to be populated with JSON:
{"time": UNIXTS, "message": "", "retry": ""}
Not sure where this message is used, but if you need to customize the message for Maintenance page, create resources/views/errors/503.blade.php
as you like.
Laravel 4.1 and below
Taking a look at the DownCommand
class for Artisan, it seems to create a new file within the app/storage/meta
folder.
Heres the DownCommand
fire
method.
public function fire()
{
touch($this->laravel['path.storage'].'/meta/down');
$this->comment('Application is now in maintenance mode.');
}
And the corresponding UpCommand
fire
method.
public function fire()
{
@unlink($this->laravel['path.storage'].'/meta/down');
$this->info('Application is now live.');
}
These files are located in vendor/laravel/framework/src/Illuminate/Foundation/Console
.
It specifically creates a file called down
in app/storage/meta
.
You could create an authorized route / controller action to replicate these commands.
Note Sjaak Trekhaa's comment below, that is the method I would use now that I've been reminded of it!
Solution 3:
Laravel 4
Just wanted to put this out there for everyone on the web, all php artisan down
does is touch (create) an empty file in the app/storage/meta
directory called 'down'. If this file exists, then the application is in maintenance mode. That's all there is to it:
// From vendor\laravel\framework\src\Illuminate\Foundation\Application.php
public function isDownForMaintenance()
{
return file_exists($this['config']['app.manifest'].'/down');
}
So if you can upload files, all you need to do is upload an empty file named 'down' to app/storage/meta
.
Laravel 5:
Down is located in storage/framework/down
Thanks ruuter.
Solution 4:
The real correct answer to question is above provided by Antonio.
You can just call artisan from your application:
Artisan::call('down'); Artisan::call('up');
Laravel 5+
Since middleware(s) were introduced in Laravel 5, I will cover how I do it in Laravel 5.3 application.
Create brand new middleware
First lets create new middleware $php artisan make:middleware CheckForMaintenanceMode
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Http\Exceptions\MaintenanceModeException;
class CheckForMaintenanceMode
{
protected $app;
public function __construct(Application $app)
{
$this->app = $app;
}
public function handle($request, Closure $next)
{
if ($this->app->isDownForMaintenance() && !$this->isBackendRequest($request)) {
$data = json_decode(file_get_contents($this->app->storagePath() . '/framework/down'), true);
throw new MaintenanceModeException($data['time'], $data['retry'], $data['message']);
}
return $next($request);
}
private function isBackendRequest($request)
{
return ($request->is('admin/*') or $request->is('login'));
}
}
Note: function
isBackendRequest()
which returnstrue
orfalse
if we are either in admin prefix (true
) or trying to login (true
) or anything else (false
)
replace global middleware
Open up App/Http/Kernel.php
and rewrite foundations middleware with our new middleware
protected $middleware = [
\App\Http\Middleware\CheckForMaintenanceMode::class,
];
If application is in maintenance mode (down) we can still access login page or any admin/*
page.
Route::group(['middleware' => 'auth', 'prefix' => 'admin'], function () {
//admin routes
});