前回投稿の続きです。
前回は、Jenkinsで自動デプロイしてみたいシステムと、その問題点、自分なりの解決案の概要を書きました。
今回は、解決案のうち、ビルド・デプロイに関する基礎的な部分を、具体的に記述してみたいと思います。
今回の目標
次のような流れをJenkinsで自動化します。Subversionからソースを取得し、ビルドして、FTPでモジュールを配布し、Tomcatを再起動する。
ポイント
- ファイルの配布は、AntのFTPタスクを使用する。
- Tomcatの再起動は、TomcatのAntタスクを使う。
前提
- Jenkinsは、開発環境(Windows)で起動する。
- テスト環境のTomcatには、Webアプリケーション(古いモジュール状態)がデプロイ済みで動作する環境となっている。
プロジェクト構成
サンプルとして用意したWebアプリケーションのソースは、次のような構成です。特別なことはなく、Eclipseで動的Webプロジェクトで作成した構成です。
手順(下準備)
ビルド
まず、ビルドを行うためのbuild.xmlを作成します。Eclipseで、プロジェクトを選択して、右クリックのメニューの「エクスポート」から、build.xmlを作成しました。多少、Tomcatのパス設定などを手直しして次のようになりました。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="Tomcat4.1Project01">
<property environment="env"/>
<property name="TOMCAT_HOME" value="../../apps/apache-tomcat-4.1.40"/>
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.4"/>
<property name="source" value="1.4"/>
<path id="Apache Tomcat v4.1 [Apache Tomcat v4.1].libraryclasspath">
<pathelement location="${TOMCAT_HOME}/common/lib/activation.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/ant-launcher.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/ant.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/commons-collections-3.2.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/commons-dbcp-1.2.2.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/commons-logging-api-1.1.1.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/commons-pool-1.4.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/jasper-compiler.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/jasper-runtime.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/jdbc2_0-stdext.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/jta.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/mail.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/naming-common.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/naming-factory.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/naming-resources.jar"/>
<pathelement location="${TOMCAT_HOME}/common/lib/servlet.jar"/>
<pathelement location="${TOMCAT_HOME}/common/endorsed/xercesImpl.jar"/>
<pathelement location="${TOMCAT_HOME}/common/endorsed/xml-apis.jar"/>
</path>
<path id="Web App ライブラリー.libraryclasspath"/>
<path id="EAR ライブラリー.libraryclasspath"/>
<path id="Tomcat4.1Project01.classpath">
<pathelement location="build/classes"/>
<path refid="Apache Tomcat v4.1 [Apache Tomcat v4.1].libraryclasspath"/>
<path refid="Web App ライブラリー.libraryclasspath"/>
<path refid="EAR ライブラリー.libraryclasspath"/>
</path>
<target name="init">
<mkdir dir="build/classes"/>
<copy includeemptydirs="false" todir="build/classes">
<fileset dir="src">
<exclude name="**/*.launch"/>
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="build/classes"/>
</target>
<target depends="clean" name="cleanall"/>
<target depends="build-subprojects,build-project" name="build"/>
<target name="build-subprojects"/>
<target depends="init" name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" debuglevel="${debuglevel}" destdir="build/classes" includeantruntime="false" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="Tomcat4.1Project01.classpath"/>
</javac>
</target>
<target description="Build all projects which reference this project. Useful to propagate changes." name="build-refprojects"/>
</project>
コマンドラインから、次のように実行して、ビルドが行われることを確認しました。
ant
デプロイ用モジュール収集
テスト環境へ配布しやすいように、テスト環境の構成に合わせて、モジュールを集めることにしました。次のようにbuild.xmlに追記します。
<target name="make-deploy-files">
<mkdir dir="build/deploy"/>
<copy todir="build/deploy">
<fileset dir="WebContent"/>
</copy>
<copy todir="build/deploy/WEB-INF/classes">
<fileset dir="build/classes"/>
</copy>
</target>
コマンドラインから、次のように実行して、処理が行われることを確認しました。
ant make-deploy-files
モジュール配布
上記処理で収集したモジュールを、テスト環境へFTPアップロードします。これもAntで実現することにしました。
AntのFTPタスクを使うためには、Apache Commons Netが必要となりますので、次のサイトから、「commons-net-3.3.jar」をダウンロードしました。
build.xmlに、次を追加しました。
<property name="server" value="xxxxx"/>
<property name="ftp_userid" value="xxxxx"/>
<property name="ftp_password" value="xxxxx"/>
<target name="deploy-ftp">
<echo message="デプロイ先サーバ: ${server}"/>
<ftp server="${server}" userid="${ftp_userid}" password="${ftp_password}" remotedir="webapps/${ant.project.name}" verbose="true">
<fileset dir="build/deploy">
<include name="**/*"/>
</fileset>
</ftp>
</target>
コマンドラインから、次のように実行して、処理が行われることを確認しました。
ant -lib build_lib\commons-net-3.3.jar deploy-ftp
Tomcat再起動
今回知ったのですが、Tomcatには、AntからTomcatを再起動するためのライブラリが用意されているのですね。さっそく使うことにしました。
次の記述をbuild.xmlに追加しました。
<property name="tomcat_ant_jar" value="${TOMCAT_HOME}/server/lib/catalina-ant.jar" />
<!-- Configure the context path for this application -->
<property name="path" value="/${ant.project.name}"/>
<!-- Configure properties to access the Manager application -->
<property name="url" value="http://${server}:8080/manager"/>
<property name="username" value="xxxxx"/>
<property name="password" value="xxxxx"/>
<!-- Configure the custom Ant tasks for the Manager application -->
<taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask" classpath="${tomcat_ant_jar}"/>
<taskdef name="install" classname="org.apache.catalina.ant.InstallTask" classpath="${tomcat_ant_jar}"/>
<taskdef name="list" classname="org.apache.catalina.ant.ListTask" classpath="${tomcat_ant_jar}"/>
<taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask" classpath="${tomcat_ant_jar}"/>
<taskdef name="remove" classname="org.apache.catalina.ant.RemoveTask" classpath="${tomcat_ant_jar}"/>
<taskdef name="resources" classname="org.apache.catalina.ant.ResourcesTask" classpath="${tomcat_ant_jar}"/>
<taskdef name="roles" classname="org.apache.catalina.ant.RolesTask" classpath="${tomcat_ant_jar}"/>
<taskdef name="start" classname="org.apache.catalina.ant.StartTask" classpath="${tomcat_ant_jar}"/>
<taskdef name="stop" classname="org.apache.catalina.ant.StopTask" classpath="${tomcat_ant_jar}"/>
<taskdef name="undeploy" classname="org.apache.catalina.ant.UndeployTask" classpath="${tomcat_ant_jar}"/>
<target name="tomcat-reload">
<reload url="${url}" username="${username}" password="${password}" path="${path}"/>
</target>
コマンドラインから、次のように実行して、処理が行われることを確認しました。
ant -lib build_lib\commons-net-3.3.jar tomcat-reload
FTPとTomcat再起動をまとめて実施できるように、build.xmlを追記しました。
<target name="deploy" depends="deploy-ftp,tomcat-reload"/>
プロジェクト構成
ここまでで、次のようなプロジェクト構成になりました。Subversionにコミットしておきます。
手順(Jenkins)
ビルドジョブ
新規ジョブを追加して、上記で作成した処理を呼ぶことにします。ジョブの名前は「Tomcat4.1Project01_Build」とし、次のように設定を行いました。
「ソースコード管理」では、次のように設定しました。特別なことは無いと思います。
build.xmlを次のようにして呼び出すことにしました。Eclipse環境と、Jenkinsの環境では、Tomcatのパスが異なることを考慮してあります。
成果物を保存します。テスト環境に配布するモジュールと、配布するためのbuild.xmlなどを含んでいます。
ジョブを実行し、正常に動作することを確認しました。
デプロイジョブ
新規ジョブを追加して、上記で作成した処理を呼ぶことにします。ジョブの名前は「Tomcat4.1Project01_Deploy」とし、次のように設定を行いました。
必要なファイルを、ビルドジョブから、コピーします。
モジュール配布とTomcat再起動を行うためAntを呼び出します。FTPタスクを使用するため、ライブラリの設定を行っています。
ジョブを実行し、正常に動作することを確認しました。
ジョブ起動設定
デプロイジョブ(Tomcat4.1Project01_Deploy)は、ビルドジョブ(Tomcat4.1Project01_Build)の終了後に起動されるように「ビルド・トリガ」を設定します。これで、ビルドジョブのジョブ実行をワンクリックするだけで、最新ソースのチェックアウトから、ビルド、デプロイまで自動化できました。
さらに、ビルドジョブの「ビルド・トリガ」でSubversionを監視するようにすれば、ワンクリックも不要となり、完全自動化もできますね。
今回作成したファイル
上記で記述したファイル類は、次の場所に置いておきました。興味があればご覧ください。
動作確認環境
- 開発環境:Windows 8.1 64bit、Eclipse 4.2、Tomcat 4.1(Windows版)
- テスト環境:Ubuntu 8.04、Tomcat 4.1(Linux版)