NginxでWordPressのログインをSSLにしてみよう

最近(というわけでもないか?)ユーザパスワードの流出問題をよく聞く。以前から自分のサイトへのログインをSSLで通信した方が良いのではと思っていたが、ブログもレンタルサーバからさくらのVPSに移行したことだし、WordPressをSSLにしてみる。

サーバ証明書を買うか買わないか

サーバ証明書も安くなって個人でも手を出せるようになってきたと聞く、http://www.rapid-ssl.jp/を調べてみたが、2012/06の時点で年額2,600円(税込)。確かに安い。が面倒なことにRedmineのログインもセキュアにしたいのに、別のサブドメインにしているのでサーバ証明書がサブドメインごとに必要になってしまう。

冷静に考えれば自分(だけ)が自分のサーバに接続するのにサーバの証明の何もないので今回はサーバ証明書を買うのを諦めてオレオレ証明書を使うことにする。

オレオレ証明書の作成

openssl req -new -newkey rsa:2048 -nodes -keyout blog.example.com.key -out blog.example.com.csr
openssl x509 -in blog.makotokw.com.csr -out blog.example.com.crt -req -signkey blog.example.com.key -days 3650

自分しか使わないことをいいことにパスフレーズなしで期限も長くしているので良い子は真似しないように。

nginxでSSLを設定する

server {
    listen               80;
    listen               443  ssl;
    server_name blog.example.com;

    ssl on;
    ssl_certificate      /etc/certs/blog.example.com.crt;
    ssl_certificate_key  /etc/certs/blog.example.com.key;

http/https両方で公開するので80と443の両方でlistenする。前手順で作成した証明書と秘密鍵のパスを設定。

/etc/init.d/nginx reload

で再起動。

WordPressの設定

WordPressでSSLの上で管理ページを使う方法は以下のドキュメントに記載されている。
Administration Over SSL

望んていた機能。WordPress 2.6以上で使え、ログインや管理ページ全般のみをSSLにすることができる。方法としては2つあっていずれのdefineをwp-config.phpに記載する。

1) ログイン時だけSSLを使う
define('FORCE_SSL_LOGIN', true);

2) ログインと管理ページでSSLを使う
define('FORCE_SSL_ADMIN', true);

入れる場所はwp-settings.phprequire_onceよりも前ならどこでも良い。

今回はログインだけセキュアにすれば満足なので1の方法を使う。セッションクッキーとか知ったこっちゃない。

設定後もログインページがSSLじゃないのだが、ソースを見てみるとformのポスト先はhttpsになっていた。そしてログインしようとするとブラウザに以下のように警告される。

blog.makotokw.com は不正なセキュリティ証明書を使用しています。
自己署名をしているためこの証明書は信頼されません。

OKじゃないけど、今回の手順では正常系。

まとめ

今回は自分が自分のサーバにログインするときのパスワードを暗号化する。というのが目的だったのでオレオレ証明書を使ってWordPressのログインページだけをSSLで通信するように設定した。対象が自分だけなので許されるが今回の手順はセキュリティ的にはそれほど良いものではないので、自分以外のユーザが使うようなケースではセキュリティについてよく検討した上で参考にしていただきたく。

NginxでWordPressを実行する 開発環境例

いくつかWordPressプラグインを開発しているのだけど、基本的に自分のブログでテストするのは最後で開発時は別に開発専用のWordPressを用意している。

その環境はVMWare PlayerでUbuntuをゲストOSとして実行している。いままではApache2で動かしていたけれど、Ubuntu 12.04 LTSのリリースのタイミングと今回さくらのVPSに移行したタイミングから開発環境でもNginxでテストすることに。

WordPress開発環境の構成

URL

開発時はwordpress-devというサーバ名で運用している。ブラウザでテストするマシン(ホストOS)の/etc/hosts(Windowsの場合はC:\Windows\System32\drivers\etc\hosts)に以下を追加しておく。

192.168.0.1 wordpress-dev

192.168.0.1は例であって実際はVMWareの仮想ネットワークが振るアドレスに変更となる。ゲストOSのUbuntuでifconfigと打てばDHCPに振られているIPアドレスがわかる。

ディレクトリ構成

