デトフィア

プログラミング

Dockerコンテナに作成したJenkinsからDockerコンテナのTomcatにwarファイルをデプロイする

以前書いた記事

DockerとJenkinsでJavaプロジェクトのコンパイル等してwarファイルのデプロイをする - Qiita

この記事ではTomcat環境をDockerコンテナで作成して、そこに同じくDockerコンテナで作成したJenkins環境からデプロイを行うということをやりました。 流れとしてはこうです

  1. Githubにソースをpushする
  2. Jenkinsのジョブを実行する(手動)
  3. テストやビルドを通してwarファイルがtomcatコンテナにデプロイされる

今回はMavenでやっていたのをgradleにして、Jenkinsの環境も新しく2.376で実施します。

また以前の記事では色々と省略していたので詳しく記事にしていこうと思います。

記事の流れ

  • コンテナの準備
    • tomcatとjenkinsのコンテナを作成します
  • tomcatの設定
    • ユーザーとロールの設定
    • Webアプリケーションマネージャの設定
  • Jenkinsの設定
    • ジョブの作成
    • 認証情報の作成
    • パイプラインスクリプトの記載

予め対象となるソースはGitHubにアップロードしておきます。

コンテナの準備

以下のフォルダ構成でファイルを準備します。

D:.
│  docker-compose.yaml
│
├─jenkins
│  └─data
└─tomcat
        Dockerfile

Dockerfile

FROM tomcat:9.0
RUN apt-get update && apt-get install -y wget && apt-get install -y vim

Docker-compose.yaml

version: '3'
services: 
  tomcat:
    build:
      context: .
      dockerfile: ./tomcat/Dockerfile
    container_name: tomcat
    privileged: true
    ports:
      - "8012:8080"
    volumes:
      - "./tomcat/data:/var"
    tty: true
  jenkins:
    container_name: jenkins
    image: jenkins/jenkins:alpine
    ports:
      - "8888:8080"
    volumes: 
      - "./jenkins/data:/var/jenkins_home"
    tty: true

コンテナを立ち上げます

docker-compose up -d

D:\docker\tomcatjenkins>docker-compose up -d
Docker Compose is now in the Docker CLI, try `docker compose up`

Creating network "tomcatjenkins_default" with the default driver
Building tomcat
[+] Building 9.6s (6/6) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                                    0.1s
 => => transferring dockerfile: 125B                                                                                                                                                    0.0s
 => [internal] load .dockerignore                                                                                                                                                       0.0s
 => => transferring context: 2B                                                                                                                                                         0.0s
 => [internal] load metadata for docker.io/library/tomcat:9.0                                                                                                                           0.0s
 => [1/2] FROM docker.io/library/tomcat:9.0                                                                                                                                             0.1s
 => [2/2] RUN apt-get update && apt-get install -y wget && apt-get install -y vim                                                                                                       9.1s
 => exporting to image                                                                                                                                                                  0.4s
 => => exporting layers                                                                                                                                                                 0.4s
 => => writing image sha256:56eab31fdeaae33f66468f60f0970fec539bb430f7ed6e2d478e3252bb8e9331                                                                                            0.0s
 => => naming to docker.io/library/tomcatjenkins_tomcat                                                                                                                                 0.0s
WARNING: Image for service tomcat was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating tomcat  ... done
Creating jenkins ... done

D:\docker\tomcatjenkins>

Tomcatの設定

ユーザーとロールを追加しておきます tomcat-users.xmlというファイルを修正します。Tomcatコンテナに入って直接修正します。 vimは事前にインストール済ですので利用可能です。

D:\docker\tomcatjenkins>docker exec -it tomcat bash
root@03442bc6f07e:/usr/local/tomcat#
root@03442bc6f07e:/usr/local/tomcat# find / -name tomcat-users.xml
/usr/local/tomcat/conf/tomcat-users.xml
root@03442bc6f07e:/usr/local/tomcat# vim /usr/local/tomcat/conf/tomcat-users.xml
root@03442bc6f07e:/usr/local/tomcat#

ファイルの最後の方に以下を追加しておきます

          <role rolename="manager-gui"/>
          <role rolename="admin-gui"/>
          <role rolename="manager-script"/>
          <user username="misaka" password="password" roles="manager-gui,admin-gui,manager-script"/>
</tomcat-users>

現状のwebappsフォルダには何もありません。

root@03442bc6f07e:/usr/local/tomcat# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE  NOTICE  README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  webapps.dist  work
root@03442bc6f07e:/usr/local/tomcat# cd webapps
root@03442bc6f07e:/usr/local/tomcat/webapps# ls
root@03442bc6f07e:/usr/local/tomcat/webapps#

webapps.distフォルダには色々入っているので必要であればコピーすることで利用可能です。

root@03442bc6f07e:/usr/local/tomcat# cd webapps.dist
root@03442bc6f07e:/usr/local/tomcat/webapps.dist# ls
ROOT  docs  examples  host-manager  manager

webapps.distのmanagerをwebappsにコピーします

root@03442bc6f07e:/usr/local/tomcat# cp -r webapps.dist/manager webapps
root@03442bc6f07e:/usr/local/tomcat#
root@03442bc6f07e:/usr/local/tomcat# ls webapps
manager

そして許可するIPアドレスを修正します。(全てのIPアドレスを許可するように修正)

