さくらの 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-fpmがメモリを食いつぶさないようにする | monoの開発ブログ
- nginx+PHP-FPMでどこまでチューニングできるか at 改訂版 新卒ネットワークエンジニア
- apache のかわりにnginxを使ってみる(2) php-fpmをインストールする | レンタルサーバー・自宅サーバー設定・構築のヒント
- nginx+php-fpmをyumでインストールして、WordPress/CakePHPを動かす設定 – Shin x blog
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 |
以上の設定やコードは下記のページを参考にしました。
- nginxでPHPを動かす – スコトプリゴニエフスク通信
- Nginx+Fastcgi+PHPでサクサク快適サイト構築! : アシアルブログ
- WordPress サイトに nginx を導入する : dogmap.jp
- WordPress on nginx with FastCGIのCentOSの場合 « stnard.jp
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 で簡単にキャシュを削除することができます。
- Nginx に cache purge モジュールを追加する : dogmap.jp
- nginxでcacheの部分的なpurgeをしてみる (あまり使えない) – Masatomo Nakano Blog
- ngx_cache_purgeモジュールをインストールする « taichino.com
ちょっとコンパイルし直さなきゃいけないので、この辺は別記事でまとめておきます。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 にキャッシュ削除のモジュール入れるためにコンパイルし直す必要があったりで、もっと事前に情報を探っておくべきでした。
コメント