目的
Docker上のJenkinsでCIパイプラインを構築する方法について記述します。
JenkinsのUI上での操作を減らし、「"極力"コード化したい」というところに重点を置きました。
お試しで構築した環境なので、実用的でない部分もあるかと思いますが、ご容赦頂ければ幸いです。
備忘録的な側面が強い記事になります!
イメージ
試したこと
A. Jenkinsを立ち上げる
A-1. docker-composeを記述する
起動したDockerコンテナからDocker自体にアクセス(Docker outside of Docker)するために、いくつか変数を渡しています。
また、Jenkinsのmasterとagentの通信を可能にするために、"default"という名前でnetworkを設定します。
version: "3"
services:
jenkins:
container_name: jenkins
restart: always
image: jenkins/jenkins:latest
networks:
- default
user: "${UID}:${GID}"
group_add:
- ${DOCKER_GID}
ports:
- 8080:8080
- 50000:50000
tty: true
volumes:
- ${DOCKER_PATH}:/usr/bin/docker
- /var/run/docker.sock:/var/run/docker.sock
- ./jenkins/home:/var/jenkins_home
A-2. コマンドを実行し、コンテナを起動する
yamlファイル内で変数を参照するために、"docker-compose build" をする前にexportする必要があります。
export DOCKER_GID=`awk -F: '$1 == "docker" {print $3}' /etc/group`
export DOCKER_PATH=`which docker`
export UID=`id -u`
export GID=`id -g`
docker-compose build
docker-compose up -d
B. Pipelineを構築する
B-1. DockerfileとJenkinsfileを新規作成する
この2点はGithubで管理します。
ディレクトリ構成は下記のような形になります。
test-pipeline/
├ .gitignore
├ Dockerfile
├ Jenkinsfile
├ requirements.txt
├ tests/
├ pytest.ini
├ test_sample.py
B-2. Dockerfileでagentの設計図を書く
今回は、Build後にPythonのテストが走ることを想定して、Python3の実行環境を構築します。
FROM python:3.9
USER root
WORKDIR /root/src
COPY requirements.txt /root/src
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
B-3. JenkinsfileでPipelineを記述する
"Build"→"Test"→"Deploy"という流れを表現しています。
pipeline {
// B-2で記述したDockerfileを用いて、コンテナとしてagentを起動する
agent {
dockerfile {
filename 'Dockerfile'
args '--network=default'
}
}
stages {
stage('build'){
steps{
echo "build"
}
// ChromeとEdgeで並行してE2Eテストが実行される
stage('test') {
parallel{
stage("Chrome"){
steps {
sh '''
cd tests/
export SELENIUM_BROWSER_ENV=Chrome
pytest test_sample.py
'''
}
}
stage("Edge"){
steps {
sh '''
cd tests/
export SELENIUM_BROWSER_ENV=Edge
pytest test_sample.py
'''
}
}
}
}
stage('Deploy'){
steps{
echo "deploy"
}
}
}
}
それぞれのStageにおいて、実行するagentを分けることもできます!
(そっちの方が実用的かも、、)
B-4. JenkinsでJobを作成する
"Pipeline script from SCM"を選択し、リポジトリURLはB-1で作成したものを使用します。
あとは作成したPipelineJobにトリガーを設定すれば、CIパイプラインが完成です!
所感
コード化できるものはコード化することで、CIでのJob管理諸々が職人化してしまうことを回避できる可能性を感じました。
IaC(Infrastracture as Code)やPaC(Pipeline as Code)という言葉もあるように、コードで管理することで再現性が高く素早い環境構築ができるようにしていきたいです。
こういった設計図のひな形のようなものを資産として持っておくと、チームとしてちょっとした強みになっていくと思います。
参考
https://qiita.com/hiroyuki_onodera/items/c6c6e6163d61ddf4dd5c
https://qiita.com/dublog/items/38831adf42e3cfeed66a