経験知ロゴ

Nginxで「ngx_cache_purge」モジュールを入れてProxy cacheを削除しやすくする方法

※本ページはプロモーションが含まれています

nginx
WordPressをNginxのProxy cacheを使用して高速化&負荷軽減する方法」でNginxのProxy cacheを使用するようにし、記事の投稿・更新時にキャッシュを削除してくれるWordPressプラグイン「Nginx Proxy Cache Purge」を導入したのですが、このプラグインはNginxに「ngx_cache_purge」モジュールが入っていないと動かないことが分かったので、「ngx_cache_purge」モジュールを導入する手順をメモ。

前提

Nginxはyumを使用しインストールしたのだが、「ngx_cache_purge」モジュールを追加するにはソースコードから再ビルドするためyumは使えない。

そこで思い切って、モジュールの追加もNginxのバージョンアップもしやすいソースコードからビルドする方法に変えることにした。

メンテナンス用にApacheの設定。

ソースコードからビルドしたNginxに変更する際にサーバーを停止させなければいけない。上手くいけば数分だが、作業が長引いてしまうと、検索エンジンやユーザーに対してよろしくないのでApacheを使いメンテナンス画面をステータスコード503で返すように設定。

メンテナンス用のディレクトリを作成。

$ sudo mkdir /var/www/maintenance

「maintenance.html」を作成。

$ cd /var/www/maintenance
$ sudo vi maintenance.html

簡単にこんな内容で作成。

