DockerコンテナでJenkinsを動かす

[こちら](http://techblog.yahoo.co.jp/event/jenkins-with-docker/ "第8回Jenkins勉強会で「Jenkins with Docker」というLTをしました #jenkinsstudy") で紹介されているように、ジョブ単位で Docker のイメージを作成する方が一般的なのだろうが、個人でちょっとした作業用に Jenkins を使う場合はDocker コンテナ上に直接 Jenkins をインストールしても良さそうな気がしたので Docker のコンテナ（ CentOS 6 ）で yum からインストールした Jenkins を動かす Dockerfile を作った。

その際にいろいろハマったのでメモ。

# yumでJenkinsをインストール

これは特に問題ない。

Open JDK を入れてから、 [マニュアル](https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins+on+Red+Hat+distributions "Installing Jenkins on Red Hat distributions") 通りのコマンドを Dockerfile へ書けばよい。

```
# Install Open JDK 7
RUN yum -y install java-1.7.0-openjdk &&\
    yum -y clean all

# Install Jenkins
RUN wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo &&\
    rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key &&\
    yum -y install jenkins &&\
    yum -y clean all
```

# Jenkinsの起動

まずここでハマった。

Dockerfile 内に `RUN service jenkins start` と書いてビルドしても、コンテナ起動時にサービスが立ち上がっていなかった。

起動したいプロセスをフォアグラウンドで起動するか、supervisord を使うかしないといけないらしい。後者は設定がめんどくさそうなので、前者を採用。

[こちら](https://github.com/jonhadfield/docker-jenkins) を参考に、ログファイルが生成されるまで待ってから tail コマンドでログファイルを監視し続けることでフォアグラウンドを維持している。

warファイルを `java` コマンドで直接起動してもフォアグランドで動かすことができる（コメント欄参照）。

あわせて `EXPOSE` で8080番ポートを指定してホスト側からJenkinsにアクセスできるようにする。

```
EXPOSE 8080
ENTRYPOINT service jenkins start &&\
    sleep 5 &&\
    tail -f /var/log/jenkins/jenkins.log
```

# タイムゾーンの設定

ベースにするイメージにもよるが、CentOS の Official images ではタイムゾーンの設定をする必要がある。

```
# Time Zone
RUN echo 'ZONE="Asia/Tokyo"' > /etc/sysconfig/clock

RUN yum -y install ntp &&\
    yum -y clean all
RUN rm -f /etc/localtime
RUN ln -fs /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
RUN ntpdate ntp.nict.jp
```

# プラグインの配置

手動でインストールするのは面倒なので、必要なプラグインは事前にインストールしておきたい。そのため、イメージ作成時に `/var/lib/jenkins/plugins` へ使いたいプラグインを配置しておく。

このとき、配置したファイルの所有者を jenkins ユーザーにする。Dockerfile に書いたコマンドはデフォルトで root ユーザーで実行されるため、 Jenkins の起動時に permission error となってしまう。これに気づかずプラグインが使えなくなってハマった。

```
# Install Jenkins Plugins
RUN wget -nv -t 3 -P /var/lib/jenkins/plugins \
        https://updates.jenkins-ci.org/latest/scm-api.hpi &&\
    wget -nv -t 3 -P /var/lib/jenkins/plugins \
        https://updates.jenkins-ci.org/latest/git-client.hpi &&\
    wget -nv -t 3 -P /var/lib/jenkins/plugins \
        https://updates.jenkins-ci.org/latest/git.hpi &&\
    wget -nv -t 3 -P /var/lib/jenkins/plugins \
        https://updates.jenkins-ci.org/latest/ansicolor.hpi &&\
    chown -R jenkins:jenkins /var/lib/jenkins/plugins
```

# まとめ

最終的に Dockerfile は以下のようになった。

```:Dockerfile
FROM centos:6.4

ENV LANG en_US.UTF-8

# Upgrade to latest version
RUN rpm -Uvh http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm &&\
    yum -y upgrade

# Install core modules
RUN yum -y install curl ntp sudo unzip wget &&\
    yum -y clean all

# Time Zone
RUN echo 'ZONE="Asia/Tokyo"' > /etc/sysconfig/clock

RUN rm -f /etc/localtime
RUN ln -fs /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
RUN ntpdate ntp.nict.jp

# Install Open JDK 7
RUN yum -y install java-1.7.0-openjdk &&\
    yum -y clean all

# Install Jenkins
RUN groupadd -g 1001 jenkins
RUN useradd -c "Jenkins Continuous Build server" \
        -u 1001 -g 1001 -d /var/lib/jenkins -s /bin/bash jenkins
RUN wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo &&\
    rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key &&\
    yum -y install jenkins &&\
    yum -y clean all

# Install Jenkins Plugins
RUN wget -nv -T 60 -t 3 -P /var/lib/jenkins/plugins \
        https://updates.jenkins-ci.org/latest/scm-api.hpi &&\
    wget -nv -T 60 -t 3 -P /var/lib/jenkins/plugins \
        https://updates.jenkins-ci.org/latest/git-client.hpi &&\
    wget -nv -T 60 -t 3 -P /var/lib/jenkins/plugins \
        https://updates.jenkins-ci.org/latest/git.hpi &&\
    wget -nv -T 60 -t 3 -P /var/lib/jenkins/plugins \
        https://updates.jenkins-ci.org/latest/ansicolor.hpi &&\
    chown -R jenkins:jenkins /var/lib/jenkins/plugins

# Install Subversion
RUN yum -y install subversion &&\
    yum -y clean all

# Install Git
RUN yum -y install git &&\
    yum -y clean all

EXPOSE 8080
ENTRYPOINT service jenkins start &&\
    sleep 5 &&\
    tail -f /var/log/jenkins/jenkins.log
```

イメージを作成して、ポートフォワードの指定をして起動する。 Mac で boot2docker を使用している場合は VirtualBox の設定も必要となる。

```console
docker build -t me/jenkins .
docker run -d -p 8080:8080 me/jenkins
```

ブラウザから `http://localhost:8080/` へアクセスすれば Jenkins のダッシュボードが表示される。