Nginxとリバースプロキシ、php-fpmとOPcacheのインストールと設定


投稿日:2015年1月25日
  • 17
  • 0



WordPressを高速動作させるWebサーバの裏側

gmo_nginx

前回」に続いて「GMO VPSを契約してWordPressを安定動作させるまでのサーバ設定方法」第四弾。

この投稿ではWordPressの高速動作に最も効果のあるWebサーバのNginxリバースプロキシを組み合わせた設定と、PHPのphp-fpmOPcacheを組み合わせた設定をします。

今回の解説で利用したVPSはこちら


目次


Apacheのアンインストール

Nginxを導入するので、同じくWebサーバのApacheを削除しておきます。

# yum erase httpd
Dependencies Resolved

================================================================================
 Package           Arch        Version                      Repository     Size
================================================================================
Removing:
 httpd             x86_64      2.2.15-30.el6.centos         @updates      2.9 M
Removing for dependencies:
 httpd-manual      noarch      2.2.15-30.el6.centos         @updates      3.5 M
 mod_perl          x86_64      2.0.4-11.el6_5               @updates      6.1 M
 mod_ssl           x86_64      1:2.2.15-30.el6.centos       @updates      183 k
 mod_wsgi          x86_64      3.2-3.el6                    @base         177 k
 php               x86_64      5.3.3-27.el6_5               @updates      3.5 M
 webalizer         x86_64      2.21_02-3.3.el6              @base         324 k

Transaction Summary
================================================================================
Remove        7 Package(s)

Nginxの公式リポジトリを追加してインストール

Nginxは公式ページにリポジトリが用意されているので、CentOS 6用を登録してyumでインストールします。

nginx: Linux packages

# wget http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
# rpm -ivh nginx-release-centos-6-0.el6.ngx.noarch.rpm
# rm nginx-release-centos-6-0.el6.ngx.noarch.rpm

リポジトリの優先順位を変更

# vi /etc/yum.repos.d/nginx.repo

[nginx]の後にpriority=2を追加。

[nginx]
priority=2

以下を変更。

enabled=1
↓
enabled=0

追加したnginxリポジトリを利用してインストール

# yum --enablerepo=nginx install nginx
Dependencies Resolved

================================================================================
 Package        Arch            Version                    Repository      Size
================================================================================
Installing:
 nginx          x86_64          1.6.0-1.el6.ngx            nginx          335 k

Transaction Summary
================================================================================
Install       1 Package(s)

バージョン確認

# nginx -v
nginx version: nginx/1.6.0

リバースプロキシとログファイル用のディレクトリの作成と所有権の変更

キャッシュとログのディレクトリの所有権をNginxの実行ユーザーと合わせておきます。今回はTera Termのときに作成した「wwwユーザー」で管理します。

具体的には以下のディレクトリがなければ作成します。

$ mkdir /var/tmp/nginx
$ mkdir /var/cache/nginx
$ mkdir /var/log/nginx/
$ mkdir /var/lib/nginx

所有権をNginxの実行ユーザーに変更。

# chown -R www:www /var/tmp/nginx
# chown -R www:www /var/log/nginx/
# chown -R www:www /var/cache/nginx
# chown -R www:www /var/lib/nginx

Nginxの動作確認

# /etc/init.d/nginx start

とりあえずこれだけでブラウザにIP(名前解決できていればドメイン名)を入力すれば以下のように表示されるはずです。

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

自動起動を有効にしとく

# chkconfig --list nginx
# chkconfig nginx on

Nginxのリバースプロキシを使った設定

下準備ができたので、Nginxの設定を行います。
ポート80で受けてキャッシュが有効でない場合は8080へ渡すという、基本的なリバースプロキシの使い方です。
その他の設定はそれぞれのコメントで解説したので参照してください。

モバイル用と、スマホ用でサイトの構成が異なる場合は113~120行目と、133行目のコメントアウトを削除、134行目を削除してください。

# cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.org
# vi /etc/nginx/nginx.conf
# 実行ユーザーの変更
user  www www;

# プロセス数。CPU数とすることが多いがnginxに任せる
worker_processes  auto;

# デフォルトはerrorレベル以上のログをlogs/error.log。この例ではwarn以上
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024; # 1つのworkerプロセスが開ける最大コネクション数
    multi_accept on; # できるだけクライアントからのリクエストを受け取る
    use epoll; # Linuxカーネル2.6以上の場合はepoll、BSDの場合kqueue
}