試行錯誤したのち、WordPress開発環境では以下のような構成にしている。

  • /var/www/wordpress-dev/2.8/ja/ -> 特定バージョンのWordPressを配置
  • /var/www/wordpress-dev/beta/en/ -> 正式リリース前のWordpressを配置
  • /var/www/wordpress-dev/stable/en/ -> 最新のWordPressを配置
  • /var/www/wordpress-dev/stable/ja/ -> 最新のWordPressを配置

WordPressバージョンによってAPIが変わるのでAPIの変更が大きかったバージョンを幾つか用意しておく。新しいWordPressバージョンでの動作確認のためbetaディレクトリに用意。普段の開発は最新版を自動更新するstableディレクトリを用意しておく。プラグインでは日英ローカライズにも対応しているのでen,jaといったディレクトリにその言語でのWordPressをそのまま配置している。

データベース接続

WordPressは同一データベースで複数のWordPressを管理することが可能。具体的には同じSQLデータベース内で別のテーブルを使うことができる。wp-config.phpにはtable_prefixという変数名があり、これをそれぞれバラバラに設定しておけば同じデータベースでも別のテーブル名が使われるので複数のWordPressを共存することができる。

デフォルトはwp_で、先程のディレクトリ階層に沿って例えば/var/www/stable/ja/wp-config.phpでは以下のようにwp_stable_ja_というように設定している。

/**
 * WordPress データベーステーブルの接頭辞
 *
 * それぞれにユニーク (一意) な接頭辞を与えることで一つのデータベースに複数の WordPress を
 * インストールすることができます。半角英数字と下線のみを使用してください。
 */
$table_prefix  = 'wp_stable_ja_';

Ubuntu 12.04でNginxを実行する

Ubuntuではnginx-extrasパッケージが普通に見つかったのでDebinaでdotdebリポジトリを追加したときの手順と変わらない。

sudo apt-get install nginx-extras
sudo apt-get install php5-fpm

でnginxからphpを実行する環境を構築できる。

トラブル apacheをバックエンドにするとリダイレクトする

そうは言ってもNginxの設定を書きなおすのが面倒だったので今まで使っていたApacheの設定をそのまま使い、Apacheをポート8080で動かし、NginxからApacheに振ってみた。

proxy_pass          http://127.0.0.1:8080;

結論からいうとうまく動かなかった。

ブラウザから http://wordpress-dev/stable/ja/ にアクセスするとNginxがproxy_passの設定に従いhttp://127.0.0.1:8080/stable/ja/を参照した結果を返そうとする。http://127.0.0.1:8080/stable/ja/ではApacheがWordpressを実行してレスポンスを返すのだが、おそらくWordPressのブログのURLとこのアクセスしたURL(http://127.0.0.1:8080/stable/ja/)が違うのでWordPressはこのURLにリダイレクトしようとしてしまう。

リダイレクトのレスポンスを受けてブラウザはhttp://127.0.0.1/stable/ja/にアクセスするが、(ホストOSの)ブラウザから見た場合127.0.0.1はNginxやApacheを動かしているゲストOSではなくホストOS自身なので期待する結果は得られない。ホストOSでWebサーバを実行していなければただの接続エラーがブラウザに表示される。

渋々Nginxの設定をする

大した手間でもないので諦めてリダイレクトの問題は調査せずにNginxの設定を書く。

upstream php {
    server 127.0.0.1:9000;
}
server {
    server_name wordpress-dev;
    error_log /var/log/nginx/error_wpdev.log debug;
    root /var/www/wordpress-dev;
    index index.php;

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_index index.php;
        fastcgi_intercept_errors on;
        fastcgi_pass php;
    }
}

上記ファイルは以下のコマンドで有効にする

    pushd /etc/nginx/sites-enabled/
    sudo ln -s ../sites-available/wordpress-dev wordpress-dev 
    popd
    sudo service nginx reload

WP_SITEURL定義のTips

接続で使うURLをWordPressがデータベースに保存しているサイトのURLが違うとリダイレクトなり問題が起きるようなのだが、wp-config.phpに以下のような記述を入れるとデータベースのサイトURLよりこちらを優先して使ってくれるようだ。URLを移行したときに接続できない場合は移行後のURLをWP_SITEURLに設定してWordPressを開き、wp-adminからサイトのURLを編集すればよいだろう。

define('WP_SITEURL', 'http://wordpress-dev/stable/ja');

NginxでWordPressを実行する CORESERVER.JPからさくらのVPSに移行編

