GentooでTomcat6を設定する

前置き

IPLookupというwebアプリをJSPで作りました。そのときに苦労したTomcatの設定に関するメモです。

本文

環境

  • サーバマシンはGentoo、開発マシンはWindows
  • ソースはGentoo側(~/配下)に置き、samba経由でWindowsのEclipseから編集する
  • サーバソフトのバージョンは、apache-2.2.15、tomcat-6.0.26、jdk-1.6.0、ant-core-1.7.1-r4

Apacheの設定

開発するwebアプリの名前はiplookupなので、Tomcat経由でアクセスする場合のURLはこんな感じです。

   http://gpsoft.dip.jp:8080/iplookup/index.jsp

運用時はApache経由でアクセスして欲しいので、以下のURLを使うことにしました。

   http://gpsoft.dip.jp/apps/iplookup/index.jsp

ApacheとTomcatの連携にはAJPを使います。

  • /etc/apache2/httpd.conf
<IfModule mod_proxy.c>
  ProxyPass /apps/iplookup ajp://localhost:8009/iplookup
  ProxyPassReverse /apps/iplookup ajp://localhost:8009/iplookup
  ProxyPassReverseCookiePath /iplookup /apps/iplookup
</IfModule>

ProxyPassは、Apacheの/apps/iplookupに来たリクエストをTomcatの/iplookupへ流せという意味です。ProxyPassReverseCookiePathはクッキー情報のパス変換ルールで、Tomcatからの/iplookupを、Apacheは/apps/iplookupとして扱うことになります(これがないと、セッション情報がちゃんと維持できません)。ProxyPassReverseの必要性はよく分かりません。

webアプリが増えるたびに2行ずつ加筆するのは面倒なので、1つ上の階層で指定した方が楽ちんですね(このとき、appsの後ろの/を忘れずに)。

  • /etc/apache2/httpd.conf
<IfModule mod_proxy.c>
  ProxyPass /apps/ ajp://localhost:8009/
  ProxyPassReverse /apps/ ajp://localhost:8009/
  ProxyPassReverseCookiePath / /apps/
</IfModule>

この例ではhttpd.confに直接書いてますが、Gentooの作法にならうなら、/etc/apache2/modules.d/の下にmod_proxy用のconfファイルを作るべきなんでしょうか? よく分かりません。

また、ApacheでAJPを使うためにはmod_proxyとmod_proxy_ajpが必要です。デフォルトでも入るのかもしれませんが、私はemergeのときにAPACHE2_MODULESで指定しました。

  • /etc/make.conf
APACHE2_MODULES="proxy proxy_ajp"      # 実際は、この2つ以外にもあります。

Apacheの起動オプションにも注意して下さい。

  • /etc/conf.d/apache2
APACHE2_OPTS="-D PROXY"    # これ以外にもたくさん。

Tomcatの設定

環境変数

環境変数を確認しておきましょう(デフォルトでこうなってるはず)。

  • /etc/conf.d/tomcat-6
CATALINA_HOME=/usr/share/tomcat-6/
CATALINA_BASE=/var/lib/tomcat-6/

たぶん、大事なのはCATALINA_BASEの方です。

AJPの有効化とHTTPの無効化

Apacheと連携するためAJPを有効化します(たぶん、デフォルトで有効化されてました)。これで、Apacheからたらい回しされて来たリクエストを受け取ることができます。

  • /var/lib/tomcat-6/conf/server.xml
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

また、デフォルトだと8080ポートでHTTPを待っているので、これを無効化しました。

  • /var/lib/tomcat-6/conf/server.xml
<!--
<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />
-->

server.xmlを書き換えた場合は、Tomcatを再起動する必要があります。

/etc/init.d/tomcat-6 restart

コンテキストの設定

デフォルトのアプリ置き場は /var/lib/tomcat-6/webapps/ なので、iplookupなら、こんな感じでアプリを置けばOKです。

/var/lib/tomcat-6/webapps/iplookup/
    META-INF/
    WEB-INF/
        classes/
        lib/
        web.xml
    index.jsp

あるいは、/var/lib/tomcat-6/webapps/iplookup.warにwarファイルを置くだけでも可です(Tomcatが展開してくれる)。

しかし今回は、デフォルトの置き場には置きません(rootじゃないと書けない場所なので)。今回は、rootにならずに、ソース編集からデプロイまでを行うことが目標です。具体的には、こんな流れになります。

  1. ソースは、~/jsp/iplookupに置く
  2. Samba経由で、WindowsのEclipseから編集する
  3. Gentoo側で、antでビルド(コンパイルとiplookup.war生成)する
  4. iplookup.warのデプロイ先は、~/jspapps/とする

