令和元年に送る!Docker for WindowsでのJenkins(Docker in Docker)環境構築ハンズオン
はじめに
元号が変わり、2020年を迎えるにあたって「CI環境も存在しない開発体制をこの先も続けていくつもりなのか?」と悶々とする日々から脱却すべく「JenkinsのパイプラインでDockerfileを指定してビルド実行」を行うための環境構築に試行錯誤をした成果を紹介します。
目的
- ゼロからDocker入りJenkinsコンテナの立ち上げまでを、最小手順で実現する
- 手順の意図を理解する
以上の2点を目指しています。
私自身、DockerもJenkinsも最低限の知識しか持ち合わせておらず、結論に到達するまでに数多くのWebページを駆けずり回ることとなりました。
この記事は、まさしく「一ヶ月前の私がほしかったモノ」です。
動作確認環境
- Windows10 Pro 1903 - 64bit
- Docker Desktop for Windows 2.1.0.5 (stable)
1. Docker入りJenkinsコンテナの構築〜立ち上げ
1.1. Dockerfile
作成
Dockerfile.sample
# 1.1.1.
FROM jenkins:2.60.3
# 1.1.2.
USER root
# 1.1.3.
RUN apt-get update && apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg2 \
software-properties-common \
&& curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - \
&& apt-key fingerprint 0EBFCD88 \
&& add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" \
&& apt-get update && apt-get install -y docker-ce docker-ce-cli containerd.io \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# 1.1.4.
RUN usermod -aG docker jenkins
# 1.1.5.
RUN cd /tmp/ \
&& wget https://updates.jenkins-ci.org/latest/jenkins.war \
&& mv ./jenkins.war /usr/share/jenkins/
# 1.1.6.
USER jenkins
1.1.1. ベースイメージ指定
Dockerfile
作成# 1.1.1.
FROM jenkins:2.60.3
# 1.1.2.
USER root
# 1.1.3.
RUN apt-get update && apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg2 \
software-properties-common \
&& curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - \
&& apt-key fingerprint 0EBFCD88 \
&& add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" \
&& apt-get update && apt-get install -y docker-ce docker-ce-cli containerd.io \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# 1.1.4.
RUN usermod -aG docker jenkins
# 1.1.5.
RUN cd /tmp/ \
&& wget https://updates.jenkins-ci.org/latest/jenkins.war \
&& mv ./jenkins.war /usr/share/jenkins/
# 1.1.6.
USER jenkins
ここでは奇をてらわずに、Jenkinsの公式イメージを指定しています。
タグについては、今後の更新で手順が変更になる可能性を考慮して、投稿時点で最新の 2.60.3
を明示的に指定しています。
1.1.2. ユーザー変更(root
<- jenkins
)
jenkinsイメージ内で、ユーザーが jenkins
に変更されています。
jenkins
ユーザーはroot権限を持たないため、以降のコマンドを実行できるよう一時的に root
ユーザーに変更します。
1.1.3. Dockerインストール
Get Docker Engine - Community for Debian | Docker Documentationを参考に、Dockerエンジンを導入します。
インストール後には、Dockerfileのお作法としてキャッシュを削除しておきます。
余談ですが、
curl
で指定するURLは、Docker v17.09以前のドキュメントでは$(. /etc/os-release; echo "$ID")
の結果を参照していました。
ホスト環境がRaspberry Piの場合等、URLにしたい文字列と$(. /etc/os-release; echo "$ID")
の結果とが一致しないケースがあることから、最新のドキュメントでは見直されているのではないかと想像します。 ※要出典
1.1.4. docker
を jenkins
ユーザーのセカンダリグループとして追加
Post-installation steps for Linux | Docker Documentationを参考に、jenkins
ユーザーが sudo
を指定せずに docker
コマンドを実行するための準備としてグループ設定を行います。
1.1.5. Jenkinsアップデート
jenkins:2.60.3
の最終更新日は、投稿時点で一年以上前となっていることから、最新のJenkinsを利用するために、アップデートします。
1.1.6. ユーザー変更(jenkins
<- root
)
一時的に変更したユーザーをもとに戻します。
1.2. docker-compose.yml
作成
version: "3"
services:
jenkins:
build: .
ports:
- 8080:8080
volumes:
# 1.2.1.
- ./jenkins_home:/var/jenkins_home
# 1.2.2.
- /var/run/docker.sock:/var/run/docker.sock:rw
1.2.1. ホスト環境との共有ディレクトリの指定
JenkinsコンテナにホストPC上で作成した Dockerfile
を送り込めるように、Jenkinsのホームディレクトリを共有ディレクトリ化します。
1.2.2. Dockerデーモンの共有
Dockerコンテナ内でDockerコンテナを動かすために、ホストPCのDockerソケットを共有します。
※この手順については Dockerコンテナ内からDockerを使うことについて - Qiita の記事が非常に参考になりました。
1.3. .env
作成(しません)
Docker for WindowsでDockerデーモンを共有するために .env
を作成して COMPOSE_CONVERT_WINDOWS_PATHS=1
を指定する必要がある、という記事を目にしましたが、私の環境では作成せずに進めることができました。
COMPOSE_CONVERT_WINDOWS_PATHS=1
1.4. イメージ構築~コンテナ作成~バックグラウンド実行
カレントディレクトリに先に示した Dockerfile
と docker-compose.yml
とを配置して、コマンドプロンプトから以下のコマンドを実行します。
$ docker-compose up --build -d && docker-compose exec -u root jenkins chown root:docker /var/run/docker.sock
Docker for Windowsでは(?) docker
グループに /var/run/docker.sock
へのアクセス権限が割り当てられていないようです。
そのため、コンテナのバックグラウンド実行後にグループ所有権を設定します。
※コマンドプロンプト以外のCUIツールを仕様した場合、パスの解決がうまくいかずに chown root:docker /var/run/docker.sock
を実行できないケースがあるようです。私はこれにハマって半日つぶしました。
2. Jenkinsコンテナ上でDocker Pipeline Pluginの登録〜実行
2.1. Jenkinsセットアップ
任意のWebブラウザで localhost:8080
へアクセスし、正規の手順でセットアップします。
※以下、テキストベースで説明していますが、他に詳しく正確で分かりやすい記事が山のようにありますので、そちらも参考にしてください。
2.1.1. Unlock Jenikins
いきなり「Administrator password」を求められます。
ここには docker-compose logs -f jenkins
を実行して、以下のとおり出力されるパスワードを入力します。
...
jenkins_1 | 2019-12-15 08:10:47.628+0000 [id=30] INFO jenkins.install.SetupWizard#init:
jenkins_1 |
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 | <Administrator password>
jenkins_1 |
jenkins_1 | This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
jenkins_1 |
jenkins_1 | *************************************************************
jenkins_1 | *************************************************************
jenkins_1 | *************************************************************
jenkins_1 |
jenkins_1 | --> setting agent port for jnlp
jenkins_1 | --> setting agent port for jnlp... done
...
2.1.2. Customize Jenkins
特にこだわりがなければ「Install suggested plugins」を選択して問題ないでしょう。
2.1.3. Gettings Started
オールグリーンになるまで数分の休憩です。
2.1.4. Create First Addmin User
初期ユーザの情報を求められるので、適宜入力欄を埋めます。
2.1.5. Instance Configuration
JenkinsのURLを指定することができます。
特にこだわりがなければデフォルトの http://localhost:8080/
で問題ないでしょう。
2.1.6. Jenkins is ready!
これでJenkinsのセットアップです!
2.2. パイプライン登録
以下、「sample」という名前のジョブを作成し、Dockerfileを指定してコンソールに「hello world.」と表示する例における手順です。
2.2.1. 下準備
- 以下内容の
Dockerfile
を作成
FROM alpine:latest
-
~/jenkins_home/workspace/sample/
ディレクトリを作成し、配下に1.
のファイルを配置
2.2.2. WEB画面操作
- ホーム画面「新規ジョブ作成」をクリック
- 「Enter an item name」に「sample」と入力して「パイプライン」を選択し、「OK」をクリック
- Generalタブ「パイプライン」「Pipeline script」を選択して「Script」に以下の内容を入力し、「保存」をクリック
node {
docker.build("sample-${BUILD_ID}", "-f Dockerfile .").inside() {
sh 'echo "Hello World!"'
}
}
2.3. Docker Pipeline Plugin実行〜結果確認
2.2.
で作成したジョブ画面の「ビルド実行」をクリックします。
今回のサンプルでは、コンソールに Hello World!
と出力するだけなので、ビルド履歴画面「Console Output」から、以下のような出力がなされていれば成功です!
Started by user admin
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/sample
[Pipeline] {
[Pipeline] isUnix
[Pipeline] sh
+ docker build -t sample-9 -f Dockerfile .
Sending build context to Docker daemon 2.048kB
Step 1/1 : FROM alpine:latest
---> 965ea09ff2eb
Successfully built 965ea09ff2eb
Successfully tagged sample-9:latest
[Pipeline] isUnix
[Pipeline] sh
+ docker inspect -f . sample-9
.
[Pipeline] withDockerContainer
Jenkins seems to be running inside container 0fb06afff12dcba3803da391819176848ca54934737d486d99a72210b37c9955
$ docker run -t -d -u 1000:1000 -w /var/jenkins_home/workspace/sample --volumes-from 0fb06afff12dcba3803da391819176848ca54934737d486d99a72210b37c9955 -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** sample-9 cat
$ docker top 3702a7909fdacf3b77b04edcd381dba1309c8c9d0991def0ab1e392e07eb56b2 -eo pid,comm
[Pipeline] {
[Pipeline] sh
+ echo 'Hello World!'
Hello World!
[Pipeline] }
$ docker stop --time=1 3702a7909fdacf3b77b04edcd381dba1309c8c9d0991def0ab1e392e07eb56b2
$ docker rm -f 3702a7909fdacf3b77b04edcd381dba1309c8c9d0991def0ab1e392e07eb56b2
[Pipeline] // withDockerContainer
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
おわりに
0 -> 1のステップを超えるためには多大な労力を要します(要しました)。
この記事が、第二、第三のワタシの労力を減らすお役にたつことががあれば幸いです。
参考
Docker関連
- docker/Dockerfile at 2.60.3 · jenkinsci/docker
- Dockerfileにおけるキャッシュの削除 - ばいばいバイオ
- Get Docker Engine - Community for Debian | Docker Documentation
- Post-installation steps for Linux | Docker Documentation
- Docker in Docker のベタープラクティス - Qiita
- Dockerコンテナ内からDockerを使うことについて - Qiita
- Docker for windows で /var/run/docker.sock をマウントできるようにする - Qiita
- How to fix docker: Got permission denied while trying to connect to the Docker daemon socket | DigitalOcean
- Docker build does not work on Windows · Issue #1341 · containous/traefik
Jenkins(Docker Pipeline Plugin)関連
- Jenkins 導入手順 2018年版 - Qiita
- Jenkinsジョブ(ビルド~テスト)をDockerコンテナ上で実行する ~Docker Pipeline Pluginを使ってみる~ - SIerだけど技術やりたいブログ
- 爆速でJenkinsをマスターしよう(Docker編) ~ JenkinsコンテナへのDockerインストール方法からJob DSL、Jenkins Pipelineまで ~ | Casual Developers Note
CIツール選定
Author And Source
この問題について(令和元年に送る!Docker for WindowsでのJenkins(Docker in Docker)環境構築ハンズオン), 我々は、より多くの情報をここで見つけました https://qiita.com/sh1928kd/items/b248a8d48d16eaab9617著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .