You are here
Home > !Laravel > メンテナンス画面の裏口

メンテナンス画面の裏口

先日、開発完了のLaravelのプログラムをインストールするときに、私だけのためにメンテナンス画面に裏口があったらいいなと思いました。

Laravelでは、

php artisan down

このコマンドの実行で、すべてのアクセスを以下のようなメンテナンス画面にできます。そのモードに切り替えて、DBの変更とかなどのインストールの作業を誰にも邪魔されずにするのです。

Be right back. 2016-01-09 13-16-41

しかし、インストール後には、できる限りの動作テストを行いたいのですが、自分も含めて誰もアクセスできない状態は不都合です。せめて私や関係者だけ、つまりそれらのIPだけからは通常に見れるようにしたいのです。

私がフレームワークなしの時代に開発したプログラムでは、すべてのプログラムに共通で最初に読み込まれるPHPファイルに、以下のようなコードで、私だけが閲覧できるようにしていました。

$allow = array('xxx.xxx.xxx.xxx');

if (isset($_SERVER)) // ウェブのアクセスのみ
{
    if (isset($_SERVER["REMOTE_ADDR"]) && !in_array($_SERVER["REMOTE_ADDR"], $allow))
    {
        include_once "maintenance.php";
        exit;
    }
}

普段はこれらはコメントしておいて、メンテナンスのときにコメントを解除するのです。xxx.xxx.xxx.xxxは私の固定IPですが、そのIPだけが、メンテ画面を含むmaintenance.phpの実行をしないのです。

これと同じことをLaravelでできないでしょうか?

ちょっと調べたところ、以下のファイルにおいて、


class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
    ];
...

vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php

このファイルがミドルウェアとして、メンテナンスのモードかどうかをチェックしているらしい。

ということで、そのファイルをコピーして、

app/Http/Middleware/CheckForMaintenanceMode.php

として、その中味を以下のように編集します。


namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Foundation\Application;
use Symfony\Component\HttpKernel\Exception\HttpException;

class CheckForMaintenanceMode
{
    /**
     * The application implementation.
     *
     * @var \Illuminate\Contracts\Foundation\Application
     */
    protected $app;
    protected $allow = ['xxx.xxx.xxx.xxx'];
    /**
     * Create a new middleware instance.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function __construct(Application $app)
    {
        $this->app = $app;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {

        if ($this->app->isDownForMaintenance()) {
            if (!in_array($request->getClientIp(), $allow)) {
                throw new HttpException(503);
            }
        }

        return $next($request);
    }
}

基本的には、先のコードと同様なメカニズムです。

そして先のKernel.phpを

...
    protected $middleware = [
        \App\Http\Middleware\CheckForMaintenanceMode::class,
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
    ];
...

と編集する。簡単な変更ですが有用です。

ちなみに、メンテナンスの解除をするには、

php artisan up

これを実行するのみなのですが、ちょっとメカニズムに興味ありますね。

調べたところ、downでは、

storage/framework/down

という空のファイルを作成されます。そしてupの実行ではこのファイルが削除されます。意外とシンプルですね。

最後に、メンテナンスの画面は以下のファイルを編集します。

resources/views/errors/503.blade.php

Leave a Reply

Top