このブログをさくらのVPSに移行して記事を書いて終わり!と思ったが長期戦の予感がしてきたのでとりあえず書いてみることにする。これを書いている時点ではすでに移行しているので今日はそこまで話。

サーバの情報

今まで使っていたレンタルサーバはCORESERVER.JPのCORE-MINI。ずっとCORE-Aだと思ってた・・・。CORE-MINIだと300以下のアカウントで共有しているのでまぁそれは重いこともあるよなー。Load Avarageが10とかザラだったし。

XREA+/CORESERVER.JPはsafeモードでphpが動くのでSuper Cacheをレガシーモードで動かさざるを得なかったり、よく空のレスポンスが返ってくる(ChromeでERR_EMPTY_RESPONSEというエラーが表示されるやつ)ことがあっていい加減うんざりしていたのでVPSに移行することにした。

で移行先のサーバはさくらのVPS 2G。メモリ2Gの仮想3コア。さくらのバックボーンがあるので回線的なパフォーマンスも期待。OSはCentOSではなくDebian 6。

と、その前に

実はNginxにしたからといって速くなるとはまったく期待していなかった。自分が抱いていたNginxのイメージは静的ファイルの配布のパフォーマンスがいいのと、同時アクセス数が多くなってもパフォーマンスが落ちないというあたり。このブログ程度であれば別にNginxにしたところで対して変わらんだろうと思っていた。

http://codex.wordpress.org/Nginx
Before you consider using nginx, be aware that PHP APC or a similar opcode cache with a WordPress caching plugin is going to offer significant performance improvements over just switching from Apache to nginx. If you aren’t already using a PHP opcode cache and WordPress caching plugin, nginx will do squat for your WordPress-based website’s performance. Also, WordPress is intertwined with the Apache world so support for nginx-based setups is limited but growing. Factor these things into your decision to use nginx.

WordPress Codexにも上のように書いてあった。「オマイラもちつけ、APCやキャッシュプラグインを使えばApcheでも十分パフォーマンスはでる」と。

Nginx x WordPressで検索するといろんな記事がヒットするが意外に鉄板な設定はなく、運用を見極めながら決めないといけない。実際設定をしていて思ったが、Nginxは機能がシンプルだけに奥が深い。VPSなどサーバ構築の敷居が下がっているだけになんか速いんでしょ?と軽い気持ちで移行をすすめてはいけないと思った。

自己満足でNginxにします宣言

じゃぁ、なんでNginxにするのよ?ということだが理由は2つほどある。

1つPHP Ninjaの存在から。これまでにない速さという触れ込みのWordPressのサービスでベータ版に飛びついてみたが、その後判明した価格帯や機能から相当なアクセスがあるブログでしかサービスの良さを享受できないことがわかった。PHP NinjaはZ Cloud、Nginx、WordPress Tuningで高パフォーマンスを実現している。これならVPSで自分で同じような構成にするからいいよ。と完全な負け惜しみからくる自己満足で構築することを決意した。

2つ目はすこしまともな理由。NginxはWebサーバでもあるがリバースプロキシの機能が豊富なのが素敵。特にバックエンドの機能と疎結合に見えるのがいい。設定ファイルで正規表現を使いまくれるのも素敵。ソフトウェアエンジニアの視点から見ると体の良いdispatcherのように見える。正規表現でこのリクエストはNginxで、これはApacheで、とか、別のサーバに処理させるなども可能なのでいろんなチャレンジができそうというのが良い。

自分のテンション(モチベーション)を上げるのは重要なのでこういう邪な理由でも意味があるのである。

PHP5-FPMのインストール

NginxでPHPアプリケーションを実行する場合はバックエンドをCGIとしてを動かすことになる。それを実現する一つの方法が PHP-FPM (FastCGI Process Manager) である。以前はセットアップが面倒だったが、PHP5.3.3から本家に統合されたのでNginxではこれが主流になるだろう。

Debianではdotdebリポジトリを使えば、以下のコマンドでインストール可能。
aptitude install php5-fpm

Debian/UbuntuのPHP設定ファイルの階層は以下のようになっている。当然別ファイルなので注意が必要。デフォルトではポート9000で受け付ける(php-fpm.conf)。これはNginxの設定で使う。

/etc/php5/cli/php.ini
/etc/php5/apache2/php.ini
/etc/php5/fpm/php-fpm.conf
/etc/php5/fpm/php.ini