http {
    server_tokens off; # エラー画面にバージョンを表示しない
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    client_max_body_size 10M; # アップロードサイズ 413 Request Entity Too Large対策

    # 「nginx: [emerg] could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32」の対策
    server_names_hash_bucket_size 64;

    # 「an upstream response is buffered to a temporary file」 対策
    # バッファサイズをオーバーしたのでメモリではなくファイルへ書き込むという警告。即問題があるわけではない
    proxy_max_temp_file_size 1024M;
    proxy_buffers 16 32k;
    proxy_buffer_size 64k;

    # 「a client request body is buffered to a temporary file」 対策
    client_body_buffer_size 64k; # Default: 8k|16k

    # logフォーマットの定義と指定。デフォルト(省略)はcombinedという定義。
    # こちらはhttpディレクティブ限定なので注意。
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on; # ハードディスクio処理とsocket-io処理のバランスを取る
    tcp_nopush      on; # TCP_CORKソケットオプションを使ってデータを1度に送る

    keepalive_timeout  65;

    gzip on; # コンテンツの圧縮を許可
    gzip_disable "MSIE [1-6]\."; # IEの1~6はキャッシュ対応していないので無効
    gzip_proxied any; # 全てのプロキシも圧縮
    gzip_min_length 1024; # gzip 圧縮を行うデータの最小サイズ
    gzip_comp_level 6; # 圧縮レベル設定、1-9
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript; # 圧縮ファイルタイプ

    # ここからプロキシサーバ設定(キャッシュサイズ、期間はサイトに合わせて変更すること)
    proxy_cache_path  /var/cache/nginx levels=1:2 keys_zone=czone:8m max_size=5000m inactive=7d; # キャッシュの場所、ディレクトリ構造、キーゾーン名とオブジェクトを保存するキーの全体サイズ(オブジェクト1つにつき128バイト消費する)、合計の最大キャッシュサイズ、保存期間。
    proxy_temp_path   /var/tmp/nginx; # テンポラリファイルのパス
    proxy_cache_key $scheme://$host$request_uri; # キャッシュに付与されるキー。削除時重要 ※要複数サイト運営時確認
    # ここからヘッダ。
    proxy_set_header  Host               $host;
    proxy_set_header  X-Real-IP          $remote_addr;
    proxy_set_header  X-Forwarded-Host   $host;
    proxy_set_header  X-Forwarded-Server $host;
    proxy_set_header  X-Forwarded-For    $proxy_add_x_forwarded_for;

    # バックエンドサーバ(リバースプロキシ)を指定する
    # ip_hashはローカルのみなので必要がないが一応作法として残す
    upstream backend {
        ip_hash;
        server 127.0.0.1:8080;
    } # upstream backend


# example.comの設定
#---------------------------------------------------------------------

    # まずはURLの正規化でwwwありをwwwなしへリダイレクト
    server {
        listen 80;
        server_name www.example.com;
        rewrite	^ http://example.com$request_uri?;
    }

    # リバースプロキシサーバの設定(ポート80用の設定)
    # 通常外部からのアクセスはここで受ける
    server {
        listen       80;
        server_name  example.com;

        # 現行のNginxでドキュメントルートをlocationディレクティブ内に記述するのは誤り
        root   /var/www/html/example;  # ドキュメントルート
        index  index.html index.htm index.php; # indexの設定

        access_log  /var/log/nginx/example.com_access.log  main;
        error_log  /var/log/nginx/example.com_error.log warn;

        # キャッシュの有効無効を調べるX-Cache:HITで有効、MISSで無効
        add_header X-Cache $upstream_cache_status;

        # ロケーション(以下の様な場合にどこで待ち受けるという指定)
        location /wp-admin { proxy_pass http://backend; }
        location ~ .*\.php { proxy_pass http://backend; }

        # サーバ全般の指定
        location / {
            # モバイル、スマホ、ログイン画面、それぞれフラグを付け
            # キャッシュの挙動を変える
            # ※モバイル用はサイトを分けていないのでキャッシュの振り分けは不採用

            # まずは初期化(using uninitializedと出るので)
            set $mobile "";
            set $do_not_cache "";

#            # モバイル用
#            if ($http_user_agent ~* '(DoCoMo|J-PHONE|Vodafone|MOT-|UP\.Browser|DDIPOCKET|ASTEL|PDXGW|Palmscape|Xiino|sharp pda browser|Windows CE|L-mode|WILLCOM|SoftBank|Semulator|Vemulator|J-EMULATOR|emobile|mixi-mobile-converter)') {
#                set $mobile 1;
#            }
#            # スマホ用
#            if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry)') {
#                set $mobile 2;
#            }

            # WordPressのログイン画面用
            if ($http_cookie ~* "comment_author_[^=]*=([^%]+)%7C|wordpress_logged_in_[^=]*=([^%]+)%7C") {
                set $do_not_cache 1;
            }

            # ログイン画面の時はproxy_no_cacheやproxy_cache_bypassが1となりキャッシュが無効になる
            proxy_no_cache     $do_not_cache;
            proxy_cache_bypass $do_not_cache;
            proxy_cache czone;

            # プロキシキャッシュをMD5で作成する際に利用するキー
            # proxy_cache_key $scheme://$host$uri$is_args$args$mobile; #モバイル用で振り分ける場合はこちら
            proxy_cache_key $scheme://$host$uri$is_args$args;

            # ステータスコードごとにキャッシュの期間を指定。proxy_cache_pathよりこちらが優先
            proxy_cache_valid  200 301 302 1d; # 1日も保存すればいいかな?
            proxy_cache_valid  404 5m;
            proxy_cache_use_stale  error timeout invalid_header updating
                                   http_500 http_502 http_503 http_504;

            proxy_pass http://backend; # プロキシの保存先を指定

            # レスポンスヘッダの書き換え
            proxy_redirect http://example.com:8080/ /;
        } # location /

    } # server 80

    # バックエンドサーバの設定(こちらはポート8080の設定)
    server {
        listen       8080;
        server_name  example.com;

        root   /var/www/html/example;
        index  index.html index.htm index.php;

        location / {
            charset utf-8;

            # PHPに関する設定
            location ~ \.php$ {
                fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include        fastcgi_params;
            } # location ~ \.php$

            # 制限事項は別ファイルのものを読み込む
            include global/restrictions.conf;

            # WordPressも別ファイルのものを読み込む
            # 複数WordPressサイトを運営していても共通の部分はモジュール化するほうが管理が楽なため
            include global/wordpress.conf;
            # include global/wordpress-ms-subdir.conf; # マルチサイト用
            # include global/wordpress-ms-subdomain.conf; # マルチサイト用

            # バックエンドサーバ側でもIPを表示できるようにする。
            set_real_ip_from 127.0.0.1;
            real_ip_header X-Forwarded-For;

        } # location /

        # エラーページ用の設定
        error_page  404              /404.html;
        location = /404.html {
            root   /usr/share/nginx/html;
        } # location = /404.html

        # エラーページの設定500番代
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        } # location = /50x.html

    } # server 8080
} # http

restrictions.confの作成

上の設定ファイルでincludeしていたファイルの作成。
参考URLにあるようにglobalディレクトリを作成してファイルを作成します。

参考URL:Nginx « WordPress Codex

# mkdir /etc/nginx/global
# vi /etc/nginx/global/restrictions.conf
# Global restrictions configuration file.
# Designed to be included in any server {} block.</p>
location = /favicon.ico {
	log_not_found off;
	access_log off;
}

location = /robots.txt {
	allow all;
	log_not_found off;
	access_log off;
}

# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~ /\. {
	deny all;
}

# Deny access to any files with a .php extension in the uploads directory
# Works in sub-directory installs and also in multisite network
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~* /(?:uploads|files)/.*\.php$ {
	deny all;
}

wordpress.confの作成

これはWordPress独自の設定。こちらも参考URLのものを利用。

# vi /etc/nginx/global/wordpress.conf

fastcgi_passの部分だけサイトに合わせて設定します。
後でphp-fpmの項目で設定するので以下のようにしておいてください。

# WordPress single blog rules.
# Designed to be included in any server {} block.

# This order might seem weird - this is attempted to match last if rules below fail.
# http://wiki.nginx.org/HttpCoreModule
location / {
	try_files $uri $uri/ /index.php?$args;
}

# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

# Directives to send expires headers and turn off 404 error logging.
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
	expires 7h;
	log_not_found off;
}

# Uncomment one of the lines below for the appropriate caching plugin (if used).
#include global/wordpress-wp-super-cache.conf;
#include global/wordpress-w3-total-cache.conf;

# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ \.php$ {
	# Zero-day exploit defense.
	# http://forum.nginx.org/read.php?2,88845,page=3
	# Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
	# Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine.  And then cross your fingers that you won't get hacked.
	try_files $uri =404;

	fastcgi_split_path_info ^(.+\.php)(/.+)$;
	#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

	include fastcgi_params;
	fastcgi_index index.php;
	fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#	fastcgi_intercept_errors on;
#	fastcgi_pass 127.0.0.1:9000;
	fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
}
ここでnoteに「cgi.fix_pathinfo = 0」にしろとあるが、PHP 5.3.9以降なら必要ない。security.limit_extensionsという項目があり、デフォルト値がphpとなっているため、phpファイル以外をphpとして実行するようなことはないため。

