さくらの VPS に nginx を入れてリバースプロキシ設定するまでの作業メモ(検証用)

さくらの VPS で CentOS 6.2 に nginx を入れてサーバーを作ります。今まで Apache を使ったサーバーしか作ったことがなくて、nginx も Apache と合わせて稼働させていたレベルだったので、今回初めて nginx オンリーのサーバーの構築です。ただ、この作業メモも検証用サーバーの域を脱しないので、後日本番で使えるレベルの記事を公開します。一応勉強した項目に参考サイトを細かく記載しているので、自分用に公開しておきます。

この記事で構築する環境

今回は下記のような WordPress や CakePHP で作った自作サイトなど様々な構造の Web サイトをしっかりと運営できるようなサーバーを構築していきます。

  • WordPress ベースの Web サイトをリバースプロキシで高速表示
  • CakePHP などで作ったキャッシュを必要としないサイトでも動かす
  • 様々なライブラリを使用して稼働していたサイトも動作させる



ちなみに WordPress はキャッシュしないとかなり重い(私のブログはこの記事を書いてる現在で1100記事あるので通常より遅いのかもしれない)ためリバースプロキシを使います。ただし、私が CakePHP で作った他サイトは、アプリ側の時点でキャッシュを取らなくても高速動作するように設計していますので、リバースプロキシは一切必要ありません。

その辺のリバースプロキシの微調整(Aサイトは必要ないがBサイトは必要あるなど)がどこまでできるかについても、私は知らないのでその辺の勉強もしていきます。

PHP のインストール

ちょうど先日 PHP で脆弱性が見つかったようですので、それに対応済みの PHP 5.3.13 をインストールすることにします。5.3.13 のインストールについては下記の記事が参考になりました。

1
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

自分が必要なものを入れるのですが、私の場合は下記のような感じです。もちろん後から必要になればいつでも追加することができます。

1
yum --enablerepo=remi install php-cli php-devel php-mbstring php-mysql php-pear

これで下記のように PHP 5.3.13 がインストールされました。ついでに古いパッケージも update されたようでスッキリです。

1
2
3
4
php -v
PHP 5.3.13 (cli) (built: May  9 2012 16:43:49) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies

APC のインストール

pecl でインストールしたいので pcre-devel をインストールします。

1
yum install pcre-devel

APC をインストールします。

1
pecl install APC

php.ini の末尾などに下記の記述をします。

1
extension=apc.so

ちなみに APC ではなく eAccelerator をインストールしたい方は以前こちらの記事でまとめていますのでご覧ください。ちなみに APC と eAccelerator のどちらが速いのか以下の記事で検証されていました。とても参考になったので紹介しておきます。

MySQL のインストール

MySQL をインストールします。

1
yum --enablerepo=remi install mysql mysql-server

/etc/my.cnf を下記のような感じで編集します。こちらもご自分の環境に合わせて変更してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1
 
# character-set
character-set-server=utf8
skip-character-set-client-handshake
 
ft_min_word_len=1
 
# Disabling symbolic-links is recommended to prevent assorted security risks;
# to do so, uncomment this line:
# symbolic-links=0
 
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
 
[client]
default-character-set=utf8
 
[mysql]
default-character-set=utf8
 
[mysqldump]
default-character-set=utf8

MySQL 自動起動設定・初期化・ root パスワード設定。

1
2
3
/sbin/chkconfig mysqld on
/etc/rc.d/init.d/mysqld start
mysqladmin -u root password 'パスワード'

nginx のインストール

yum で nginx をインストールします。

1
yum --enablerepo=remi install nginx

nginx の設定をします。

1
vi /etc/nginx/conf.d/virtual.conf

静的なファイルを表示するだけなら以下のような感じで良いです。

1
2
3
4
5
6
7
8
9
server {
    listen       80;
    server_name  example.com;
 
    location / {
        root   /var/www/vhosts/example.com;
        index  index.html index.htm;
    }
}

nginx が自動起動するように設定します。

1
/sbin/chkconfig nginx on

nginx を起動します。

1
/etc/init.d/nginx start

FastCGI を使えるようにする

nginx で PHP が使えるようにします。ちなみに PHP を動作させるにあたって FastCGI を使うんですけど、それを管理するのに spawn-fcgi を使うか php-fpm を使うかの2種類を試しましたので、どちらも公開させて頂きます。php-fpm の方が設定が楽です。

PHP を使えるようにする php-fpm 版

php-fpm をインストールする。

1
sudo yum --enablerepo=remi install php-fpm

自動起動設定をする。

1
sudo /sbin/chkconfig php-fpm on

php-fpm を起動する。

1
sudo /etc/init.d/php-fpm start

php-fpm をチューニングします。

1
sudo vi /etc/php-fpm.d/www.conf

