Help us understand the problem. What is going on with this article?

Nginxでメンテナンスページに編集なしで即時切り替える方法

More than 3 years have passed since last update.

メンテナンスをする度にnginxの設定ファイルを編集するのはドキドキする & 構成管理的によろしくない。何より障害発生時は一刻を争うので、nginx の設定で時間を浪費したくない。

そこで、編集なしでメンテナンスページに切り替える方法を検討してみた。

実現したいこと

  1. 設定ファイルを編集することなく、メンテナンスページに切り替えたい
  2. 内部アクセス(例えばオフィス)では検証のため、メンテナンスにはしたくない
  3. オフィスのIPアドレスは増えるかもしれないのでそれを見越しておきたい

設定

いろいろ調べた上での結論から。

http {
  geo $access_from {
    default        external;
    203.0.113.0/24 internal;
  }

  server {
    error_page 503 @maintenance;

    set $maintenance false;

    if (-e /var/tmp/nginx/maintenance) {
      set $maintenance true;
    }
    if ($access_from !~ external) {
      set $maintenance false;
    }
    if ($maintenance = true) {
      return 503;
    }

    location @maintenance {
      root /var/www/html/static;
      rewrite ^(.*)$ /50x.html break;
    }
  }
}

こうしておけば、メンテナンスモードはファイルに touch するだけで発動することができます。便利。

$ touch /var/tmp/nginx/maintenance

調査 & 工夫したこと

geo

ngx_http_geo_module を利用して、 $access_from という独自変数を定義しています。

オフィスのゲートウェイIPが増えたとしても、 geo モジュールで internal とラベリングするだけでよく、if 文を連発しなくても済むいうのがミソ。

今回の設定例では一筆書きですが、/etc/nginx/conf.d/geo.conf 等に分離するのもアリです。

If is Evil?

If Is Evil という有名? なドキュメントがあります。設定間違えると、SIGSEGV するかもよ、と書かれててドキリとします。

よく読むと、

"Directive if has problems when used in location context"

"There are cases where you simply cannot avoid using an if, for example, if you need to test a variable which has no equivalent directive."

と書かれているので、用法用量を間違わなければ問題ナシです。

今回の例も evil にならないような設定をしている(はず)。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away