root@03442bc6f07e:/usr/local/tomcat# find ./ -name context.xml
./conf/context.xml
./webapps/manager/META-INF/context.xml
./webapps.dist/manager/META-INF/context.xml
./webapps.dist/examples/META-INF/context.xml
./webapps.dist/host-manager/META-INF/context.xml
root@03442bc6f07e:/usr/local/tomcat#
root@03442bc6f07e:/usr/local/tomcat# vim ./webapps/manager/META-INF/context.xml

以下のようにallowとなっている部分のValveをコメントアウトします

          <!--
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
                  allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
          -->
  <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>

この2つをやらないと/managerにアクセスした時に403エラーが返ってきます

  • tomcat-users.xmlにアカウントを追加
  • context.xmlの許可アドレスを修正

Jenkinsの設定

次にJenkinsの設定を行います。 コンテナは立ち上がっている状態なので、以下にアクセスします

http://localhost:8888/

初期設定が必要になります

パスワードを/var/jenkins_home/secrets/initialAdminPasswordから取得して入力する必要があります。

コンテナに入ってcatコマンドを実行してもいいですが、コンテナに入らずに実行します。 execコマンドにコンテナ名とコマンドを渡してあげます

D:\docker\tomcatjenkins>docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
df8b97707cea464face45e640f0abfe7

ここで取得したキーを入力します

オススメのプラグインをインストールするをクリック(左)して、初期設定を行います。

ここで古いJenkinsを利用しているとプラグインのインストールに失敗するようです。 私は2.303でエラーになりました。 と思ってlatestを利用しても同じようなエラー。迷っていると以下の記事に遭遇しました

Jenkinsのdockerイメージは、Docker公式とJenkins公式の2つあるのか… - 新しいことにはウェルカム なるほど。。

任意のユーザーを作成してJenkinsの開始を行います。

Deploy to container プラグインのインストール

Deploy to containerというプラグインをインストールします

Jenkinsの管理 > プラグインマネージャー > 利用可能

検索ワードに「Deploy to container」と入力

installにチェックを入れてinstall without restartを押します

パイプラインジョブの作成

パイプラインジョブを任意の名前で作成したら、GitHub projectにチェックを入れてURLを指定します。 一旦これだけの設定で保存しておきます

次のジョブの画面からPipeline Syntaxをクリックします。

ContainersにTomcat9.x Remoteを選択して、Credentialsの追加を押下します

認証情報の追加でDomainを「グローバルドメイン」を選択して、種類に「ユーザー名とパスワード」を選択します。

ここではtomcatで作成したユーザーとパスワードを指定します。IDは任意のものを入力して追加ボタンを押下します

その後、ContainersのCredentialsに追加した認証情報を指定します

このTomcatのURLはコンテナのIPアドレスと、そのコンテナで動いているTomcatのポート番号を指定します

今回の場合ホスト側でアクセスする時のアドレスではないことに気を付けてください

TomcatのURLを入力したらGenerate Pipeline Scriptボタンを押します。
このスクリプトはデプロイステージで利用しますのでメモしておきます。

deploy adapters: [tomcat9(credentialsId: 'tomcat_misaka', path: '', url: 'http://172.31.0.2:8080')], contextPath: null, war: '**/*.war'

ジョブの画面から設定を押してジョブの修正を行います。

設定画面の下にパイプラインという項目を修正します。

定義に「Pipeline script」を選択します

以下のコードを入力します

pipeline { 
    agent any 
    options {
        skipStagesAfterUnstable()
    }
    stages {
        stage('Build') { 
            steps {
                echo 'Start gradle Build..' 
                checkout([$class: 'GitSCM', branches: [[name: '*/main']],
                userRemoteConfigs: [[url: 'https://github.com/jirentaicho/jenkins-test']]])
                sh 'chmod +x gradlew'
                sh './gradlew build'
                echo 'Deploy..'
                deploy adapters: [tomcat9(credentialsId: 'tomcat_misaka', path: '', url: 'http://172.31.0.2:8080')], contextPath: null, war: '**/*.war'
            }
        }
    }
}

deploy adapters: の部分はgenerateで出力したコードの部分です。 どの認証情報で、どのパスに、どのwarファイルをデプロイするかを指定しています。

gradle buildを行うと一通り実行してくれるのでbuildだけを行っています

実行して正常に終了してくれるのを待ちます

成功すると緑色で、失敗すると赤色で表示されます。 もし失敗した場合はログを確認します。

ビルド履歴の#番号の個所をクリックします

Console Outputを押すと実行ログがを見ることができます

これは接続拒否されていました。 →原因はポート番号に誤りがありました。

他にもURLが間違っているとTimeoutになっていたりします。

成功してTomcatのWebアプリケーションマネージャを利用するとデプロイができていることがわかります

またアプリケーションも確認します

テストの失敗

失敗するテストケースをgithubにpushしてjenkinsを動かしてみます。 gradleのtestで失敗するはずです。

    @Test
    public void test_fail(){
        assertTrue(false);
    }

予想通り失敗しています

詳細のログを確認してみます

テストで失敗してることがわかります。

おまけ

docker-composeでコンテナの停止から削除

D:\docker\tomcatjenkins>docker-compose stop jenkins
Stopping jenkins ... done

D:\docker\tomcatjenkins>docker-compose rm jenkins
Going to remove jenkins
Are you sure? [yN] y
Removing jenkins ... done