
Docker上でアプリケーション開発から運用まで完結させる開発スタイルは今まさに求められています。今回はDocker前提としてDevOpsのCI/CDを実現させるために、JenkinsにDockerをインストールしてパイプラインで自動ビルドする方法を紹介します。
はじめに
以前の記事「爆速でJenkinsをマスターしよう(NodeJS編)」では、Jenkinsの基本的なインストール方法から始まり、Job DSLによる新しいジョブの作成方法、NodeJSアプリケーションの自動テスト方法、GitHubのコミットをトリガーにした自動ビルド方法を爆速で紹介しました。
今回は、JenkinsにDockerをインストールして、Jod DSLでパイプラインジョブを追加し、Jenkins Pipelineで自動ビルドする方法を紹介します。
前提
以下の準備が完了している必要があります。
- Dockerがインストールされていること
- GitHubのアカウントがあること
- DockerHubのアカウントがあること
詳しいバージョンは「環境」を参照してください。
Docker入りのJenkinsのセットアップ
まずはDockerコマンドを使えるようにしたJenkinsをセットアップしましょう。
ベースを作る
必要なフォルダとファイルを作りましょう。
$ mkdir devops_jenkins_docker
$ cd devops_jenkins_docker
$ touch Dockerfile
$ touch docker-compose.yml
Dockerファイルを作る
Dockerfile
以下のようにDocker CEをJenkins内にインストールするようにします。
FROM jenkins
USER root
RUN apt-get update \
&& apt-get install -y \
apt-utils \
apt-transport-https \
ca-certificates \
curl \
software-properties-common \
&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - \
&& apt-key fingerprint 0EBFCD88 \
&& add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable" \
&& apt-get update \
&& apt-get install -y docker-ce \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& usermod -aG docker jenkins
RUN cd tmp/ \
&& wget https://updates.jenkins-ci.org/latest/jenkins.war \
&& mv ./jenkins.war /usr/share/jenkins/
USER jenkins
docker-compose.yml
Dockerコンテナ上でDockerコマンドを実行するために「/var/run/docker.sock」のボリュームを設定します。
version: "3"
services:
jenkins:
build: .
ports:
- 8080:8080
volumes:
- ./jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
Jenkinsの起動
それではDockerからJenkinsを起動しましょう。「/var/run/docker.sock」の権限変更を忘れずに行いましょう。
$ docker-compose up --build -d
$ docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------------------------------
devops_jenkins_docker_jenkins_1 /bin/tini -- /usr/local/bi ... Up 50000/tcp, 0.0.0.0:8080->8080/tcp
$ docker-compose exec -u root jenkins chmod 666 /var/run/docker.sock
$ docker-compose logs -f jenkins
...
jenkins_1 | *************************************************************
jenkins_1 | *************************************************************
jenkins_1 | *************************************************************
jenkins_1 |
jenkins_1 | Jenkins initial setup is required. An admin user has been created and a password generated.
jenkins_1 | Please use the following password to proceed to installation:
jenkins_1 |
jenkins_1 | c834fdf8220943fab0454f1f0ff823ea
jenkins_1 |
jenkins_1 | This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
jenkins_1 |
jenkins_1 | *************************************************************
jenkins_1 | *************************************************************
jenkins_1 | *************************************************************
...
初期化キーとして「c834fdf8220943fab0454f1f0ff823ea」をメモしておきます。
Jenkinsのセットアップ
ブラウザで「localhost:8080」にアクセスして、セットアップを完了します。
Jenkinsのインストールが完了しました。
Dockerの動作確認
JenkinsからDockerが実行できるかテストしましょう。
ホーム画面から「新しいジョブ」をクリックします。
任意のジョブ名(今回は「test_docker」)を入力し、「パイプライン」を選択し、「OK」をクリックします。
「パイプライン」から「Pipeline script」を選択し、以下の「Script」を入力し、「保存」をクリックします。
node {
docker.image('alpine:latest').inside {
sh 'echo Hello Docker!'
}
}
「ビルド実行」をクリックしてテストを実行します。
ビルドが成功しました。
これでDockerがJenkinsから実行されていることを確認できました。
DockerHub用の認証情報の追加
今回は最終的にビルドしたDockerイメージをDockerHub上にPushするので、DockerHubのアカウント情報をJenkinsに追加する必要があります。
ホーム画面から「認証情報」をクリックします。
「Jenkins」をクリックします。
「グローバルドメイン」から「Add credentials」をクリックします。
「ユーザー名とパスワード」を選択し、DockerHubのアカウントのユーザ名とパスワードを入力し、任意のID(今回は「dockerhub-credentials」)を付けて、「保存」をクリックします。
追加した認証情報が表示されています。
Job DSL用のプラグインを追加
後でJob DSLを使うので、プラグインをインストールします。
Jenkinsの再起動が完了すればOKです。
サンプルDockerアプリケーションの作成
ベースの作成
以前の記事「爆速でJenkinsをマスターしよう(NodeJS編)」で作成したNodeJSアプリケーションをそのままDocker化して使いましょう。
$ git clone https://github.com/{your-github-account}/devops_sample_nodejs.git
$ cd devops_sample_nodejs
$ touch Dockerfile
NodeJSアプリケーションのDocker化
Docker化して動作確認をしましょう。
Dockerfile
Dockerfileを以下のように書きます。
FROM node:11-alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
RUN npm install
COPY ./ ./
CMD npm start
ビルドと実行
Dockerとしてビルドができ、Docker上でコマンドが実行できることを確認しましょう。
$ docker image build -t devops_sample_nodejs:latest .
$ docker container run devops_sample_nodejs:latest
...
Next year is 2019.
2 years until Tokyo Olympic.
The tax of 100 yen is 10 yen if the tax rate is 10%.
I baked 10 cookies. There're 5 people here so you can eat 2.
$ docker container run devops_sample_nodejs:latest npm test
...
PASS test/utis.spec.js
utils test
math test
✓ should be 3 when adding 1 and 2 (7ms)
✓ should be -1 when subtracting 2 from 1
✓ should be 12 when multipying 3 by 4 (1ms)
✓ should be 4 when dividing 8 by 4
Test Suites: 1 passed, 1 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: 1.718s
Ran all test suites.
$ git add .
$ git commit -m 'Dockerize app'
$ git push origin master
OKですね。これをGitHubにPushしておきましょう。
Jenkins PipelineのためのJenkinsfileの作成
ベースを作る
パイプライン用のファイルを準備します。
$ mkdir misc
$ touch misc/Jenkinsfile
Jenkinsfileにパイプラインの設定を書く
Jenkinsfile
パイプライン上で、GitHubからのクローン、Dockerイメージのビルド、Docker内でのテスト、DockerHubへのイメージのPush、を実行するようにします。
node {
def app
stage('Clone repository') {
checkout scm
}
stage('Build image') {
app = docker.build('{your-dockerhub-account}/devops_sample_nodejs')
}
stage('Test') {
app.inside {
sh 'npm install --only=dev'
sh 'npm test'
}
}
stage('Push image') {
docker.withRegistry('https://registry.hub.docker.com', 'dockerhub-credentials') {
app.push("latest")
}
}
}
「{your-dockerhub-account}」は自分のDockerHubのアカウント名を置き換えてください。
Job DSLによるパイプラインジョブの追加
ベースを作る
Job DSL用のファイルを作成します。
$ touch pipeline.groovy
Job DSLの設定ファイルを書く
pipeline.groovy
Job DSLには以下のように、5分単位のポーリング、パイプライン用のJenkinsfileのパス指定、を設定します。
pipelineJob('Pipeline Basic Job') {
def repo = 'https://github.com/{your-github-account}/devops_sample_nodejs.git'
description("Pipeline for $repo")
triggers {
scm('H/5 * * * *')
}
definition {
cpsScm {
scm {
git {
remote { url(repo) }
branches('master')
scriptPath('misc/Jenkinsfile')
extensions { }
}
}
}
}
}
「{your-github-account}」は自分のGitHubのアカウント名に置き換えてください。
GitHubにPushする
パイプライン用に作成したファイルをGitHubにPushしておきます。
$ git add .
$ git commit -m 'Add pipeline'
$ git push origin master
Job DSLから新しいJenkins Pipelineのジョブを追加する
ホーム画面から「新規ジョブ作成」から、任意の名前(今回は「seed_job」)を入力し、「フリースタイル・プロジェクトのビルド」を選択し、「OK」をクリックします。
「ソースコード管理」の「Git」を選択し、「リポジトリURL」を入力します。
「ビルド」の「Process Job DSLs」をクリックします。
「DSL Scripts」にDSLファイル名を入力し、「保存」をクリックします。
「In-process Script Approval」をクリックします。
「Approve」をクリックします。
これでDSLが承認されました。
プロジェクト画面に戻って、「ビルド実行」をクリックします。
ビルドが成功し、新しいジョブが作成されました。
自動作成されたジョブ内容の確認
DSLで自動作成されてパイプラインジョブの設定を確認しましょう。
「設定」をクリックします。
「説明」が正しく設定されています。
「スケジュール」が正しく設定されています。
「リポジトリURL」が正しく設定されています。
これでパイプラインジョブの設定が完了です。
CIの動作確認
最後に、Jenkins上でDockerを動かし、自動ビルドしてみましょう。
パイプラインによる自動ビルドの実行
「ビルド実行」をクリックします。(キャプチャでは、パイプラインが見やすいように予め複数回ビルドを実行してあります。)
ビルドが成功しました。
自動的にテストが実行されています。
自動的にDockerイメージがDockerHubにPushされています。
ジョブの画面に戻ると、パイプラインで実行したステージが確認できます。
DockerHubの画面も確認してみましょう。
正しくDockerHubにイメージがPushされています。
これで完了です。
最後に
いかがでしたか?これでDockerアプリケーションをJenkinsでビルドする方法やパイプラインの使い方をマスターできたことでしょう。今回はNodeJSベースのDockerアプリケーションですが、当然他の言語でも動きます。JenkinsとDockerを使いこなしてCI/CDを開発現場で実施していきましょう。それでは。
環境
- Docker: 18.06.1-ce, build e68fc7a
- Jenkins: 2.151