Wordpress を Nginx + Fast-cgi で動かす

# 要件
・OSはCentOS 6.x を想定
・WordpressをNginxで動かす
・Wordpressのインストールディレクトリは`/var/www/vhosts/hogehoge.com`とする
・NginxでWordpressのキャッシュ化を行い、高速化を図る
・Nginxはソースからのインストール
・PHP(Wordpress)はFast-CGIで実行し、Nginx　⇔　Fast-CGI間はUnixSocketで通信する

# Fast-cgi(spawn-fcgi OR php-fpm)の用意
## spawn-fcgi

### インストール
```rb:コマンド
yum install spawn-fcgi #要remiリポジトリ
chkconfig spawn-fcgi on
```

### 設定
```rb:/etc/sysconfig/spawn-fcgi
#UnixSocketで通信
OPTIONS="-u nginx -g nginx -S -s /tmp/php.socket -C 32 -F 1 -P /var/run/spawn-fcgi.pid -- /usr/bin/php-cgi"
#TCPで通信
OPTIONS="-u nginx -g nginx -S -p 9000 -C 32 -F 1 -P /var/run/spawn-fcgi.pid -- /usr/bin/php-cgi"
```

### spawn-fcgi の起動
```rb:コマンド
/etc/init.d/spawn-fcgi start
```

##php-fpm
###インストール
```rb:コマンド
yum install php-fpm
chkconfig php-fpm on
```

###php-fpm の設定
```rb:/etc/php-fpm.d/www.conf
# UnixSocketで通信
;listen = 127.0.0.1:9000
listen = /var/run/php-fpm/www.sock
#接続許可クライアントの設定
listen.allowed_clients = 127.0.0.1
#実行ユーザの変更 (Apache⇒Nginx)
;user = apache
user = nginx
;group = apache
group = nginx
```

###php-fpm の起動
```rb:コマンド
/etc/init.d/php-fpm start
```

#Nginx
## インストール準備
###必要モジュールのインストール
```rb:コマンド
 yum install pcre pcre-devel zlib zlib-devel openssl openssl-devel gcc
```
###nginxユーザ追加
```rb:コマンド
useradd -s/sbin/nologin -d/usr/local/nginx -M nginx
```
##ソースインストール
```rb:コマンド
#ダウンロードディレクトリへ移動
cd /usr/local/src
#ソースファイルのダウンロード
wget http://nginx.org/download/nginx-1.2.3.tar.gz
#展開
tar zxvf nginx-1.2.3.tar.gz
#展開先ディレクトリへ移動
cd nginx-1.2.3
#コンフィグ ⇒ make ⇒ インストール
./configure --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module && make && make install
```
## logrotateの設定
```rb:/etc/logrotated/nginx
/var/log/nginx/*log {
    missingok
    notifempty
    sharedscripts
    rotate 12
    weekly
    compress
    postrotate
        kill -USR1 `cat /var/run/nginx.pid`
    endscript
}
```
## 起動スクリプト
```bash:/etc/init.d/nginx
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15 
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid
 
# Source function library.
. /etc/rc.d/init.d/functions
 
# Source networking configuration.
. /etc/sysconfig/network
 
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)
 
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
 
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
 
lockfile=/var/lock/subsys/nginx
 
make_dirs() {
   # make required directories
   user=`$nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
   if [ -z "`grep $user /etc/passwd`" ]; then
       useradd -M -s /bin/nologin $user
   fi
   options=`$nginx -V 2>&1 | grep 'configure arguments:'`
   for opt in $options; do
       if [ `echo $opt | grep '.*-temp-path'` ]; then
           value=`echo $opt | cut -d "=" -f 2`
           if [ ! -d "$value" ]; then
               # echo "creating" $value
               mkdir -p $value && chown -R $user $value
           fi
       fi
   done
}
 
start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}
 
stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}
 
restart() {
    configtest || return $?
    stop
    sleep 1
    start
}
 
reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}
 
force_reload() {
    restart
}
 
configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}
 
rh_status() {
    status $prog
}
 