参考URL:PHP-FPMでcgi.fix_pathinfo=0は必要なのか

nginxで動作させるphp-fpmのインストールと設定

過去はspawn-fcgiとの組み合わせが良くありましたが、最近はphp-fpmを使うのが主流です。

Nginx でPHPを動かす(php-fpmをバイナリパッケージ(rpm)を作成し、インストールする) [PHP5.2系の場合]」によると、
spawn-fcgiが、PHPと全く独立したプログラムで、FastCGIプロセス管理を行うのに対して
php-fpmは、PHPに一部機能を組み込んで、FastCGIプロセス管理を行うという違いがあるそうです。

# yum install php-fpm
Dependencies Resolved

================================================================================
 Package         Arch           Version                   Repository       Size
================================================================================
Installing:
 php-fpm         x86_64         5.3.3-27.el6_5            updates         1.1 M

Transaction Summary
================================================================================
Install       1 Package(s)

php-fpmの設定ファイルを編集

# cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.org
# vi /etc/php-fpm.d/www.conf

一応listenの値を確認しておく。nginxの設定と合わせる。

listen = 127.0.0.1:9000
↓
listen = /var/run/php-fpm/php-fpm.sock

リバースプロキシを導入して、w3c total cacheで管理したいので、キャッシュの削除の際に権限が無いと困るのでxginxの実行者と統一しておく。

user = apache
group = apache
↓
user = www
group = www

listenについては別に設定する必要がある。

;listen.owner = nobody
;listen.group = nobody
;listen.mode = 0666
↓
listen.owner = www
listen.group = www
listen.mode = 0660

メモリ等が不足する場合は実行数を以下の設定で調整する。

pm.max_children = 50
pm.max_spare_servers = 35
↓
pm.max_children = 15
pm.max_spare_servers = 15
pm.max_spare_servers」は「pm.max_children」以下にしないと、下のエラー出るので注意。

Starting php-fpm: [16-Sep-2014 10:39:03] ALERT: [pool www] pm.min_spare_servers(5) and pm.max_spare_servers(35) cannot be greater than pm.max_children(15)
[16-Sep-2014 10:39:03] ERROR: failed to post process the configuration
[16-Sep-2014 10:39:03] ERROR: FPM initialization failed

ログ用のディレクトリの権限変更

デフォルトだとapacheになっているようだ。

# chown www.www /var/log/php-fpm/

php-fpmの起動

# /etc/init.d/php-fpm start

php-fpmを起動項目に追加

# chkconfig --list php-fpm
# chkconfig php-fpm on

/etc/php.iniの編集

このままだとdate.timezoneのエラーが出るのでPHPのタイムゾーンの設定をする。

# cp /etc/php.ini /etc/php.ini.org
# vi /etc/php.ini
;date.timezone
↓
date.timezone = Asia/Tokyo

このままだとアップロード可能な最大ファイルサイズが2MBなのを修正。どちらも「memory_limit = 128M」以下でないとだめなので注意。

; post_max_size = 8M
↓
post_max_size = 32M
; upload_max_filesize = 2M
↓
upload_max_filesize = 32M

これで32MBまでアップロードできる。

逆にPHPの実行にメモリが足りないと出ることがあるのでphp-fpmの設定ファイルを調整。

# vi /etc/php-fpm.d/www.conf
;php_admin_value[memory_limit] = 128M
↓
php_admin_value[memory_limit] = 256M

再起動して反映。

# /etc/init.d/php-fpm restart

OPcacheのインストールと設定

PHPのキャッシュといえばAPCでしたが、深刻なメモリ上の障害があり、バージョン3.1.14から開発が中止しています。
代わりにPHP5.5からはopcasheが正式に採用されました。
導入が容易で、ベンチマークはOPcacheのほうが20%も高速とのことなので、OPcacheへの乗り換えもすぐに終了しそうです。

今回インストールしたremiリポジトリではPHPのバージョンが5.4止まりでしたが、PECLを利用したインストール方法が用意されています。

PECLについては詳しくは「PECL 拡張モジュールのインストール」を参照してください。

PECLを使うにはphp-develが必要なのでインストールします。

# yum install --enablerepo=remi --disablerepo=base,updates,extras,centosplus,contrib php-devel
(省略)
Dependencies Resolved

===============================================================================
 Package             Arch          Version                   Repository   Size
===============================================================================
Installing:
 php-devel           x86_64        5.4.32-1.el6.remi         remi        1.2 M
Updating for dependencies:
 php-bcmath          x86_64        5.4.32-1.el6.remi         remi         61 k
 php-cli             x86_64        5.4.32-1.el6.remi         remi        3.9 M
 php-common          x86_64        5.4.32-1.el6.remi         remi        933 k
 php-fpm             x86_64        5.4.32-1.el6.remi         remi        1.3 M
 php-gd              x86_64        5.4.32-1.el6.remi         remi        145 k
 php-mbstring        x86_64        5.4.32-1.el6.remi         remi        946 k
 php-mcrypt          x86_64        5.4.32-1.el6.remi         remi         52 k
 php-mysql           x86_64        5.4.32-1.el6.remi         remi        137 k
 php-pdo             x86_64        5.4.32-1.el6.remi         remi        121 k
 php-recode          x86_64        5.4.32-1.el6.remi         remi         38 k
 php-tidy            x86_64        5.4.32-1.el6.remi         remi         56 k
 php-xml             x86_64        5.4.32-1.el6.remi         remi        172 k

Transaction Summary
===============================================================================
(省略)

peclでOPcacheをインストール

# pecl install zendopcache-beta
(省略 ズラーっとたくさん出る)
Build process completed successfully
Installing '/usr/lib64/php/modules/opcache.so'
install ok: channel://pecl.php.net/zendopcache-7.0.3
configuration option "php_ini" is not set to php.ini location
You should add "zend_extension=opcache.so" to php.ini

丁寧に「zend_extension=opcache.so」を追加しろと表示されています。

# vi /etc/php.ini

特に設定する項目はないですが、opcache.memory_consumptionで使用するメモリサイズ(MB)を指定してください。
WordPress単独なら128MBもあれば十分です。

[zendopcache]
zend_extension=/usr/lib64/php/modules/opcache.so
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1

再起動

# /etc/init.d/php-fpm restart

確認

# php -v
PHP 5.4.32 (cli) (built: Aug 21 2014 07:33:35)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies

Zend OPcache v7.0.3」と表示されていれば成功です。


OPcacheの利用状況をグラフ化して表示

インストールしただけだと正しく動作しているか、容量が十分かなど確認できないので、グラフ化してくれるツールをインストールします。

