Docker版JenkinsでのアップグレードTips

Dockerのjenkins:2.60.3-alpineを利用しているが、Dockerのイメージが1年ほど更新されていない状況。
そのためJenkinsのUI（ブラウザーから開いた管理画面）からアップデートをかけたところ、思わぬところで躓いたため、対応を残しておく。
https://hub.docker.com/r/library/jenkins/tags/

（注意）以降に記載した対応が公式のJenkins Dockerイメージとして推奨/サポートする対応かどうかは未確認である。Docker Hubに公開されている文書上からはブラウザー上からのアップデート操作を想定していない可能性も考えられる。

##前提
* Docker 17.05.0-ce
* docker-compose 1.8.0  
* jenkins:2.60.3-alpine
* 自分のDocker環境で（当初）永続化していたディレクトリーは以下

> /var/jenkins_home/

* DockerHub上のガイドではアップグレードに関する記載は以下となっている
 ![jenkins000001.JPG](https://qiita-image-store.s3.amazonaws.com/0/270508/1bf39372-b8c3-60ea-b3ab-cbc4981c2dd8.jpeg)


## 現象
* ブラウザーからUI上でJenkinsのアップデートをかけバージョンアップした
* 普段のバックアップはdocker stopコマンドで停止した状態で実行しており、アップグレード後にdocker-compose downは未実行
* ある日、別件のメンテナンスでdocker-compose downして作業を行いdocker-compose up --build -dを実行したところjenkinsにログインできない状況となった
    * エラー「XmlPullParserException」が発生

## 1次調査
* エラー・ログの出力は以下

> org.xmlpull.v1.XmlPullParserException: only 1.0 is supported as <?xml version not '1.1' (position: START_DOCUMENT seen <?xml version=\'1.1\'... @1:1

* エラーが表示されたファイルのxmlのバージョンを1.0に修正し再起動すると該当するエラー・メッセージは消えるが、別のファイル（中身はxml 1.1）のエラーが表示された
* xml v1.1となっているファイルを検索するとアップグレード作業を行った日のタイムスタンプとなっている
* v2.105からjenkinsが生成するファイルが1.1対応になっている
    * https://jenkins.io/changelog/#v2.105
    * https://jenkins.io/doc/upgrade-guide/2.107/

* まともに起動しない状態をとりあえず解消するべきxml 1.1の記述を一通り1.0に戻す
    * 下記はコマンドの例（へっぽこですが）

```cmd:
$ sudo grep -rnw srv/jenkins/var/jenkins_home/ --include="*.xml" -e "xml version='1.1'"
$ sudo grep -rl srv/jenkins/var/jenkins_home/ --include="*.xml" -e "xml version='1.1'" |
sudo xargs -n 1 -I{} cp {} {}.bk
$ sudo grep -rl srv/jenkins/var/jenkins_home/ --include="*.xml" -e "xml version='1.1'"
$ sudo grep -lr srv/jenkins/var/jenkins_home/ --include="*.xml" -e "xml version='1.1'" |
sudo xargs sed -i 's/1.1/1.0/'
$ sudo grep -rl srv/jenkins/var/jenkins_home/ --include="*.xml" -e "xml version='1.1'"
```
 
* docker-compose up --build dを実行し起動
    * この時点ではJenkins ver 2.60.3
    ![jenkins000002.JPG](https://qiita-image-store.s3.amazonaws.com/0/270508/eb05bd96-05ea-81a7-441b-69631e238577.jpeg)

* ブラウザーからアップデートを実行
    * 管理画面から「Or Upgrade Automatically」ボタンをクリックしてアップグレードを実行する
    ![jenkins000003.JPG](https://qiita-image-store.s3.amazonaws.com/0/270508/b922f4f0-3bf9-09d0-18f7-b6cbebe90da9.jpeg)

* アップグレードは正常に完了する
* docker-compose down し、docker-compose up -d （--buildなしでも）を実行するとXmlPullParserExceptionが再発する

## 原因の推測
* 新しいバージョンのjenkins.warファイルがダウンロードおよび展開されているディレクトリーが**永続化されてない**可能性が高い    

## 2次調査
* docker-compose down
* xmlファイルを全て1.0に戻す（grepとsedで一括置換）

```cmd:
$ sudo grep -lr srv/jenkins/var/jenkins_home/ --include="*.xml" -e "xml version='1.1'" |
sudo xargs sed -i 's/1.1/1.0/'
$
```
* docker-compose up --build -d
* コンテナに「docker exec -it <container name> /bin/bash」でログインしwarのディレクトリーを調査
    * 「/usr/share/jenkins/jenkins.war」（warファイルの配置先と推測）
    * 「/var/cache/jenkins/war」（warの展開先と推測）

```cmd:
$ docker exec -it jenkins_1 /bin/bash
bash-4.3# find / -name *war* -type d
/var/cache/jenkins/war
/var/cache/jenkins/war/META-INF/maven/org.jenkins-ci.main/jenkins-war
/tmp/jetty-0.0.0.0-8080-war-_jenkins-any-781527918347635117.dir
/tmp/jetty-0.0.0.0-8080-war-_jenkins-any-2252951103130751390.dir
/tmp/jetty-0.0.0.0-8080-war-_jenkins-any-5296010582638823514.dir
/lib/firmware
/sys/bus/acpi/drivers/hardware_error_device
/sys/devices/software
/sys/class/firmware
/sys/firmware
/sys/module/firmware_class
bash-4.3# find / -name *.war -type f
/usr/share/jenkins/jenkins.war
bash-4.3# exit
$
```
* docker cpコマンドでコンテナ内の該当するディレクトリー（2つ）をDockerホスト上に取得する

```cmd:
$ mkdir -p .srv/jenkins/var/cache
$ mkdir -p .srv/jenkins/var/cache/jenkins/
$ docker cp jenkins_1:/var/cache/jenkins/war ./srv/jenkins/var/cache/jenkins/
$ docker cp jenkins_1:/usr/share/jenkins ./srv/jenkins/usr/share/
```
* docker-compose.ymlを編集しjenkinsのコンテナの永続化ボリュームを2つ追加する

```cmd:
./srv/jenkins/var/cache/jenkins/war:/var/cache/jenkins/war
./srv/jenkins/usr/share/jenkins:/usr/share/jenkins
```
* docker-compose up --build -dを実行
* ブラウザー上からjenkinsのアップグレードを実行
* docker-compose downを実行
* docker-compose up -dを実行
* jenkinsは正常に起動し、アップグレードしたバージョンが維持されている

## まとめ
* DockerのJenkins（公式）イメージはブラウザーのボタンから実行したアップグレードについては想定していない可能性が高い
* 無理やり最新版を利用したい場合には永続化ボリュームの見直しが必要になる