以下のような感じで設定しておきます。これからサイト運用して少しずつ調整していこうと思っています。この部分は下記ページを参考にしました。

1
2
3
4
5
6
pm = dynamic
pm.mac_children = 10
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500

設定が完了したら反映させます。

1
sudo /etc/init.d/php-fpm restart

php-fpm に関しては下記ページを参考にさせて頂きました。

PHP を使えるようにする spawn-fcgi 版

spawn-fcgi をインストールします。

1
yum install spawn-fcgi

php-fastcgi を作成します。

1
vi /etc/rc.d/init.d/php-fastcgi

下記のようなファイルを作成します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/bin/sh
#
# spawn-fcgi   Start and stop FastCGI processes
#
# chkconfig:   - 80 20
# description: Spawn FastCGI scripts to be used by web servers
 
# Source function library.
. /etc/rc.d/init.d/functions
 
RETVAL=0
SPAWNFCGI="/usr/bin/spawn-fcgi"
PHPFCGI="/usr/bin/php-cgi"
FCGIPORT="9000"
FCGIADDR="127.0.0.1"
PHP_FCGI_CHILDREN=5
PHP_FCGI_MAX_REQUESTS=1000
ALLOWED_ENV="PATH USER"
USER=apache
GROUP=apache
PIDFILE=/var/run/phpfcgi.pid
 
ALLOWED_ENV="$ALLOWED_ENV PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS FCGI_WEB_SERVER_ADDRS"
 
case "$1" in
  start)
        PHPFCGI_START=$"Starting ${NAME} service: "
        echo -n $PHPFCGI_START
 
        # clean environment
        E=
        for i in $ALLOWED_ENV; do E="$E $i=${!i}"; done
        daemon $SPAWNFCGI -a ${FCGIADDR} -p ${FCGIPORT} -u ${USER} -g ${GROUP} -P ${PIDFILE} -C ${PHP_FCGI_CHILDREN} -f ${PHPFCGI}
        RETVAL=$?
        ;;
  stop)
        echo -n "Stopping php-fcgi: "
        killproc -p $PIDFILE phpfcgi
        echo
        RETVAL=$?
        ;;
  *)
        echo "Usage: $0 {start|stop}"
        exit 1
esac
exit $RETVAL

php-fastcgi を自動起動できるように設定。

1
2
3
4
chmod 755 /etc/rc.d/init.d/php-fastcgi
/sbin/chkconfig --add php-fastcgi
/sbin/chkconfig php-fastcgi on
/sbin/service php-fastcgi start

以上の設定やコードは下記のページを参考にしました。

PHP が動くように nginx を設定する

以上で FastCGI が使えるようになりましたので、PHP ファイルについては FastCGI に処理してもらえるように設定しましょう。下記のファイルに設定を書きます。

1
sudo vi /etc/nginx/conf.d/virtual.conf

下記は WordPress を動かす場合のサンプルです。ファイルが存在すれば(例えば画像ファイルなどです)普通にファイルを表示して終了(break の所)、存在しなければ index.php に処理を投げて終了せず、その下の設定(location ~ \.php の部分)で FastCGI に処理をお願いする感じです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
server {
 
    listen      80;
    server_name example.com;
    root        /var/www/vhosts/example.com;
    access_log  /var/log/nginx/example.com/access.log   main;
    error_log   /var/log/nginx/example.com/error.log;
    client_max_body_size 36M;
 
    location / {
        index  index.php index.html index.htm;
        # static files
        if (-f $request_filename) {
            expires 14d;
            break;
        }
        # request to index.php
        if (!-e $request_filename) {
            rewrite ^(.+)$  /index.php?q=$1 last;
        }
    }
 
    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME  /var/www/vhosts/example.com/$fastcgi_script_name;
        include        fastcgi_params;
    }
 
    location ~ (\.ht|\.git|\.svn) {
        deny  all;
    }
 
}

一番下にある .ht とかっていうのは .htaccess や .htpasswd などのファイルへのアクセスを無効化しています。今まで .htaccess でアクセス制限をかけていたファイルなどがあれば、ここに全て書き込むようにしましょう。

ちなみに補足ですが、nginx では .htaccess が使えないので、.htaccess で行なっていた処理は全て virtual.conf で設定するようにします。そのため、nginx でも WordPress Super Cache を使うことはできるのですが、.htaccess を使ったファイルへの直接アクセスはできないため、レガシーキャッシュを使う感じになります。ただ、WordPress のキャッシュについては nginx のリバースプロキシを使う方法がありますので、下記で紹介していきます。

nginx のリバースプロキシでキャッシュする

nginx には強力なキャッシュ機能があります。WordPress のような PHP で動いてるけどコンテンツ内容は静的な場合は、リバースプロキシでキャッシュをするのが良いです。

リバースプロキシの仕組み