OCP – Opcache Control Panel」をダウンロードして、公開ディレクトリにアップロード。
あとはブラウザからアクセスするだけで以下のように表示されます。
常設する場合は、セキュリティ上の問題になるので、アクセス規制をしておいてください。

gmo_nginx01

Free Memoryの項目が極端に少ないようならopcache.memory_consumptionを、
キーの数が足りないようならopcache.max_accelerated_filesを、
それぞれメモリの許す範囲で増やしてください。


今回の解説で利用したVPSはこちら
GMOクラウドのVPS

以上でWebサーバとPHPの設定が完了しました。
適切に設定をすれば、無調整のApacheで運用するのに比べて数百倍のアクセスをさばくことができます。

次は「MySQLのインストールと各種設定、phpMyAdminのインストールと設定」です。


現在のページを共有する



現在のページに関連する記事

Nginxとリバースプロキシ、php-fpmとOPcacheのインストールと設定 Nginxで502 Bad Gatewayの原因が「upstream sent too big header~」の場合の対処法
Nginxとリバースプロキシ、php-fpmとOPcacheのインストールと設定 WordPressの特定のファイルに対してNginxでIPを規制する方法
Nginxとリバースプロキシ、php-fpmとOPcacheのインストールと設定 NginxとFastCGIの組み合わせでHTTP_USER_AGENTが取得できない
Nginxとリバースプロキシ、php-fpmとOPcacheのインストールと設定 Nginx 1.6.2にngx_cache_purge 2.3組み込むんでコンパイルする方法
Nginxとリバースプロキシ、php-fpmとOPcacheのインストールと設定 WordPressのサイトをHTTPS化して学ぶLet’s Encryptの使い方
Nginxとリバースプロキシ、php-fpmとOPcacheのインストールと設定 MySQLのインストールと各種設定、phpMyAdminのインストールと設定
Nginxとリバースプロキシ、php-fpmとOPcacheのインストールと設定 Nginxで特定の国のIPだけを許可する方法

おすすめの記事

公式ドキュメントよりも詳しいTinyMCEの使い方(基本編)

公式ドキュメントよりも詳しいTinyMCEの使い方(基本編)

WordPressのサイトをHTTPS化して学ぶLet’s Encryptの使い方

WordPressのサイトをHTTPS化して学ぶLet’s Encryptの使い方

WordPressの最速キャッシュを探せ!APC、memcached、Transients APIを比較

WordPressの最速キャッシュを探せ!APC、memcached、Transients…

DELL Inspiron 3250のHDDをSSDへ換装して、メモリを16GBへ増設

DELL Inspiron 3250のHDDをSSDへ換装して、メモリを16GBへ増設

最新のXAMPPをインストールし、安全・高速に運用する方法

最新のXAMPPをインストールし、安全・高速に運用する方法

Windows 10でpsd形式のファイルをサムネイル表示する方法

Windows 10でpsd形式のファイルをサムネイル表示する方法

自前の国別IPv6、IPv4アドレス割当リストを作成しよう

自前の国別IPv6、IPv4アドレス割当リストを作成しよう

Apacheのmod_rewriteモジュールの使い方を徹底的に解説

Apacheのmod_rewriteモジュールの使い方を徹底的に解説