サービスはいつものように止めたり、動かしたりできる。

service php-fpm restart

WordPressアプリケーションの移行

レンタルサーバだけどドメインは自分のものを使っていた。つまり今回の移行ではURLは変わらないのでデータベースやWordPressのファイルはそのまま移行した(wp-content/cache/は除く)。移行後、権限の変更が必要なファイルがあったので備忘録として残しておく。ちなみにdotdebからインストールしたNginxのデフォルトの設定ではNginxはwww-dataで動作する。

sitemap.xml
sitemap.xml.gz
wp-content/wp-cache-config.php
wp-content/advanced-cache.php

最初の2つはGoogle XML Sitemapsプラグイン、残りの2つはWP Super Cacheプラグインにプラグインの設定ページから再生成できるので単にファイルを削除しておけばよい。基本的にアプリケーションが書き込むファイル以外の所有者や権限は変えたくない派。

WordPressを動かすためのNginxの最低限の設定

ようやく本題。

WordPressのためのNginxの設定はNginxのサイトやWordPressのサイトに書いてある。そして微妙に違うw

http://wiki.nginx.org/WordPress
http://codex.wordpress.org/Nginx

これ以外にも検索するといろいろ出てくる。どれも微妙に違うけど別にどれでもさほど問題なかったりもする。でもやはり知らない設定をコピペして使いたくない。とりあえずの最低限の設定は以下。あとはデフォルト。

upstream php {
    server 127.0.0.1:9000;
}

server {
    server_name blog.example.com;
    root /var/www/blog.example.com;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }   
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass php;
    }    
    location ~ /\. {
       deny all;
    }
}

設定の補足。
1. 全部 /index.php に振っとけばindex指定は要らなくね?と思ったが index index.php;がないと管理ページ(/wp-admin/(index.php))にアクセスできなかった罠。
2. Nginxのサイトの設定 "try_files $uri $uri/ /index.php" を使っていたらパラメータが引き継がれないのでパーマリンクをカスタマイズしているときに投稿のプレビューが更新されない問題に遭遇。これはWordPress側の"try_files $uri $uri/ /index.php?$args;"が正解。

safeモードから解放されて、ようやくSuper Cache プラグインの「レガシーなページキャッシング」から「キャッシュファイルの提供に PHP を利用する」に変更できた。

これから調整していきたいこと

さくらのVPSに変えただけで快適になったのでまずは満足している。以下は徐々に対応していきたい。

  • Nginx/PHP-FPMの設定を調整
  • tcp portでアクセスするのがいいのかどうか
  • エラーページのカスタマイズ
  • 適切なphpスクリプトだけを対象にする
  • 静的ファイルの有効期限の設定
  • ログファイルに出力すべきものをフィルタ
  • APCを有効にしたらSIGSEGVが起きる原因の調査
  • Super Cacheプラグインでキャッシュをrewriteする設定

参考になったもの

書籍は以下の2冊を見ながらやっています。

さくらのVPSでRedmineとかTracをApacheからNginxに切り替える

「さくらのVPS」でっていうのがいいタイトルなのかどうかわからないけど、実際のところはDebina 6で構築する話。ApacheをWebサーバとして公開していたRedmine/Trac/Subversionをある機会でNginxに切り変えることにした。

この記事の段階ではDebian 6+Nginx 1.0.14の内容となっています。(1.2.0からはパッケージが変わっているようです)

Nginxにする動機

正直なところ、個人利用のRedmineやTracでパフォーマンスを気にする必要もあまりなく、これ単独でNginxにする動機はない。背景にはレンタルサーバで公開しているWordPressのblogをNginx+php-fpmを利用する形でさくらのVPS 2Gに移行しようと思っていたことがある。するとPort 80をNginxに明け渡さないといけなくなるため他のサービスも対応が必要になる。

方針

今回は以下の方針でいくことにする

  • RedmineはNginx+passengerで公開
  • Trac/SubversionはApacheをバックエンドにしてNginxをリバースプロキシとして公開

Trac/Subversionはもうreadonlyでほとんど使っていないので本来はRedmine/Gitに移行したいところなのである。必要なものは移行したが開発を辞めてしまったYahoo! WidetやMovableTypeプラグインなどは移行コストと構築コストを考えたときに後者を取ってしまっているのが現状である。今回もさくらのVPS 2Gに構築したときも悩んだがやはり面倒になったのでそのままTrac/Subversionを構築してしまった。パフォーマンスを気にする必要もなく、メンテナンスコストを掛けたくないので別にApacheのままでいいという判断である。