<!DOCTYPE html>
<html>
    <head>
        <title>メンテナンス中 | 経験知</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <style>
        body { text-align: center; padding: 150px; }
        h1 { font-size: 50px; }
        body { font: 20px Helvetica, sans-serif; color: #333; }
        article { display: block; text-align: left; width: 650px; margin: 0 auto; }
        a { color: #dc8100; text-decoration: none; }
        a:hover { color: #333; text-decoration: none; }
</style>
    </head>
    <body>
    <article>
        <h1>メンテナンス中</h1>
        <p>只今メンテナンス中です。〇〇時には終了します。</p>
    </article>
    </body>
</html>

「httpd.conf」の設定。

$ sudo vi /etc/httpd/conf/httpd.conf
# ServerTokens On
ServerTokens Prod
......
# ServerName www.example.com:80
ServerName yourdomain:80
......
# DocumentRoot "/var/www/html"
DocumentRoot "/var/www/maintenance"
......
# <Directory "/var/www/html">
<Directory "/var/www/maintenance">
......
# ServerSignature On
ServerSignature Off
......
<VirtualHost *:80>
DocumentRoot /var/www/maintenance
ServerName yourdomain
ErrorDocument 503 /maintenance.html
RewriteEngine On
RewriteCond %{REQUEST_URI} !=/maintenance.html
RewriteRule ^.*$ - [R=503,L]
</VirtualHost>

上記部分を変更。

「httpd.conf」の構文チェック。

$ sudo apachectl configtest

「Syntax OK」が表示されたらメンテナンス画面が表示されるか確認するため、Nginxを止めてhttpdを起動し確認できたらすぐ戻す。

$ sudo /etc/init.d/nginx stop
$ sudo /etc/init.d/httpd start

トップページや各ページでメンテナンス画面が表示されたらhttpdを止めNginxを起動する

$ sudo /etc/init.d/httpd stop
$ sudo /etc/init.d/nginx start

これでNginxの切替時の下準備完了。

新しいNginxのビルドと切り替え

yum は止めて nginx をソースからインストールする | 脳無しの呟き《土鍋と麦酒と炬燵猫》」を参考に進めていく。SPDYは入れない。

バックアップを作成

$ mkdir ~/backup
$ cd ~/backup
$ sudo cp -r /var/www/html ./
$ sudo cp -r /etc/nginx ./
$ sudo cp /etc/init.d/nginx ./nginx.orig // 起動スクリプト保存

作業ディレクトリを「/usr/local/src/nginx」に作成しNginx、ngx_cache_purgeをダウンロードして展開。
因みに「src」は一般的にソースコードを入れるディレクトリ。

$ sudo mkdir /usr/local/src/nginx
$ cd /usr/local/src/nginx

nginx newsでNginxの最新版のバージョンを確認。今回は1.6.0と1.7.0があったが、「stable」版の1.6.0を使うことにした。

$ sudo wget http://nginx.org/download/nginx-1.6.0.tar.gz

バージョンによって「1.6.0」の部分を変える。

OpenSSL: The Open Source toolkit for SSL/TLS」で最新のOpenSSLのバージョンを確認しダウンロード。

$ sudo wget http://www.openssl.org/source/openssl-1.0.1g.tar.gz

「1.0.1g」の部分はダウンロードするバージョンに変更。

FRiCKLE Labs / nginx / ngx_cache_purge」で最新版のngx_cache_purgeを確認しダウンロード。

$ sudo wget http://labs.frickle.com/files/ngx_cache_purge-2.1.tar.gz

「2.1」の部分はダウンロードするバージョンに変更。

ダウンロードした3つのファイルを解凍。

$ sudo tar xvzf nginx-1.6.0.tar.gz
$ sudo tar xvzf openssl-1.0.1g.tar.gz
$ sudo tar xvzf ngx_cache_purge-2.1.tar.gz

現在稼働中のNginxのfonfigureを確認し、「configure arguments」をコピーする。

$ nginx -V

こんな感じで表示される。
configure

コピーしたものをテキストエディタで開き、下記部分を環境に合わせて修正・追加。

 --prefix=/usr/local/nginx-1.6.0 // 変更
 --sbin-path=/usr/local/sbin/nginx // 変更
 --with-openssl=/usr/local/src/nginx/openssl-1.0.1g // 追加
 --add-module=/usr/local/src/nginx/ngx_cache_purge-2.1 // 追加

修正・追加したらビルドを実行。

$ sudo ./configure --prefix=/usr/local/nginx-1.6.0 --sbin-path=/usr/local/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-mail --with-mail_ssl_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-ld-opt=-Wl,-E  --with-openssl=/usr/local/src/nginx/openssl-1.0.1g --add-module=/usr/local/src/nginx/ngx_cache_purge-2.1

下記のようなエラーがでた。

./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre= option.

「PCRE」ライブラリが足りないのでインストール。

$ sudo yum install pcre pcre-devel

もう一度「configure」を試す。

またエラー

./configure: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using --without-http_gzip_module
option, or install the zlib library into the system, or build the zlib library
statically from the source with nginx by using --with-zlib= option.

「zlib」ライブラリがないのでインストール。他にもエラーが出たのでインストールしたもののまとめ。

$ sudo yum install zlib zlib-devel
$ sudo yum --enablerepo=epel,remi,rpmforge install libxml2 libxml2-devel
$ sudo yum --enablerepo=epel,remi,rpmforge install libxslt libxslt-devel
$ sudo yum install gd gd-devel php-gd

エラーが出なくなったらインストール。

$ sudo make
$ sudo make install
$ sudo ln -s /usr/local/nginx-1.6.0 /usr/local/nginx

最後の「ln」コマンドは「/usr/local/nginx」というエイリアスを作ることで新しいバージョン「/usr/local/nginx-1.6.1 」を新たに作成した時に

$ sudo ln -s /usr/local/nginx-1.6.1 /usr/local/nginx

とするだけで良いので、後々のバージョンアップが簡単になる。

新しいバージョンのNginxが問題ないかの確認。

$ sudo /usr/local/sbin/nginx -t

下記のようなエラーが出た

nginx: [emerg] open() "/usr/local/nginx-1.6.0/logs/keikenchi.access.log" failed (2: No such file or directory)
nginx: configuration file /etc/nginx/nginx.conf test failed

ディレクトリが無いというので作る。

$ sudo mkdir /usr/local/nginx-1.6.0/logs

もう一度テストすると

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

テストOK。

Nginxを止めhttpdを立ち上げメンテナンス画面に切り替える。

$ sudo /etc/init.d/nginx stop
$ sudo /etc/init.d/httpd start

nginxの設定ファイルを編集

$ sudo vi /etc/init.d/nginx

下記のように変更

#nginx=${NGINX-/usr/sbin/nginx}
nginx=${NGINX-/usr/local/sbin/nginx}

「sysconfig」ファイルを編集。

$ sudo vi /etc/sysconfig/nginx

下記の一行をファイルの最後に追加

NGINX=/usr/local/sbin/nginx

起動スクリプト等の確認。

$ sudo chkconfig --add nginx
$ sudo chkconfig nginx on
$ sudo chkconfig --list nginx // ランレベル 2345 が on であること確認
$ sudo /usr/local/sbin/nginx -t // 念のため設定ファイルに問題ないか再度確認

問題がなければhttpdを止めnginxを起動し、バージョンを確認する。

$ sudo /etc/init.d/httpd stop
$ sudo /etc/init.d/nginx start
$ /usr/local/sbin/nginx -v

インストールしたバージョンが表示されたら完了!

ngx_cache_purgeの設定

「default.conf」を設定。

$ sudo vi /etc/nginx/conf.d/default.conf
server {
    listen       80;
 …
    location / {
        proxy_pass http://backend;
        proxy_cache zone; //zoneに注意
        proxy_cache_key $scheme://$host$uri$is_args$args;
        proxy_cache_valid  200 1d;
    }
    location ~ /purge(/.*) {
      allow 127.0.0.1;
      deny all;
      proxy_cache_purge zone "$scheme://$host$1$is_args$args"; //zoneに注意
    }

を追加。2箇所の「zone」の部分に注意。「/etc/nginx/nginx.conf」の

   proxy_cache_path /var/cache/nginx/cache levels=1 keys_zone=zone:4m inactive=7d max_size=50m;

で指定した「keys_zone=zone」の値を指定する。

保存したら再起動。

$ sudo service nginx restart

後はWordPressのプラグイン「Nginx Proxy Cache Purge」をインストールすれば、新規投稿、編集時に編集したページのキャッシュを削除してくれる。

おわりに

参考サイト「yum は止めて nginx をソースからインストールする | 脳無しの呟き《土鍋と麦酒と炬燵猫》」を元に進めましたが、やはり僕の環境とは違うところがあり、なんとか完了することが出来ました。

yumでインストールしたNginxはそのままになってます。。。

この手順はあくまで僕が行った作業のメモです。この通りにやってうまくいく保証はないのでこの通りにやる場合は自己責任でお願いします。

もっとサーバーの勉強もしないとな〜

役に立ったらこの記事のシェアをお願いします

ブログのフォロー・RSS購読は下記ボタンから