rh_status_q() {
    rh_status >/dev/null 2>&1
}
 
case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac
```
###パーミッションの変更
```bash:コマンド
chmod 755 /etc/init.d/nginx
```

## 参考設定
```nginx:/usr/local/nginx/conf
user  nginx;
# CPUコア数と同じ値が良いらしい。
# 容量の大きなファイルの配信や、静的ファイルの配信の場合はコア数の1.5~2倍が良いらしい。
worker_processes   8;

worker_rlimit_nofile    8192;

error_log   /var/log/nginx/error.log warn;

pid        /var/run/nginx.pid;


events {
    worker_connections   8192;
    use epoll;
    multi_accept off;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    server_tokens off;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;

    keepalive_timeout   0;

    gzip              on;
    gzip_http_version 1.0;
    gzip_types        text/plain 
                      text/xml 
                      text/css 
                      application/xml 
                      application/xhtml+xml 
                      application/rss+xml 
                      application/atom_xml 
                      application/javascript 
                      application/x-javascript 
                      application/x-httpd-php;
    gzip_disable      "MSIE [1-6]\.";
    gzip_disable      "Mozilla/4";
    gzip_comp_level   2;
    gzip_proxied      any;
    gzip_vary         on;
    gzip_buffers      4 8k;
    gzip_min_length   1100;

    proxy_cache_path  /var/cache/nginx levels=1:2 keys_zone=czone:100m max_size=500m inactive=7d;
    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;


    server {
        listen       80;
	server_name  hogehoge.com;
	rewrite      ^  http://www.hogehoge.com$request_uri?;
    }
 
    server {
        listen       80;
        server_name  www.hogehoge.com;

        charset      utf-8;

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

        error_page   404              /404.html;

        error_page   500 502 503 504  /50x.html;

        location / {
            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;
            }
            if ($http_cookie ~* "comment_author_[^=]*=([^%]+)%7C|wordpress_logged_in_[^=]*=([^%]+)%7C") {
                set $do_not_cache 1;
            }
            proxy_no_cache          $do_not_cache;
            proxy_cache_bypass      $do_not_cache;
            proxy_cache             czone;
            proxy_cache_key         "$scheme://$host$request_uri$is_args$args$mobile";
            proxy_cache_valid       200 301 302 3h;
            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://127.0.0.1:8080;
            proxy_redirect          off;

	    expires 7d;
	}

	location ~ .*\.(jpg|JPG|gif|GIF|png|PNG|swf|SWF|css|CSS|js|JS|inc|INC|ico|ICO) {
    	    root    /var/www/vhosts/www.hogehoge.com;
	    index  index.php index.html index.htm;
	    expires 7d;
        }

# ログイン/管理画面はキャッシュをさせない。

        location /cms/wp-admin {
            proxy_pass http://127.0.0.1:8080;
        }

        location /cms/wp-login.php {
            proxy_pass http://127.0.0.1:8080;
        }

    }


    server {
        listen       8080;
        server_name  hogehoge.com www.hogehoge.com;

        charset      utf-8;

        access_log   /var/log/nginx/hogehoge.com8080_access.log main;
        error_log     /var/log/nginx/hogehoge.com8080_error.log warn;

        location / {
            root   /var/www/vhosts/hogehoge.com;
            index  index.php index.html index.htm;

# Wordpressパーマリンク用の設定

            ### Permalink ###
            if (!-e $request_filename) {
                rewrite ^.+?($/wp-.*) $1 last;
                rewrite ^.+?(/.*\.php)$ $1 last;
                rewrite ^ /cms/index.php last;
            }
            ##### ##### #####
        }

        location ~ \.php$ {
             include /usr/local/nginx/conf/fastcgi_params;
             fastcgi_pass unix:/tmp/php.socket;
             fastcgi_index index.php;
             fastcgi_param SCRIPT_FILENAME /var/www/vhosts/hogehoge.com$fastcgi_script_name;
        }

        error_page  404               /404.html;

        error_page   500 502 503 504  /50x.html;
    }
}