対してRedmineについては現在も利用しているし、Railsはそれほど設定に悩まなそうなので(これは甘い見通しだったが)Nginxに移行してみようと考えた。

Nginxのインストール

なお、ここからの手順はすべてrootで実行している。

Debian squeezeからインストールしたら、Nginx 0.7だった。ちょっと古いと思いunstableから入れようかと思ったがdotdebという便利なリポジトリがあるようなのでこれを使ってみることに。

dotdebリポジトリを追加

/etc/apt/sources.listに以下を追加。

# dotdeb.org
deb http://packages.dotdeb.org stable all
deb-src http://packages.dotdeb.org stable all

GnuPG キーの追加のため以下を実行する。

cd /tmp
wget http://www.dotdeb.org/dotdeb.gpg
cat dotdeb.gpg | apt-key add -

とりあえず更新
aptitude update

nginx-extrasのインストール

dotdebのnginx 1.2.0からpassengerモジュールはnginx-extrasから取り除かれ、代わりにnginx-passerngerというパッケージが公開されています。従って1.2以降でpassengerを使う場合に実行するコマンドは aptitude install nginx-passerngerが正解です。各パッケージごとのモジュール一覧は以下のリンクを参照ください。
https://docs.google.com/a/moolfreet.com/spreadsheet/ccc?key=0AjuNPnOoex7SdG5fUkhfc3BCSjJQbVVrQTg4UGU2YVE#gid=0

nginx-extrasではPassengerに対応してくれている。サイコー。
http://www.dotdeb.org/2011/05/07/rails-user-dotdeb-now-supports-passenger/

というわけでインストールする。

aptitude install nginx-extras

デフォルトだとport 80を使うようになっているのでApacheを動かしているとNginxは開始できないと思われる。

Nginxの設定

細かい調整は今後必要になってくる、とりあえずサーバのバージョン情報を返すのを無効にしておく。

server_tokens off;

Passenger(Ruby On Rails)のために以下のコメントを外しておく。

        ##
        # nginx-passenger config
        ##
        # Uncomment it if you installed nginx-passenger
        ##

        passenger_root /usr;
        passenger_ruby /usr/bin/ruby;

Virtual Hostの設定

