はじめに
今回はLinuxサーバ環境で半ば無理やりCI環境を構築して.NETプラットフォームのアプリケーションをCIするという誰が得をするのだろうという内容の話です。
具体的に言うと、GitBucketでソースコードをホストして、GitBucketにプッシュされたときにJenkinsでビルド+テスト実行を行うというごくありふれた内容です。 こいつらをDocker上に構築します。
+-------------------+ +-------------------+
| GitBucket | -- (2)web hook --> | Jenkins |-----
-->| 192.168.0.10:8080 | | 192.168.0.10:8090 | |
| +-------------------+ ---------- +-------------------+<-- |
| | | |
| (1)push | (4)pull | | (3)order
| | (6)return result | |
| | | |
| +-------------------+ | +-------------------+ | |
---| Windows Client | --------->| Jenkins Slave |--- |
+-------------------+ | 192.168.0.10:9000 | |
+-------------------+<----
(5)build & test
余談ですが、最初はいつも通り『VB.NETでも〜』という内容にしようと思ったのですが、xbuildがvbprojをどうしてもビルドしたくないと言うので急遽C#殿にお越しいただきました。
環境
とりあえず以下の環境を使用しました。
- Ubuntu 16.04
- Docker 1.12.1
- docker-compose 1.8.1
- Jenkins 2.19.1
- GitBucket 4.5.0
- Mono 4.6.1
- Visual Studio 2015 Community update 3
- .NET Framework 4.5.2
- ReSharper 2016.02
- NUnit 3.5.0
- Nuit.ConsoleRunner 3.4.1
セットアップ
Docker・docker-compose
公式マニュアルを以下略。
Jenkins・GitBucket・Jenkinsビルドスレーブ環境構築
まずはGitBuckt環境を構築しましょう。
こちらは特に変わったことはしてません。openjdk-8-jre-alpineをベースにGitBucketのバイナリをダウンロードして実行しているだけです。
FROM java:openjdk-8-jre-alpine ADD https://github.com/gitbucket/gitbucket/releases/download/4.5/gitbucket.war /opt/gitbucket/gitbucket.war VOLUME /srv/gitbucket EXPOSE 8080 CMD ["java", "-jar", "/opt/gitbucket/gitbucket.war", "--gitbucket.home=/srv/gitbucket"]
Jenkinsは公式イメージを使用しています。
ただ、公式イメージにはMonoの環境が入っておらず、途中でユーザを切り替えてるせいで公式イメージをベースにMono環境を追加するという手法も使えなかったので、別途Monoをインストールしたコンテナをスレーブとして使用しています。(クソポイントその1)
ubuntu:16.04をベースにビルド及びテスト実行のためのMono、Jenkinsスレーブデーモンを動かすためのJava、Jenkinsのスレーブとして動作させるためにDockerでは禁忌とされているSSHサーバをインストールしています。(クソポイントその2)
何処かで見たことがあると思ったあなた。素晴らしいです。先頭部分はbuildpack-deps:jessie-scmからパクって拝借してきました。
あとはNuGetにパッケージの復元を許可するためにEnableNuGetPackageRestoreをTRUEに設定しています。
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
wget \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y --no-install-recommends \
bzr \
git \
mercurial \
openssh-client \
subversion \
\
procps \
&& rm -rf /var/lib/apt/lists/*
RUN set -x \
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF \
&& echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list \
# && echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list \
&& echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list \
&& apt-get update \
&& apt-get -y install mono-complete openjdk-8-jdk \
&& rm -rf /var/lib/apt/lists/*
RUN set -x \
&& apt-get update \
&& apt-get install -y openssh-server \
&& rm -rf /var/lib/apt/lists/*
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
ENV EnableNuGetPackageRestore TRUE
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
あとはこれらのコンテナを上げたり下げたりビルドする為のdocker-compose.ymlをでっち上げれば構築は完了です。
version: '2'
services:
gitbucket-websrv:
build: './gitbucket'
ports:
- '8080:8080'
volumes:
- '/srv/mono-ci/gitbucket:/srv/gitbucket'
jenkins:
image: 'jenkins:2.19.1'
ports:
- '8090:8080'
- '50000:50000'
volumes:
- '/srv/mono-ci/jenkins:/var/jenkins_home'
jenkins-slave-mono:
build: './jenkins-slave-mono'
ports:
- '9000:22'
ちなみにこれらの環境を構築するだけなら10秒*1で終わります。
git clone https://github.com/jyuch/mono-ci.git cd mono-ci docker-compose up
Jenkins・GitBucket初期設定
GitBucket
GitBucketにroot:rootでログインし、自身の作業用アカウントとJenkins用のアカウントを作成しましょう。
Jenkinsアカウントはコントリビューターになれれば良いので管理者でなくても大丈夫です。
Jenkins
アカウント登録後のプラグイン選択画面ではとりあえずおすすめをインストールしておきましよう。
その後、管理画面より以下のプラグインをインストールします。
- GitBucket Plugin
- NUnit plugin
その後はJenkinsの管理 > ノードの管理よりスレーブノードを登録します。
今回の構成ですとSSHポートは9000なのでそこだけは注意が必要です。
最後にCSRF対策のチェックボックスを外します。セキュリティを切るのはいささか気が引けますがこの作業をしないとGitBucketからのweb hookが通らないのでまぁ仕方ないのかなと自分の中で折り合いを付けながらチェックボックスを外すか別のいい感じの方法を探して下さい。いい感じの方法がありましたら教えてください。
ここまでで初期セットアップは完了です。お疲れ様でした。
*1:イメージのプル・ビルド時間を除く