Tomcatが、デフォルト置き場以外のwarファイルを見つけてくれるようにするには、コンテキスト情報を設定する必要があります(Tomcatの「コンテキスト」は「アプリ」と同義っぽい)。正式にはコンテキスト記述子(Context Descriptor)と呼ぶようですが、本記事内ではコンテキストファイルと呼ぶことにします。

  • /var/lib/tomcat-6/conf/Catalina/localhost/iplookup.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context
  path="/iplookup"
  docBase="/home/foo/jspapps/iplookup.war"
  reloadable="false"
/>

ファイル名(iplookup.xml)はアプリ名を反映しています。docBaseにディレクトリを指定しても構いませんが、その場合は、そのディレクトリにwarを展開しておく必要があります。reloadableをtrueにすると、アプリを修正したときにTomcatが自動的に再ロードしてくれるらしいですが、今回は関係ないと思います(理由は後述)。

古いTomcatではコンテキスト情報をserver.xmlに書いていたようですが、ちょっとコンテキスト情報を変えたくらいでTomcatを再起動するのはインパクトが大きいので、別ファイルに分離されたようです。というわけで、iplookup.xmlを書き換えてもTomcatを再起動する必要はありません(新規作成時は再起動が必要かも)。

これで、Tomcatがiplookup.warを見つけて展開してくれるはずです。もし、うまく行かない場合は、server.xmlを確認して下さい。

  • /var/lib/tomcat-6/conf/server.xml
<Host name="localhost"  appBase="webapps"
      unpackWARs="true" autoDeploy="true"
      xmlValidation="false" xmlNamespaceAware="false">

unpackWARsとautoDeployがポイントです。このようになっていれば、iplookup.war更新時に、Tomcatが自動的にwarを/var/lib/tomcat-6/webapps/に展開して再ロードしてくれます(なので前述のreloadableは関係ない)。

注意点1

Tomcatは、以下の3つをまとめて1つのアプリとして管理しているようです。

  • warファイル(~/jspapps/iplookup.war)
  • warファイルを展開したディレクトリ(/var/lib/tomcat-6/webapps/iplookup/)
  • コンテキストファイル(/var/lib/tomcat-6/conf/Catalina/localhost/iplookup.xml)

そして、なんと、warファイルや展開ディレクトリを削除すると、コンテキストファイルを自動的に削除してしまうのです。warや展開ディレクトリは再生成が容易ですが、コンテキストファイルが消されてしまうとダメージが大きいです(何度作り直したことか…)。

注意点2

今回は、アプリのパスとURLのパスが食い違っています。つまり、Tomcatから見たアプリのパスは/iplookupで、ブラウザから見たURLのパスは/apps/iplookupです。この食い違いをAJPのレイヤで吸収しています。しかし、できることなら、このパスは一致させておいた方が良さそうです。例えば今回の場合、index.jspの中でrequest.getRequestURL()を呼ぶと、"http://gpsoft.dip.jp/iplookup/index.jsp"が返ってきます。AJPでのパス変換をTomcatは知らないようですね。

という訳で、アプリのパスも/apps/iplookupとしてみましょう。

まずは、AJPの設定を変更します。パスが同じなので、ProxyPassReverseCookiePathは不要でしょう。

  • /etc/apache2/httpd.conf
<IfModule mod_proxy.c>
  ProxyPass /apps ajp://localhost:8009/iplookup/apps
  ProxyPassReverse /apps ajp://localhost:8009/apps
</IfModule>

あとはコンテキストファイルを変更すればOKかなぁ…

  • /var/lib/tomcat-6/conf/Catalina/localhost/iplookup.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context
  path="/apps/iplookup"
  docBase="/home/foo/jspapps/iplookup.war"
  reloadable="false"
/>

と思いきや、そう甘くはありませんでした。Context要素のpath属性が階層を持つ場合は、コンテキストファイル名も階層にマッチするように変える必要があるようです。今回の場合、iplookup.xmlをapps#iplookup.xmlにリネームします。localhostディレクトリの下にappsディレクトリを作って、その下にiplookup.xmlを置く方が直感的な気もしますが、そうではありません。例えば、path="/tomcat/apps/iplookup"なら、localhostディレクトリの直下に、tomcat#apps#iplookup.xmlという名前でコンテキストファイルを作ります。妙な仕様ですが、Tomcatの公式サイト(直リンク)に書いてました。

Last modified:2011/06/09 18:23:24
Keyword(s):
References:[サーバ管理・Linux関連]
This page is frozen.