VirtualDocumentRootを使って複数ドメインをスッキリ管理(Apache)

最近は個人的にはnginxnode-http-proxyを使うことが多くなってきましたが、phpを手軽に使いたいときとかhttpdもまだまだ使う機会は多いです。今日は新しいサーバの設定しながらふとTipsを一つ吐き出してみます。


Apache httpdで名前ベースで複数ドメインを管理する際、始めの頃はドメイン増やす度にVirtualHostディレクティブを1つずつ増やしていったりするんだけど、そのやり方だと数が増えてくるとコピペ修正ミスが出たりどんどん管理が大変になってきます。でもこれ実は VirtualDocumentRoot というディレクティブを使うと一つのVirtualHostで書けちゃいます。↓こんな感じ。

NameVirtualHost *:80

  VirtualDocumentRoot /home/domains/%0/public_html


  Options All
  AllowOverride All

%0にはFQDN全体が入ってくれるので以下のようなディレクトリを作るだけで簡単にそのドメインのDocumentRootが出来てしまいます。ついでにディレクトリの設定もワイルドカード使って書いてます。

/home/domains/kawaz.jp/public_html
/home/domains/danger.example.co.jp/public_html
/home/domains/sub.kawaz.jp/public_html
/home/domains/www.example.com/public_html
/home/domains/www.kawaz.jp/public_html

ここまではマニュアルにも載ってるし、ブログ記事も結構見つかります。

もう一歩前へ!

ドメインが増えるだけならまだしもサブドメインも増えてきた日にはdomainsディレクトリでのlsも見にくいしtab補完も分かりにくくなってきます。
そこで僕はJavaのパッケージ名のようにドメインを逆順にピリオドで繋げた以下のようなディレクトリ構成をやりたいなーと思ったので出来るだけシンプルになるよう工夫してみました。

/home/domains/com.example.www/public_html
/home/domains/jp.kawaz/public_html
/home/domains/jp.kawaz.sub/public_html
/home/domains/jp.kawaz.www/public_html
/home/domains/jp.co.example.danger/public_html

その結果出来たのが↓この設定です。これを追記しておくだけで逆順FQDNディレクトリでマルチドメインが出来るようになりました。

NameVirtualHost *:80

  ServerAlias *.*.*.*
  VirtualDocumentRoot /home/domains/%4.1+.%3.1+.%2.1+.%1.1+/public_html


  ServerAlias *.*.*
  VirtualDocumentRoot /home/domains/%3.1+.%2.1+.%1.1+/public_html


  ServerAlias *.*
  VirtualDocumentRoot /home/domains/%2.1+.%1.1+/public_html


  Options All
  AllowOverride All

%の細かい書式は何となく分かれば読み飛ばしで十分*1。VirtualHostのServerNameの代わりにServerAiasを使い、更に上から順にマッチが行われるのを利用して、サブドメインの階層の数により複数のVirtualHostを用意してます。大抵はこの3つのパターンがあれば事足りると思いますが分かりやすい設定なので増やすのも簡単だと思います。

ついでにログも見直す

最近はGoogleAnalyticsとか使うので自分でaccess_logを解析することは滅多に無く、使い道と言えばもっぱらデバッグ用途です。なので非常に見づらいデフォルトの古臭いLogFormatはバッサリ捨てて↓こんな感じの設定を書くことが多いです。

LogFormat "%{%FT%T%z}t %>s %T %B \"%m http://%{Host}i%U%q\" \"%{User-Agent}i\" %h" custom
CustomLog "logs/custom_log" custom

こうすると以下のようなログが出来ます。

2011-07-26T00:58:25+0900 200 0 6243 "GET http://www.kawaz.jp/i/test.php?id=111" "DoCoMo/2.0 P05B(c500;TB;W24H16)" 67.195.115.49
2011-07-26T00:58:25+0900 200 1 6341 "GET http://www.kawaz.jp/i/test.php?id=123" "DoCoMo/2.0 D905i(c100;TB;W24H17)" 67.195.115.49
2011-07-26T00:58:25+0900 404 0 185 "GET http://example.com/" "DoCoMo/2.0 F01C(c500;TB;W24H16)" 192.168.1.1
2011-07-26T00:58:25+0900 200 0 1639 "GET http://sub1.kawaz.jp/" "KDDI-CA3D UP.Browser/6.2_7.2.7.1.K.3.352 (GUI) MMP/2.0" 127.0.0.1
2011-07-26T00:58:24+0900 200 3 5320 "GET http://sub1.kawaz.jp/profile" "KDDI-CA3D UP.Browser/6.2_7.2.7.1.K.3.352 (GUI) MMP/2.0" 127.0.0.1
2011-07-26T00:58:25+0900 200 0 6341 "GET http://www.kawaz.jp/i/birthday.php" "DoCoMo/2.0 P905i(c100;TB;W24H15)" 127.0.0.1
2011-07-26T00:58:26+0900 200 0 6341 "GET http://sub2.kawaz.jp/" "DoCoMo/2.0 SH905i(c100;TB;W24H16)" 121.119.167.218

ポイントはまず日時が見やすい!(あの年月日を逆に書くいた上あまつさえ月を名前で書くという文化は未だに馴染めない、ソートもしにくいし何が嬉しいの?)
次にステータスコードが縦にそろって見やすい(固定幅のカラムを前に集めるとガタガタにならなくてよいです)
第3カラムでは応答にかかった秒数も付けました、重たいページを探すのに便利です。
第4カラムはレスポンスサイズ。まぁあると便利です。
第5カラムではHTTPメソッドとリクエストされたURLです。パスだけじゃなくホスト名も付けることでコピペでブラウザ表示が確認できて便利です。
で、あまり使うことが無いUser-Agentと接続元IPは後ろに追いやってます。
あと LogFormat で良くやるのは \"%{Location}o\" を付けておくとプログラムで Location ヘッダを出力した際に飛び先の確認が出来てデバッグに便利です。

*1:%1にjp、%2にkawaz、%3にwwwとかが入るので、%1.%2.%3とか書きたいとこですが、%2.1や%2.2がkやaになるという仕様があるため単純にピリオドで繋げると書式エラーになってしまいます。ここで%2.1+は%2のうち1文字目以降全部=kawazとなってこの後ろなら初めてピリオドを置くことが出来るといった次第です(^^;