Tomcat6.0でコンテキストごとにデータソース、レルムの設定を行う

Tomcatで複数のアプリケーションをデプロイするとき、データソースやレルムの設定をアプリケーション(コンテキスト)ごとに設定したいときがある。結論から言うと、$CATALINA_HOME/conf/server.xmlのHostタグ内にアプリケーションごとのContextタグを書いて、さらにその中にデータソースやレルムの設定を行えばいい。こんな風に。

<!-- server.xmlから抜粋 -->
<Host appBase="webapps" autoDeploy="false" name="localhost" unpackWARs="true"
	xmlNamespaceAware="false" xmlValidation="false">
	<!-- 1つ目のアプリケーションの設定 -->
	<Context docBase="service1_dir" path="/service1" reloadable="false">
		<Resource name="jdbc/service1_db" auth="Container" type="javax.sql.DataSource"
			maxActive="10" maxIdle="3" maxWait="10000" username="service1_user"
			password="service1_pass" driverClassName="org.postgresql.Driver"
			url="jdbc:postgresql://localhost:5432/service1_db" />
		<Realm className="org.apache.catalina.realm.DataSourceRealm"
			dataSourceName="jdbc/service1_db" localDataSource="true" roleNameCol="user_role"
			userCredCol="login_passwd" userNameCol="login_user_name" userRoleTable="users"
			userTable="users" />
	</Context>
	<!-- 2つ目のアプリケーションの設定... -->
	<Context docBase="service2_dir" path="/service2" reloadable="false">
	<!-- ...以下省略 -->

分かってしまえば当然といえば当然の設定なんだけど、結構はまってしまった。また、上記設定をしたときの各種ファイル、アプリケーションの配置は次のようになっている。

CATALINA_HOME
     +-------conf
     |         +--------- server.xml
     +-------webapps
                +-------- service1_dir
                `-------- service2_dir

ただ、現在の新しいTomcat(5、6)では、server.xmlにコンテキストの設定をするのは推奨していないらしい。ので、上記の設定はあんまりお勧めの方法ではない・・。とはいえ、推奨する方法だと場合によって面倒くさかったりする。(半分はこれを調べててはまった)

たとえば上記の設定と同じことを推奨の方法でやってみる場合を考えてみるとこうなる。
前提として、アプリケーションは2つ、それぞれ/service1, /service2でアクセスさせる。ただし、アプリケーションのディレクトリ名はこれとは別の「service1_dir」「service2_dir」となっている。

まず、アプリケーションはwebappsの配下においてはいけない。正確にはserver.xmlのHostに定義されているappBase以下に置いてはいけない。さらにContextの設定にあるdocBase絶対パスで指定する。
次に、CATALINA_HOME/conf/以下に「engine name」/「host name」というディレクトリを作成し、「コンテキストパス」.xmlというファイルを作る。ここで指定したファイル名がコンテキストパスとして認識される(今回の例ではservice1.xml, service2.xmlとなる)。また、「engine name」「host name」はserver.xmlの以下の行で指定された名前となる。(ホスト名は、Hostタグの中でも設定出来るのでそっちが優先されるはず)

<Engine name="Catalina" defaultHost="localhost">

これをふまえて、推奨の方法で設定すると以下の通りとなる。まずは、ディレクトリ構成。

CATALINA_HOME
     +-------conf
     |         +--------- Catalina
     |         |             +-----------localhost
     |         |                             +------- server1.xml
     |         |                             `------- server2.xml
     |         |
     |         +--------- server.xml(ここにはコンテキストの設定は書かない)
     |
     +-------webapps(ここにアプリを設置しない)
     |
     `-------appdir(どこか適当なディレクトリ)
                +-------- service1_dir
                `-------- service2_dir

次に、server1.xmlの内容は以下の通りとなる。(docBase絶対パスを指定している以外は、最初の例と同様)

	<Context docBase="${catelina.base}/appdir/service1_dir" path="/service1" reloadable="false">
		<Resource name="jdbc/service1_db" auth="Container" type="javax.sql.DataSource"
			maxActive="10" maxIdle="3" maxWait="10000" username="service1_user"
			password="service1_pass" driverClassName="org.postgresql.Driver"
			url="jdbc:postgresql://localhost:5432/service1_db" />
		<Realm className="org.apache.catalina.realm.DataSourceRealm"
			dataSourceName="jdbc/service1_db" localDataSource="true" roleNameCol="user_role"
			userCredCol="login_passwd" userNameCol="login_user_name" userRoleTable="users"
			userTable="users" />
	</Context>

ちなみに、上記設定でpath="/service1"とやってるけど、これは無視されるらしい。この設定が有効なのはContextの設定をserver.xmlに書いたときだけなんだと。。ポイントとしては

  • アプリケーションごとのコンテキスト設定は「$CATALINA_HOME/conf/Catalina/localhost」以下にXMLを作成
  • 上記XMLのファイル名がコンテキストパスとなる
  • appBase以下にアプリケーションを配置しない
  • コンテキスト設定(server1.xmlとか)のdocBaseはアプリケーションの場所を絶対パスで指定

と、まぁ、なかなか分かりにくいね。。なので私は推奨の方法は使っていません。今のところ・・。


以下のサイトを参考にさせていただいています。
Tomcatのコンテキストパス指定 | Das Tagebuch von Judith - 楽天ブログ
Apache Tomcat Configuration Reference - The Context Container
http://www.oki.com/jp/oss/document/tomcat/tomcat-6.0.14/build/tomcat-docs/config/printer/context.html
Tomcatのセキュリティとリスクの基本分かってる? (4/4):Tomcatはどこまで“安全”にできるのか?(4) - @IT
http://f25.aaa.livedoor.jp/~ayase/php/pukiwiki/pukiwiki.php?Tomcat%C0%DF%C4%EA