仕組みとしては 80 番ポートでアクセスを受けていたけど、それを 8080 番ポートで受けるように変更します。その上で 80 番ポートをリバースプロキシにして(Web サーバまでの間にプロキシサーバーを挟む感じ)キャッシュを実装します。80 番ポートはキャッシュがあればキャッシュを返し、キャッシュが無ければ 8080 番の Web サーバにアクセスさせるという流れです。

リバースプロキシを使う

まず、/etc/nginx/nginx.conf を編集します。

1
sudo vi /etc/nginx/nginx.conf

以下のように設定をします。キャッシュ以外の部分も載せておきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
 
    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;
    #tcp_nopush     on;
 
    #keepalive_timeout  0;
    keepalive_timeout   30;
 
    # gzip圧縮
    gzip  on;
    gzip_http_version 1.0;
    gzip_vary         on;
    gzip_comp_level   6;
    gzip_types        text/xml text/css application/xhtml+xml application/xml application/rss+xml application/atom_xml application/x-javascript application/x-httpd-php;
    gzip_disable      "MSIE [1-6]\.";
 
    # リバースプロキシの設定
    proxy_cache_path  /var/cache/nginx levels=1:2 keys_zone=czone:4m max_size=50m inactive=120m;
    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;
 
    upstream backend {
        ip_hash;
        server 127.0.0.1:8080;
    }
 
    # Load config files from the /etc/nginx/conf.d directory
    # The default server is in conf.d/default.conf
    include /etc/nginx/conf.d/*.conf;
 
}

次に /etc/nginx/conf.d/virtual.conf を編集します。

1
sudo vi /etc/nginx/conf.d/virtual.conf

下記のように設定していきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
server {
 
    listen      80;
    server_name example.com;
    root        /var/www/vhosts/example.com/www;
    access_log  /var/log/nginx/example.com/access.log   main;
    error_log   /var/log/nginx/example.com/error.log;
    client_max_body_size 36M;
 
    location /wp-admin { proxy_pass http://backend; }
    location ~ .*\.php { proxy_pass http://backend; }
    location / {
        set $mobile "";
        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 "@ktai";
        }
        if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry)') {
            set $mobile "@mobile";
        }
        if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
            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 60m;
        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/ /;
    }
}
 
server {
 
    listen      8080;
    server_name example.com;
    root        /var/www/vhosts/example.com/www;
    access_log  /var/log/nginx/example.com/access.log   main;
    error_log   /var/log/nginx/example.com/error.log;
    client_max_body_size 36M;
 
    location / {
        index  index.php index.html index.htm;
        # static files
        if (-f $request_filename) {
            expires 14d;
            break;
        }
        # request to index.php
        if (!-e $request_filename) {
            rewrite ^(.+)$  /index.php?q=$1 last;
        }
    }
 
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ \.php$ {
        include        fastcgi_params;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME  /var/www/vhosts/example.com/www/$fastcgi_script_name;
    }
}

キャッシュの有効期限を設定する

以下の設定はステータスコード 200、301、302 の場合は60分間キャッシュを保持するってことです。60分経てばキャッシュを作りなおすという感じです。

1
2
proxy_cache_valid  200 301 302 60m;
proxy_cache_valid  404 5m;

キャッシュを削除できるようにする

nginx ではデフォルトでキャッシュを削除することができませんので、ngx_cache_purge モジュールを入れてキャッシュを削除することができるようにします。

ngx_cache_purge をインストールする

FRiCKLE Labs から ngx_cache_purge の最新版をダウンロードして作業をします。これを入れた後で、WordPress の場合はプラグイン Nginx Proxy Cache Purge で簡単にキャシュを削除することができます。

ちょっとコンパイルし直さなきゃいけないので、この辺は別記事でまとめておきます。60分でキャッシュが再生成されるので、60分待てば良い話ですしね。

参考サイトや技術メモ

nginx と Apache の違いを物凄く詳しく解説

nginx と Apache の違いを物凄く詳しく解説されている部分が個人的にはとても勉強になりました。図もとても参考になります。この辺をまだご存知ない方は一度目を通してみてください。

さくらの VPS がディスクをマウントしなくて良くなってた

さくらの VPS 4G とかでは HDD がバラバラだったのですが、最近のさくらの VPS はいちいちマウントしなくても良くなったようです。

1
2
3
4
Filesystem            Size  Used Avail Use% マウント位置
/dev/vda3             195G  1.8G  184G   1% /
tmpfs                1004M     0 1004M   0% /dev/shm
/dev/vda1             251M   53M  186M  23% /boot

まとめ

以上な感じです。初回から綺麗に構築することはできないようで、色々後から必要なものが発覚したりとぐだぐだ。終いには nginx にキャッシュ削除のモジュール入れるためにコンパイルし直す必要があったりで、もっと事前に情報を探っておくべきでした。

コメント

コメントは受け付けていません。