Debian/UbuntuでApacheとおなじみの管理方式になっている。nginx.confよりsites-enabled/*がIncludeされており、sites-availableにサイトごとの設定を書いて、sites-enabeldにシンボリックリンクを張る方式である。

a2ensite/a2dissiteと同様のコマンドngxensite/ngxdissiteがインストールされていた。これを使うとsites-availableにファイルを置いておけば有効・無効(シンボリックリンクの生成・削除)は以下のように行える。

# 有効にする
ngxensite (ファイル名)
# 無効にする
ngxdissite (ファイル名)

a2ensiteでは複数のファイルを指定できたが、ngxensiteで複数指定しても最初のファイルしか有効にならなかった。

Apacheの設定変更

Apacheはバックエンドとして動かすことになるのでいくつかの設定変更が必要になってくる。

Portの変更

VirutalHostで公開しているのでそれぞれのPortを変更する。まずListeningのPort変更。

NameVirtualHost *:8081
Listen 8081

mod_rpafのインストール

NginxをリバースプロキシとしてApacheをバックエンドで動作させる場合、Apacheから見て接続してくるクライアントはNginxである。同じサーバで動かすので同じホストからアクセスされることになる。この場合、ログのリモートホストが127.0.0.1で出力されたり、グローバルIPで接続を制限していても127.0.0.1からのアクセスなので素通りになったりして面倒なことになる。

これらを解決するのがmod_rpafである。mod_rpafはリバースプロキシが送ってくるX-Forwarded-Forなどのヘッダを見てリバースプロキシのリクエスト元をリモートホストとして処理してくれる。

mod-rpafもaptでインストールできた。

aptitude install libapache2-mod-rpaf
a2enmod rpaf

デフォルトの設定は以下のようになっていたのでApacheとNginxを同一サーバで動かすならこのままでいい。

<IfModule mod_rpaf.c>
RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1
</IfModule>

X-Forwarded-Forのヘッダの設定などはNginx側で行う必要があるがそれはこのあとに記載する。

サイトの設定

さて、いよいよここからApacheからNginxへの移行のためのサイト設定になる。
まずApacheのVirutalHostのポートを以下のようにして変更しておく。

<VirtualHost *:8081>

次にNginxのサイト設定を行う。説明の都合で一つにまとめると以下のような感じになる。

server {
    root /usr/share/nginx/www;
    index index.html
    server_name example.com;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /redmine {
        passenger_enabled on;
        passenger_base_uri /redmine;
    }

    location /trac {
        proxy_set_header    X-Forwarded-Host    $host;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_pass          http://127.0.0.1:8081;
    }

    location /svn {
        proxy_set_header    X-Forwarded-Host    $host;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_pass          http://127.0.0.1:8081;
    }
    location ~ /\.ht {
       deny all;
    }
}

Trac/Subversionはそれぞれサブディレクトリで公開していたので、それぞれのlocationでproxy_passtとして同じサーバでポート8081で動いているApacheを指定し、X-Forwarded-Forの設定を行なっている。

ドキュメントルートがデフォルト(/usr/share/nginx/www)のままだが実際にはApacheの際のドキュメントルートと同じものを設定している。そのためApacheの.htで始まるファイルを返してしまわないようにアクセスを拒否する設定をいれている。

Redmineもサブディレクトリで公開している。nginx.confでpassenger_rootとpassenger_rubyの設定は有効にしたのでここでは、passenger_enabled、passenger_base_uriの設定を追加している。ちなみにRailsアプリをサブディレクトリで公開するための設定はPassengerのサイトに書いてあった。他にもいろいろな情報があって参考になる。
http://www.modrails.com/documentation/Users%20guide%20Nginx.html#deploying_rails_to_sub_uri

Nginxのログローテーション

Apacheにはrotatelogsという専用モジュールへログファイルをpipeして日付をファイル名につけてローテーションできたがNginxではそのような機能はなく、logrotateを使うのが基本のようである。デフォルトでは以下のようなファイルがインストールされていた。

/var/log/nginx/*.log {
        daily
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi; \
        endscript
        postrotate
                [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
        endscript
}

logrotateを調べたところdateextというオプションがあるのでdailyと併用すれば日付の名前をつけてローテーションできるようだ。確かlogrotateにはログを恒久的に残すという仕様はなかったと思うので、rotateの設定で世代を沢山残すようにするか自分でファイルをコピーするかしないといけない。

置き換え

ひと通り設定が終わったので、Apache/Nginxを再起動する。Nginxのデフォルトサイトは無効にしておく。ブラウザでアクセスできれば成功となる。

ngxdissite default
ngxensite example
/etc/init.d/apache restart
/etc/init.d/nginx restart

参考になったもの

このエントリを書いている時点で日本語の本はこれしかないと思われる。最初の情報としてはかなり訳にたつ。

Nginxの設定に書けるDirective一覧。新しいサービスはドラスティックに変わっていくのでまずはオフィシャルな情報をチェックするに限る。
Nginx – Directive Index

RedmineのようなRuby On RailsをApache/Nginxで実行させるPassengerのNginx向けのドキュメント、各種設定について参考になる。
Phusion Passenger users guide, Nginx version

まとめ

細かい設定などまだまだ勉強することは多いが、設定の書き方など結構フレキシブルな感じがある。例えばaccess_logがlocationディレクティブでも書けるので今回のようにサービスごとにサブディレクトリに分けている場合はサービスごとにログファイルを運用することも可能である。(Aapcheでも同様のことはできるがちょっと面倒というか設定に可読性があまりないと思う)

まだまだ何をするにせよApacheからNginxへの翻訳が必要な状況だが使っていくうちに覚えるであろうと信じたい。今回はあくまでWordpressを持ってくるための事前準備なので、次はWordpressの移行に取り組みたい。

試行錯誤集

うまくいった手順だけを書くと簡単に見えてしまうが、ここにたどり着くまでいろいろあった。同じことにハマった人のために紹介しておく。

X-Forwarded-Forの設定は明示的に必要

Apacheにmod_rpafを入れたらそれでokと思っていたがApacheのログが127.0.0.1になる。Nginxはproxy_passを設定してもX-Forwarded-Forの設定は自前でする必要があるようだ。しばらくApache側の設定反映を疑ったため時間を浪費した。

gem passengerは使わなくていい

Passengerのインストール方法をみるとNginxへのインストールには、

gem install passenger
passenger-install-nginx-module

を実行すればよくて、最初はこれに従ってみたところ以下のような質問が表示された。

Automatically download and install Nginx?

Nginx doesn't support loadable modules such as some other web servers do,
so in order to install Nginx with Passenger support, it must be recompiled.

Do you want this installer to download, compile and install Nginx for you?

 1. Yes: download, compile and install Nginx for me. (recommended)
    The easiest way to get started. A stock Nginx 1.0.10 with Passenger
    support, but with no other additional third party modules, will be
    installed for you to a directory of your choice.

 2. No: I want to customize my Nginx installation. (for advanced users)
    Choose this if you want to compile Nginx with more third party modules
    besides Passenger, or if you need to pass additional options to Nginx's
    'configure' script. This installer will  1) ask you for the location of
    the Nginx source code,  2) run the 'configure' script according to your
    instructions, and  3) run 'make install'.

Whichever you choose, if you already have an existing Nginx configuration file,
then it will be preserved.

え、せっかくaptでnginx入れたのに何いってんの?ちょっと待ってちょっと待ってちょっと待って。でキャンセルした。そう、この方法でインストールする場合、Passenger機能の付いたnginxをビルドして新規にインストールすることになる。でもやっぱり管理上、aptで運用したい。

libapache2-mod-passengerがあるんだからnginxのパッケージもあるんじゃないのとapt-cache search passengerで検索してnginx-extrasが見つかったのでgem uninstall passengerで消えてもらった。

passenger-install-nginx-moduleを実行するためにいろんなパッケージを入れたのはここだけの秘密。

nginx-fullはnginx-extrasの上位版ではない

dotdebからnginxをインストールするとnginx-fullがインストールされる。さらにnginx-extrasをインストールしようとするとnginx-fullと衝突したので、nginx-fullはnginx-extrasを包括しているんだろうと勝手に勘違いしてしまった。そのためpassengerの設定をしようとすると「 unknown directive “passenger_root” 」とか言われて怒られる。

nginx-fullとnginx-extrasのパッケージの情報を表示してみたところ以下のようにモジュールが異なっていた。

(nginx-full)
Standard HTTP Modules:
   Core, Access, Auth Basic, Auto Index, Browser, Charset, Empty GIF, FastCGI,
   Geo, Gzip, Headers, Index, Limit Requests, Limit Zone, Log, Map, Memcached,
   Proxy, Referer, Rewrite, SCGI, Split Clients, SSI, Upstream, User ID, UWSGI
 Optional HTTP Modules:
   Addition, Debug, GeoIP, Gzip Precompression, HTTP Sub, Image Filter, IPv6,
   RealIP, Secure link, Stub Status, SSL, WebDAV, XSLT
 Other Modules:
   File AIO
 Mail Modules:
   Mail Core, IMAP, POP3, SMTP, SSL
 Third Party Modules:
   Auth PAM, Cache purge, Echo, Syslog, Upstream Fair Queue
 (nginx-extras)
Standard HTTP Modules:
   Core, Access, Auth Basic, Auto Index, Browser, Charset, Empty GIF, FastCGI,
   Geo, Gzip, Headers, Index, Limit Requests, Limit Zone, Log, Map, Memcached,
   Proxy, Referer, Rewrite, SCGI, Split Clients, SSI, Upstream, User ID, UWSGI
 Optional HTTP Modules:
   Addition, Debug, WebDAV, Flash Streaming Video, GeoIP, Gzip Precompression,
   HTTP Sub, Image Filter, MP4, RealIP, Stub Status, SSL, XSLT, IPv6, Embedded
   Perl, Secure Link, Random Index
 Mail Modules:
   Mail Core, POP3, IMAP, SMTP, SSL
 Third Party Modules:
   Echo, Embedded Lua, http push, Nginx Development Kit, Upload module,
   Upload Progress, HttpHeadersMore, Upstream Fair Queue, Chunkin, Auth PAM
 Modules added by Dotdeb:
   File AIO, Syslog, Cache purge, Passenger

というわけで nginx-extras > nginx-full である。nginx-fullを削除して、nginx-extrasを入れなおすはめになった。