いただいたコメントなど

  1. 岡田 のコメント:

    非常に参考になりました。
    色々nginx関連の記事を見ましたがここが一番優れていました!!

    • oxy のコメント:

      丁寧にコメントありがとうございます。
      優れていたなんてとんでもない。様々なサイトから知恵を拝借してまとめただけです。
      元は個人的なメモですが、お役に立てたようで何よりです。

  2. 岡田 のコメント:

    こんばんは、先ほどの岡田です。
    GTMetrixで調べるとどうも不調でした(Pagespeed C)。

    そこで、
    Nginxを使っったもう一歩進んだWordPressチューニング
    http://cloudrop.jp/wordpress/more_tuning_on_nginx

    こちら(WP Super Cache)と組み合わせることは可能でしょうか?
    W3TotalCacheでも構いませんが
    # Uncomment one of the lines below for the appropriate caching plugin (if used).
    #include global/wordpress-wp-super-cache.conf;
    #include global/wordpress-w3-total-cache.conf;
    このコメントを外すだけで使えるということでしょうか?

    リバースプロキシとWPキャッシュはどちらか一方だけなのでしょうか?

    よろしくお願いします。

    追伸:右下のコップの跡がリアルでびっくりしました

    • oxy のコメント:

      まず内容を整理したいと思います。

      紹介していただいたNginxを使ったもう一歩進んだWordPressチューニングについてです。

      1.fastcgi cache(HttpFcgiModule)を使ったキャッシュ
      2.WP Super Cacheを使ったキャッシュ

      上記二点が解説されています。
      まず1についてですが、このページではリバースプロキシを利用したキャッシュ方法を解説しています。
      fastcgi cacheとリバースプロキシを比較した場合、速度の違いは微々たるもので、ほとんど影響がないと思って頂いて構いません。
      リバースプロキシにはスケールアップ時にロードバランサという機能を利用したり、
      複数のサイトを運営する場合にキャッシュの場所を個別に設定できるなどメリットがいくつかあるので、
      「サーバ1台でWordPressのサイトを1つだけ運営する」という限られた場合以外はリバースプロキシをお勧めします。

      2のついては、先に結論を書けば、リバースプロキシとWP Super CacheやW3 Total Cacheを組み合わせることはできますが効果は限定的です。

      WP Super Cacheというプラグインを実際に使ったことは無いので説明は避けます。
      ざっと設定を見るとPHPやSQLの結果をキャッシュするもののようです。

      そこでこのサイトでも使っているW3 Total Cacheを例に説明します。

      W3 Total Cacheは非常に多機能なプラグインで、様々なタイプのキャッシュに対応しています。
      詳しくは以前の投稿で解説したので参照してみてください。

      ページキャッシュについてはNginxのリバースプロキシで対応しているので、W3 Total Cacheでさらにキャッシュ化するメリットはありません。

      PHPのキャッシュについてはこのページで解説しているOPcacheを導入すれば十分で、さらにキャッシュ化するメリットはあまり無いと思います。
      もしプラグインでキャッシュ化する場合、それぞれ方法は異なりますがOPcache、プラグイン、リバースプロキシと三重にキャッシュすることになります。

      SQLの結果についてはW3 Total CacheのObject cacheという機能を利用すればキャッシュできますが、こちらも効果は限定的です。

      また、ブラウザキャッシュについてはNginxで設定しているのでプラグインで再度設定しても意味はありません。

      そもそもリバースプロキシで適切にキャッシュされたページを返している場合、PHPやSQLは実行されていないので全く効果はありません。
      WP Super CacheやW3 Total Cacheでキャッシュを有効にしてもGTMetrixはそれらの違いを判定に含めることはできないので効果は無いと思います。

      GTMetrixでスコアが振るわない原因は別のところにあると思われます。
      もし良かったらコメント欄か、フォームにてサイトのURLか結果の画像を教えていただければ原因がわかるかもしれません。

      ちなみにwordpress-wp-super-cache.confやwordpress-w3-total-cache.confをコメントアウトした場合は、
      「/etc/nginx/global/」に対応する設定ファイルを追加する必要があります。
      それぞれの設定ファイルについてはCodexにサンプルがあるので参照してみてください。
      http://wpdocs.sourceforge.jp/Nginx#W3_Total_Cache_Rules

  3. 岡田 のコメント:

    大変わかりやすく長い解説、まことに感謝しております。

    WordPressにあまりプラグインを増やしたくなかったので、
    この記事通りの設定で決めたいと思います。

    成人向けコンテンツを多く取り扱うサイトなので、大変お見苦しいかと思われますので、
    僕のWEBサイトはお見せできません。

    ちなみにGoogleCloudComputeのg1-small(vCPU 1 個、メモリ 1.7 GB)を使っています。

    • oxy のコメント:

      成人向けコンテンツは私もお世話になるので別に見苦しいとは思いませんw

      これは想像でしかありませんが、画像の圧縮率が低いとスコアが伸びません。
      以前の投稿」で画像を圧縮するソフトを紹介したので、良かったら試してみてください。

  4. 岡田 のコメント:

    こんばんは、このたびは多々お世話になっております。
    上記の質問とはちょっと違うのですが、サーバ接続が不安定なのを
    検診していただきたいとご連絡いたしました。

    この記事の通りにNginxの設定をしてあります。

    サーバの調子が不安定なのか、
    DNS関連の設定で何か間違っているところがあるのか
    わかりませんが、接続できる時とできない時があります。

    キャッシュを削除して1時間位待つと、たまに接続できる時がありますが、
    また1時間くらいすると見れなくなります。
    しかし、Apacheなどでも同じ症状なのでキャッシュは関係ないかもしれません。

    環境
    CentOS7
    Nginx1.7.10
    MariaDB10
    PHP5.6.5

    今GoogleCloudComputeの無料期間なので、4回ほど新しく作りなおしているんですが
    やっぱり繋がらなくなる時があります。

    ちなみにBINDというDNS関連設定は行っておりません。
    GoogleColudDNSからネームサーバを設定しただけです。
    SELinuxやFirewallは停止済みです。

    よろしくお願いします。

    • oxy のコメント:

      試しに外部からnslookupとdigコマンドで調べてみましたが、設定は正しくされていると思います。
      考えられるのはDNSへの登録から伝播まで1週間程度はかかるので、名前の解決ができないのかもしれません。この場合は安定するまで数日待ってみるしかありません。

      nginxが原因の場合は、ログを見れば原因が判明するかもしれません。
      このページと同じ設定なら「/var/log/nginx/error.log」もしくは「/var/log/nginx/example.com_error.log」にログがあるはずです。

      Googleのサービスを利用しているとのことなので、連続したサーバの不調は考えにくいですね。
      単純にメモリ等のリソースが足りずOOM Killerが起きている可能性もあるのでdstat等でメモリを圧迫しているソフトが無いか調べてみてください。
      http://oxynotes.com/?p=7566

      サーバ自体が不安定の場合は原因をFluentd等を利用して連続したサーバの状態を調べてみてください。
      http://oxynotes.com/?p=7596

      個人的にはOOM Killerの可能性が高いと思います。
      phpfpmの「pm.max_children = 15」等の設定を「5」に変更するなど調整してみてください。

  5. 岡田 のコメント:

    早期回答ありがとうございます。
    このたびは大変お役立ちさせていただき、まことに感謝しております。

    前回のコメントを送ってからは結構安定しています、何もいじっていません。
    とくに、GoogleSpeedで図ると7割くらいでスマホ、もしくはPCのサイト表示エラーがでてたんですが、今は100%完全に解析できています。

    ErrorログからはPermission denidなどの表示はありましたが、解決済みです。

    仰るとおり、DNSの登録から伝播まで一週間というのが今回の原因だったのかもしれません。
    何度も何度もお名前.comでネームサーバ変更やRebootを繰り返していたのです。

    ちなみにAWSも使用していたのですが、その時は今回のようなことは一度もありませんでした。
    やはりドメインだったのかもしれません。

    http://www.confのpm.max_childrenとspareの方を『5』に設定しました。
    後ほどDstatで色々確認していきたいと思います。

    よろしければ、Bind設定やiptablesの設定もやってみたいと思っているんですが、それほど重要でしょうか?
    とくに海外の国ごとにIP拒否などはかなり必需かと思うのですが、不要でしょうか?

    よろしければ、今後共色々教訓いただきたいのですが
    差し支えなければ、コンタクトを希望いたします。よろしくお願いします。

    (メールアドレスは削除しました:管理人)
    岡田 24歳
    HTML、CSS、Java、PHP、C#
    ほんの少しですが、Androidアプリを開発していました。

  6. 岡田 のコメント:

    重ねて質問すみません。
    教えていただいたdstat-top–oomをするとmysqld 61と連続で表示されます。

    お世話になっております岡田です。

    いろいろ調べてそのプロセスの順位を下げると
    今度はtuned 18と表示されるようになりました。
    サイトのアクセス状況は変わりませんでした。

    また、再起動して今コメントを書いている現在では
    mysqld 60と表示されているにもかかわらず、
    Chromeで当サイトが閲覧できる状態になっています。

    また、昨日はChromeとIEではキュッシュ削除更新しても何をしても繋がらなかったんですが
    Torだけ表示できました。HTMLの編集がしたかったのでTorで管理画面にもいけました。

    もし、こうではないかなど、おわかりいただける範囲があった場合のみでぜひ返信をお願いします。
    失礼します。

    • oxy のコメント:

      BINDは重要ですが、GoogleColudDNSを利用しているなら今のところ設定する必要はありません。

      iptablesは外部に開かれたサーバの場合、設定は必須と言えます。
      失礼ながら試しにポートスキャンさせていただいたところ、22と80しか開いてないようなので、即問題になるような状態ではないですが、やはり設定しておいたほうがいいと思います。

      dstat-top–oomですが、「mysqld 61」という表記はOOM Killerが起きた際に最優先で停止されるプロセスと優先度を表したもので、プロセスが殺されたことを示すものではありません。OOM Killerが実際に起きているかは「cat /var/log/messages | grep Killed」というコマンドで調べることができます。

      またTorで接続できたということは、nginx等は正常に動作しているものと思われます。
      恐らく、iptablesで一定のアクセスをするとブロックされる仕組みがデフォルトで設定されているのかもしれません。ハッシュリミットや、リミットモジュールを利用して設定します。
      他にもswatchでログを監視してブロックする仕組み等も考えられます。このへんのセキュリティ対策は無数に考えられるため、Googleのサーバの仕様を確認する以外に無いと思います。

      Torで接続できるということなので、個人的にはiptablesが原因の可能性が高いと思います。
      拙い記事ですが、このブログでもiptablesについての記事があるので、良かったら参照してください。
      http://oxynotes.com/?p=6401

  7. 岡田 のコメント:

    何をやっても駄目でした、サーバの勉強が足りない自分が悪かったです。諦めました。
    しかし、たくさんの知識を教えていただきありがとうございました!

    • oxy のコメント:

      駄目でしたか。
      サーバの設定はトライ・アンド・エラーの連続なので、地道にコツコツ失敗してみてくださいw

      エルピーアイジャパンでサーバ構築に関して全体的にざっくり俯瞰したドキュメントを公開しています。
      ユーザー登録すれば無料で閲覧できるので一読しておくと役に立つかもしれません。
      http://www.lpi.or.jp/linuxtext/server.shtml

      ではまた。

  8. 岡田 のコメント:

    ご無沙汰しております、岡田です
    この度は多大なる説明、回答をまことにありがとうございました。
    上記コメントの後も2度位試しましたがやはりダメで、
    その1ヶ月後の今、久々に手を付けてみると、
    ドメイン無しのIPアドレスで運営していたところ、ここ1週間まったく問題無い状態です。

    ドメイン系で何かあったのかもしれません。お名前.comは危なかったのかもしれません。

    • oxy のコメント:

      IPでは問題無いとのこと、とりあえず、おめでとうございます。
      2度試してダメだったということは、単なる記述ミスではなく、設定が誤っていると考えたほうが良さそうですね。
      DNS関係は特殊な記述のオンパレードなので、ドット1つで全く異なる設定になってしまいます。
      ネットでは設定例は多くありますが、意外と体系的にまとまったサイトは少ないため、書籍で学ぶのがお勧めです。

  9. linux入門者 のコメント:

    お世話になります。
    「リバースプロキシとログファイル用のディレクトリの作成と所有権の変更」で
    mkdir /var/lib/nginx とすると
    mkdir: cannot create directory `/var/lib/nginx’: Permission denied
     とメッセージがでます。基本的な部分で申し訳ありませんがどう対応すればよいでしょうか?
    他のディレクトリは作成できました。

    • oxy のコメント:

      エラーが出た時は、エラーメッセージを翻訳すると解決策がわかります。

      cannot create directoryはディレクトリが作成できません。
      Permission deniedは許可の拒否という意味です。

      つまりディレクトリを作成する権限が無いユーザーで作成しようとしているということです。
      rootユーザーにスイッチしてディレクトリを作成してみてください。

  10. linux入門者 のコメント:

    ありがとうございました。
    rootで出来ました。
    あとひとつ、vi /etc/php.ini にて
    ;php_admin_value[memory_limit] = 128M
    を修正したいのですが記述が見つかりません。

    • oxy のコメント:

      説明不足でしたね。失礼しました。

      追記したとおり/etc/php.iniではなく、以下のファイルを開いて設定してください。
      # vi /etc/php-fpm.d/www.conf

  11. linux入門者 のコメント:

    何度も申し訳ありません
    pecl install zendopcache-beta とすると
    WARNING: channel “pecl.php.net” has updated its protocols, use “pecl channel-update pecl.php.net” to update
    downloading zendopcache-7.0.5.tgz …
    Starting to download zendopcache-7.0.5.tgz (97,101 bytes)
    …………………done: 97,101 bytes
    35 source files, building
    running: phpize
    sh: phpize: command not found
    ERROR: `phpize’ failed
    というようにエラーがでてしまいます。どうしたらよいでしょう??

    • oxy のコメント:

      「sh: phpize: command not found」とあるようにphpizeが足りないようです。
      「command not found」はコマンドが足りないというメッセージです。
      以下のコマンドでphp-develをインストールして再度実行してみてください。

      # yum install php-devel

      上のコメントにある通り、エラーメッセージを読む癖を付けてください。
      または、エラーメッセージで検索してみてください。殆どの場合、エラーの解決法は既にネットにあります。

  12. linux入門者 のコメント:

    度々申し訳ありません。
    OPcacheがうまくインストールできません。
    PHPのバージョンが5.3.3 というのが原因(5.4以上)と思い、
    5.4にアップグレードを試みてますが、うまく行きません。
    5.3を削除して5.4をインストールするのでしょうか?

  13. linux入門者 のコメント:

    ご指摘の方法を試しましたがうまくいかず、5.3を削除したら5.4.40をインストールできました。
    OPcache 7.0.6もインストールできました。
    ありがとうございました。

    • oxy のコメント:

      正しくインストールできたということで、おめでとうございます。
      このサイトの手順と違って別の依存関係にあったソフトが入っていたのかもしれませんね。

  14. baron のコメント:

    はじめまして。
    WordPressを設置するVPSを初めて構築するにあたり
    大変参考になりました。

    こちらで説明されている通り
    構築し、WordPressをインストールまで出来ました。

    ですが、
    WordPressのデザイン変更にあたり
    Nginxのキャッシュで苦労しており

    http://oxynotes.com/?p=8656
    を参考にngx_cache_purgeを組み込みました。

    その後
    nginx.confはこちらに記載されている内容を
    以下のように変更しました。

    server {
    listen 80;
    server_name mydomain;

    ## 中略 ##

    proxy_no_cache $do_not_cache;
    proxy_cache_bypass $do_not_cache;
    proxy_cache czone;

    # proxy_cache_key $scheme://$host$uri$is_args$args$mobile;
    proxy_cache_key $scheme://$host$uri$is_args$args;

    proxy_cache_valid 200 301 302 1d;
    proxy_cache_valid 404 5m;
    proxy_cache_use_stale error timeout invalid_header updating
    http_500 http_502 http_503 http_504;

    proxy_pass http://backend;

    proxy_redirect http://mydomain:8080/ /;
    } # location /

    location ~ /purge(/.*) {
    proxy_cache_purge czone “$scheme://$host$1$is_args$args”;
    }

    } # server 80

    http://mydomain/purge/

    一度目は、Succeccful purge と表示されキャシュは削除され
    html、CSSの変更も即反映しましたが

    再度、html、CSSを変更後 キャッシュを削除しようと
    http://mydomain/purge/ にアクセスしても404 Not Found となります。

    その場合でも、キャッシュは残ったままで反映には時間がかかってしまいます。

    /var/cache/nginx 以下をrmすれば即反映するので
    キャッシュ自体は作成されているようなのですが
    location ~ /purge(/.*) { proxy_cache_purge czone “$scheme://$host$1$is_args$args”;}
    という記述が間違っているのでしょうか?

    http://mydomain/purge/~ で特定ページのキャッシュを削除するにはどうすればいいでしょうか?

    よろしくお願いいたします。

    • oxy のコメント:

      はじめましてbaronさん
      Succeccful purgeと出て一度は消えているということなので、ngx_cache_purgeの設定は正しいと思います。

      1点確認なのですが、http://example.com/purge/で消えるアドレスはhttp://example.com/だけです。
      http://example.com/hogeのキャッシュを消す場合は、http://example.com/purge/hogeと入力する必要があります。

      また、nginxのリバースプロキシによるキャッシュは削除できても、WordPressのキャッシュ系プラグインのキャッシュが残っていることも考えられます。もしキャッシュ系プラグインが有効な場合は無効にしてみてください。

      他にもこのページの設定例で紹介したOPcacheによるキャッシュが帰ってきている可能性もあります。
      検証時にはキャッシュが煩わしいということであれば、一時的に無効にしてphp-fpmを再起動してみてください。

  15. baron のコメント:

    こんな夜分に迅速な返信ありがとうございます。

    >>http://example.com/purge/で消えるアドレスはhttp://example.com/だけです。
    http://example.com/hogeのキャッシュを消す場合は、http://example.com/purge/hogeと入力する必要があります。

    の点は大丈夫です。

    例えば、http://example.com/purge/ で一度目削除した後

    もう一度、 http://example.com/purge/ では404 ですが

    http://example.com/purge/2015/06 を実行するとSucceccful purge と表示されます。
    もちろんキャッシュが削除されるのはhttp://example.com/2015/06のページだけとなりますが。

    キャッシュ系のプラグインも一度、すべて停止してみましたが
    2度目以降は、 http://example.com/purge/ 404が返ってきます。

    Nginx Proxy Cache Purgeというプラグインを導入しているので
    新規投稿時に自動でキャッシュを削除するようで
    htmlは、新規投稿時に削除されているようですが
    CSSのキャッシュは削除されないようです。

    疑問に思うのは、どのページに対しても1度めはSucceccful purgeとなりますが
    2度目以降、404になるという点です。

    これは、キャッシュを一度、purgeすると
    2度目以降、キャッシュの保存先が変わってしまっているのでしょうか?

    • oxy のコメント:

      リバースプロキシのキャッシュのパスはproxy_cache_keyとproxy_cache_pathの項目を変えない限り、同じアドレスに関しては保存場所は固定です。(アドレスをmd5で暗号化してディレクトリやファイルのパスにしています)

      もう1点確認なのですが、WordPressのユーザーでログインして閲覧してないでしょうか?
      上記の設定ではログイン時はキャッシュしない設定になっているので、ログインユーザーで閲覧時にはキャッシュは作成されません。
      ChromeであればControl + shift + N等のショートカットで匿名ユーザーとしてアクセスできるので試してみてください。

  16. baron のコメント:

    ご丁寧にありがとうございます。

    proxy_cache_keyとproxy_cache_pathに関してはこちらのページでご紹介頂いたまま設定しております。

    WordPressのユーザーでログイン状態では
    キャッシュされていないようで、デザイン変更後に即反映いたしますが、

    別のブラウザでログアウト状態では、反映しないのです。

    html自体は、
    proxy_cache_valid 200 301 302 1d; の部分を一時的に
    proxy_cache_valid 200 301 302 1m; にすればそこまで煩わしくないのですが
    CSSのキャッシュが残ってしまいます。

    これは、/etc/nginx/global/wordpress.confの

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
    expires 7h;
    log_not_found off;
    }

    が関係してるのでしょうか?

    • oxy のコメント:

      expiresはファイルの作成日と有効期限(設定ファイルの場合は7日)をアクセスするごとに照合しているため、ファイルを更新してブラウザ側でF5をクリックすれば正しく更新されます。
      このへんの動作と、確認方法については「http://oxynotes.com/?p=7176」でまとめたので、良かったら参照してみてください。
      もしレスポンスヘッダで304 Not Modifiedが帰ってきていて、Expiresの日時が古いままならキャッシュが帰ってきているため、正しくキャッシュは消えていません。

      また、うろ覚えですが、たしかサーバ側の時間の設定が正しくできていないとexpiresヘッダの付いたファイルが正しく更新されない不具合もあったはずです。その辺の環境も調べてみてください。

      もう一度確認なのですが、CSSのキャッシュは削除されていますか?
      例)http://example.com/purge/wp-content/themes/style.css

      nginxのリバースプロキシはhtmlだけでなく、画像やCSSファイルもキャッシュするため、即座に変更を反映させるにはCSSも合わせて削除する必要があります。

      どちらにしてもファイルに変更を加えて即座に全体に反映させるには、一旦キャッシュを無効にするか(もしくは極端に短くするか)、キャッシュディレクトリのファイルを削除するのが手っ取り早い方法です。

  17. baron のコメント:

    ご丁寧にありがとうございます。

    時系列でまとめますと、

    1.http://example.com/purge/ → Succeccful purge
    2.http://example.com/purge/ → 404 404 Not Found
    3.http://example.com/archive/purge/ → Succeccful purge
    4.http://example.com/archive/purge/ → 404 404 Not Found
    5.http://example.com/purge/wp-content/themes/style.css → Succeccful purge
    6.http://example.com/purge/wp-content/themes/style.css → 404 404 Not Found

    なっておりましたので、ここで proxy_cache_valid 200 301 302 1m;に変更
    7.http://example.com/purge/ → 404 404 Not Found

    この時点でこちらに質問させて頂きました。

    そこで、再度
    8.http://example.com/purge/ → 404 404 Not Found
    9.http://example.com/archive/purge/ → 404 404 Not Found
    10.http://example.com/purge/wp-content/themes/style.css → Succeccful purge
    となりました。

    再度、CSS変更後
    11.http://example.com/purge/ → 404 404 Not Found
    12.http://example.com/archive/purge/ → 404 404 Not Found
    13.http://example.com/purge/wp-content/themes/style.css → 404 404 Not Found
    となるようです。

    現在は、
    nginx.conf を proxy_cache_valid 200 301 302 1m;
    wordpress.conf を
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
    expires 1m;
    log_not_found off;
    }
    で様子を見ていますが
    html、CSSともに変更後すぐに反映しています。

    サイトの構築が終われば
    nginx.conf を proxy_cache_valid 200 301 302 1d;
    wordpress.conf を
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
    expires 7h;
    log_not_found off;
    }
    というのが現実的な気がします。

    何度も質問にお答え頂きありがとうございました。

    • oxy のコメント:

      詳細な検証お疲れ様です。

      expiresの設定が原因で反映が遅れることは通常考えにくいですが、何か特殊な状況があるのかもしれませんね。
      ブラウザのバグや、キャッシュ削除後に何らかのアクセスがあって再びCSSのキャッシュが作成された、など。CSSは共通なので別ページヘのアクセスがあった場合でも作成されてしまいます。

      昨夜の質問を頂いた時点ですっかり酔いが回っていたので失念していましたが、
      nginxのキャッシュがヒットしているかどうかを判定することができるように設定ファイルに以下の記述をしていたのを忘れていました。
      add_header X-Cache $upstream_cache_status;

      これはレスポンスヘッダにNginxのキャッシュの状況を書き出してくれる設定です。
      キャッシュにヒットすると「X-Cache:HIT」、
      キャッシュにヒットしないと「X-Cache:MISS」
      ログインユーザーなどでキャッシュはあっても利用していない場合は「X-Cache:BYPASS」となります。

      キャッシュを削除してもCSSファイルが変更されていなければexpiresで設定した期間はブラウザキャッシュを利用します。「Status Code:304 Not Modified」の状態です。
      しかしCSSが変更されていれば、変更点は即座に反映されるはずです。「Status Code:200 OK」となる。
      またCSSの更新日時もブラウザキャッシュなのか、新しくアップロードしたものかの参考になります。

      もしまた同じような状況になったら何が原因で反映がされていないかを判断する際に参考にしてみてください。

      どちらにしてもキャッシュは多用するとレイテンシが発生するので、ローカルでしっかりと検証した後にサーバにアップロードして、キャッシュをクリアするのが現実的だと思います。

  18. baron のコメント:

    以前にNginxの設定について質問しましたbaronです。

    Nginxのrewriteのことでわからないことがあるので質問したいのですが

    WordPressでメディアライブラリから画像を削除した際に
    別画像を表示させたいのです。

    Apacheで運用していた時は
    以下のhtaccessを /wp-content/uploads に設置しておりました。

    RewriteEngine On

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} (.*)\.(gif|jpg|png|jpeg)
    RewriteRule ^.*$ default.png [L]

    このような環境をNginxで実装するために

    nginx.confに

    location ~ /wp-content/uploads(/.*) {
    if (!-e $request_filename){
    rewrite ^(.*)$ default.png redirect;
    }
    }

    と記載してみましたが
    削除していない画像も含め uploads ディレクトリの画像全てが
    default.pngに変わってしまいました。

    他にも

    location ~ /wp-content/uploads(/.*) {
    error_page 404 = @noimg;
    access_log off;
    log_not_found off;
    }

    location @noimg {
    rewrite ^(.*)$ default.png redirect;
    access_log off;
    log_not_found off;
    }

    location ~ /wp-content/uploads {
    try_files $uri ~ default.png;
    }

    なども試してみましたが
    いずれも、全ての画像がdefault.png に入れ替わってしまいます。

    Nginxで削除された画像がリクエストされた場合に
    別画像を表示させるにはどうしたらいいのでしょうか?

    • oxy のコメント:

      baronさん、お久しぶりです。
      その後、トラブル無く動作していますか?

      ご質問の件ですが、
      serverディレクティブのlistenが80(つまりバックグラウンドではない方です)で、
      location /ディレクティブに以下の記述で動作すると思います。
      (default.pngが/wp-content/uploads/にある場合)

      location ~ /wp-content/uploads/.+\.(gif|jpg|png|jpeg) {
      	try_files $uri /wp-content/uploads/default.png;
      }
      
  19. bron のコメント:

    返信ありがとうございます。
    覚えていていただき光栄です。

    早速、教えていた来ましたコードを試しましたが
    やはり、uploads ディレクトリにあるすべての画像がdefault.pngに変わってしまいます。

    location ~* /wp-content/uploads/.*\.(gif|jpg|jpeg|png)$ {
    try_files $uri /inc/no-img.png;
    }

    また、別のNginxサーバー(自分で構築したのではないので詳しい設定状況は不明です)で
    上記のコードを試したところうまく作動したのですが
    同じコードを自分が構築したNginxサーバーで試したことろ
    やはり、すべての画像が入れ替わってしまいました。

    これらの状況から考えますとNginx以外の要因でこのような現象が起こってるのでしょうか?
    Nginxの設定を含めて
    php,MySQL,phpmyadmin,php-fpm,OPcacheの設定はこちらでご説明があったとおりの設定となっております。

  20. baron のコメント:

    ありがとうございます。
    自己解決?致しましたので報告します。

    listen 80のドキュメントルートの設定を
    location / { の外に

    server {
    listen 80;
    server_name example.com;

    root /var/www/html/example; # ドキュメントルート
    index index.html index.htm index.php; # indexの設定

    access_log /var/log/nginx/example.com_access.log main;
    error_log /var/log/nginx/example.com_error.log warn;

    中略

    # サーバ全般の指定
    location / {

    # モバイル、スマホ、ログイン画面、それぞれフラグを付け
    # キャッシュの挙動を変える
    # ※モバイル用はサイトを分けていないのでキャッシュの振り分けは不採用

    中略

    として

    location ~* /wp-content/uploads/.*\.(gif|jpg|jpeg|png)$ {
    try_files $uri /inc/no-img.png;
    }
    } # server 80

    で無事作動いたしました。

    ですが
    root /var/www/html/example; # ドキュメントルート
    index index.html index.htm index.php; # indexの設定

    この2行の書き順を変えただけでなぜ作動するようになったのかはわかりませんので自己解決と言えるか微妙ですが…

    追加で質問があるのですが
    WordPress Popular Postsのようなプラグインを導入しておりますが
    これには、プレビュー数が表示されおりますが
    Nginxの場合、キャッシュの関係で正確に計測できるのでしょうか?

    • oxy のコメント:

      baronさん

      過去のNginxではドキュメントルートの設定をlocation内に記述していましたが、現行ではlocation内にドキュメントルートの設定を書くのは誤りです。バックエンドサーバ用の設定も修正しておいてください。(現状どちらでも問題なく動作するので、今でも誤った解説が散見される状態です)
      このサーバを設定する際は直していたのですが、少し特殊な設定にしているため、古いメモから解説を作成したのですが、修正するのを忘れたようです。失礼しました。

      個人的にはそれが原因でtry_filesが動作しないことは考えにくいのですが(テストを行い、どちらでも動作することを確認しました)、もしかしたらnginxのバージョンの違いなどにより不具合が出たのかもしれません(テスト環境は1.6.2です。最新の2系を使われているようなら、そのせいかもしれません)。

      WordPress Popular Postsについてですが、カウントはPHPとMySQLで行われるため、キャッシュ化されていても問題なくカウントされます。
      ただ、Nginxのキャッシュが更新されるまでPVは反映されません。リアルタイムにカウントしたい場合はキャッシュの有効期限を5分など、短めにすることをお勧めします。

linux入門者 へ返信する コメントをキャンセル

コメントは認証制のため、すぐには反映されません。

プログラミングに関する質問は「日本語でプログラミングの悩みを解決するQ&Aサイト sukegra」をご利用ください。