jenkins+dockerでDjangoアプリのunittestをCIする

最終更新日時:2020-12-30 23:26

初版公開日時:2020-12-30 23:26


昨日の記事 でDjangoアプリのunittestをがんばって実装しました。となると次はCIです(CDはまた今後の機会に)。


CIの草の根といえばJenkinsが始まりなのかもしれません(Jenkinsがはやり始めた後にクラウドでCI/CDのサービスを見かけるようになった気がします)。自宅のPCサーバで動くOSSなものといえば、JenkinsとGitlabがあるのかなと思いますがGitlabは大きなソフトですし、自宅wiki兼gitサーバはいまだにtracなのでJenkinsをとりあえず使ってみています。


今までJenkinsではShiningPanda Pluginというのを使ってvirtualenvな環境でpythonアプリをunittestをしていました。この場合、Jenkinsサーバ自体にアプリが必要とするOSのパッケージを入れる必要があり、Jenkinsサーバの移行が結構大変だった記憶があります。できればnittestの環境はdockerコンテナ内で完結するようにしてJenkinsサーバ(=ホストサーバ)を汚さないようにしたいです。


JenkinsでDockerを使ってCIするにはDocker PluginやDocker Slaves Pluginというプラグインがあるようなのですが、webを調べてみても結構複雑な使い方をしている人が多いように思いました。あまり複雑なことはしたくないため、webの断片的な情報を集めて原始的な使い方をしてみました。


以下の雰囲気の流れでJenkinsのプロジェクトからdockerコンテナを呼び出してunittestをする環境を構築するようにしてみました。

  • 仮想サーバにDebian 10をインストール

  • Jenkinsをインストール
    • Jenkins Coberturaプラグインをインストール(coverage.xmlというレポートファイルを読み込みプラグイン)

  • dockerをインストール

  • webアプリケーションのunittest用のdockerコンテナをビルドするDockerfileを作成
    • webアプリケーションで必要とするOSのパッケージをインストールしておく

    • Djangoのデータベースはmariadbを使っているため、mariadb-serverをインストールしておく

    • build時にCREATE DATABASE、mariadbのユーザ追加(GRANT)を実行しておく

    • pipによるpythonライブラリのインストールはbuild時にはせず、jenkinsの実行時に行う

FROM debian:10

RUN apt-get update

RUN apt-get install -y locales git
RUN apt-get clean
RUN echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen
RUN locale-gen

# for web application.
RUN apt-get install -y python3 python3-dev python3-setuptools python3-pip default-libmysqlclient-dev gcc make
RUN apt-get clean

RUN apt-get install -y mariadb-server
RUN apt-get clean

# setup user account for unittest.
RUN /usr/bin/mysql_install_db
RUN (/usr/bin/mysqld_safe &) && sleep 5s && \
   mysql --execute='CREATE DATABASE ★database名★ DEFAULT CHARACTER SET utf8mb4' && \
   mysql --execute='GRANT ALL ON *.* TO ★DBユーザ名★@localhost IDENTIFIED BY "★DBパスワード★"'
  • docker buildして、webアプリケーションのunittest用のdockerコンテナを生成

  • Jenkinsのプロジェクトを作成

  • プロジェクト設定にあるgitリポジトリの設定には何も設定しない

  • 「ビルド」の設定
    • ワンライナーでmariadb-serverの起動、git clone、unittestの実行、coverage.xmlをJenkinsホストへ渡すようコピー、と処理しています

docker run -v ${JENKINS_HOME}/workspace/${JOB_NAME}:/mnt ★dockerコンテナのタグ名★ \
 sh -c "(/usr/bin/mysqld_safe &) && \
 git clone git://192.168.xxx.xxx/★gitリポジトリ名★.git && \
 cd ★gitリポジトリ名★ && \
 sh unittest.sh jenkins-docker && \
 cp -fv coverage.xml /mnt/"
  • 「ビルド後の処理」
    • Cobertura XMLレポート パターンに"coverage.xml"と入力

  • Jenkinsでビルドを実行
    • unittestが完了すると、カバレッジのレポートのメニューが表示されます。


みなさまもCIライフをお楽しみください。


auther: dictoss

地元の北海道から流れて大阪へ行き、現在は東京でお仕事中。 仕事ではCentOS、家ではDebianとFreeBSDを使い何かしようと画策中。

github.com