Help us understand the problem. What is going on with this article?

Jenkins 導入手順 2018年版

久しぶりにJenkinsでCI環境作ったところ、Jenkins2になったことで以前と比べてだいぶ導入方法が変わってたので、忘れないためのメモです。

Jenkinsとは何か? なぜJenkins ?

Jenkins は自動化を導入するソフトウェアで、CIやCDを実現するためのツールとして使われます。同じカテゴリのサービスに、Travis CIやCircle CIがあります。TravisがGitHubのみ、Circle CIがGitHubやBitbucket Cloudのみを対象としているのに対して、Jenkinsは対象の制限が無いのが強みです(オンプレでもOK)。

個人的には、コードを GitHub で管理してるなら、Jenkinsの学習コストや運用コストを考えると、Circle CIやTravis CIなどの CIサービスを使ったほうがいいと思います。
オンプレでBitBucketサーバを立てたりして、Circle CIが使えないときは Jenkins を使わざるを得ません。でも昔よりは運用コストが低くなってるのかなと思います。

この記事で達成すること

  • dockerを使ってJenkinsをインストール
  • nginx を使って Port 80 -> 8080 にリバースプロキシーする
  • Node.js のプロジェクトのPipelineを作成する。2分ごとにポーリングして監視するように設定

前提

  • OS は Linux or Mac
  • Jenkins からも dockerコンテナを起動して、dockerコンテナの中で処理させる

dockerをインストールする

Jenkins公式が配布しているdockerイメージを使ってJenkinsを起動するのが、2018年現在だと一番簡単なセットアップ方法だと思いますので、この方法でセットアップします。

Docker store https://store.docker.com/search?type=edition&offering=community から Docker Community Edition をインストールしてください

Jenkinsの導入/起動

まず Jenkins のデータを格納するディレクトリを作成します。

mkdir $HOME/jenkins_home

jenkinsci/blueocean という公式が配布しているdockerイメージを使います。
以下のコマンドを実行すると、まだdockerイメージをダウンロードしてないときはダウンロードしてから、dockerコンテナを起動します。

sudo docker run \
   -u root \
   --rm \
   -d \
   -p 8080:8080 \
   -v $HOME/jenkins_home:/var/jenkins_home \
   -v /var/run/docker.sock:/var/run/docker.sock \
   jenkinsci/blueocean
  • -u root : Jenkinsからdockerコンテナを起動するため、rootユーザーで実行します。
  • —-rm : docker コンテナ終了時に、自動的にコンテナを削除します。Jenkinsの状態はすべて jenkins_home ディレクトリに格納されるため、コンテナ終了時に削除しても問題ないです。
  • -d : バックグラウンド (detachモード)で実行します
  • -p 8080:8080 : ホストマシンのポートとコンテナのポートをマッピングします。先の数字がホストマシンのポートで、後ろの数字がコンテナのポートです。
  • -v $HOME/jenkins_home:/var/jenkins_home : ホストマシンの $HOME/jenkins_home ディレクトリをコンテナの /var/jenkins_home ディレクトリにマップします。ここにJenkinsのデータが格納されます。
  • -v /var/run/docker.sock:/var/run/docker.sock : docker.sock をコンテナにマップすることで、コンテナの中から新たにdockerコンテナを起動できるようになります。

nginxでリバースプロキシする

(手元の環境で動かすだけならこの手順は不要です。)
80番ポートで受けたリクエストを8080番ポートに転送します。

以下のような転送設定でリクエストを転送できます。

/etc/nginx/conf.d/default.conf
upstream jenkins {
  server 127.0.0.1:8080 fail_timeout=0;
}

server {
  listen       80;
  server_name  my-ci.com; # 実際のドメインを指定してください。手元で試すだけなら localhost で良いです。

  location / {
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_pass              http://jenkins;
  }
}

上記は80番ポートでアクセスを受け付ける時の設定例です。SSLを使用したときの設定例はこちらにあります。
https://wiki.jenkins.io/display/JENKINS/Jenkins+behind+an+NGinX+reverse+proxy

Post-installation setup wizard

JenkinsをセットアップしたURLにブラウザでアクセスします。
(localhostにセットアップしているとして、 リバースプロキシを設定したならhttp://localhost/ 、 設定してないなら http://localhost:8080/ )

Starting_Jenkins.png

準備ができるとAdministrator passwordを求められます。

Sign_in__Jenkins_-2.png

画面に書かれてるように、initialAdminPassword というファイルにパスワードが記載されてます。

cat $HOME/jenkins_home/secrets/initialAdminPassword

コマンドを実行することでパスワードを取得できます。
これをブラウザのAdministrator password入力欄に貼り付けて、Continueをクリックします。

次にプラグインをインストールする画面が表示されます。

SetupWizard__Jenkins_.png

こだわりがなければ 「Install suggested plugins」 を選んで、おすすめプラグインをインストールします。
プラグインがダウンロード/インストールされます。これには少し時間がかかります。

次に

  • 初期ユーザの情報を登録します。ユーザ名、パスワードなどのフィールドを入力して保存します。
  • Jenkins URLの設定をします。実際に利用するURLを設定してください。手元で試すだけなら http://localhost:8080/ などで良いです。

これでJenkinsのインストールは完了です。

Node.js のプロジェクトのPipelineを作成する

現在のJenkinsは、Pipelineという仕組みを使って処理内容を定義します。
Pipeline とは continuous delivery (CD) pipeline のJenkinsにおける表現です。CD pipelineは継続的デリバリーを実現するためにいくつかの処理を行いますが、Pipelineはそれらの処理を可視化したり、コードで定義する機能を提供します。

Pipelineの定義はJenkinsfileという設定ファイルで行います。JenkinsfileをSCMのリポジトリに含めておくことで、Jenkinsはリポジトリに含まれるJenkinsfileを見つけてPipelineを作成します。
ですので、Jenkinsにどういう処理をさせるかはJenkinsfileを書いておけば良く、画面から処理内容を設定する必要はなくなりました。JenkinsもTravis CIやCircle CIと同じようにファイルで処理を設定できるようになったということですね。

Jenkinsfileを含んだ、Node.jsのサンプルプロジェクトを用意しました。
https://github.com/kmdsbng/jenkinsfile_sample

このプロジェクトを監視するPipelineを作っていきます。

Open Blue Oceanリンクを選びます。

ダッシュボード__Jenkins_.png

Create a new Pipeline ボタンを選びます。

Jenkins_と_1__zsh_と_ondai_memo_20180927_txt_______-_VIM_と_すべてのノート.png

Jenkins.png

Gitを選びます。(たぶんGitHubを選んでもいける。その時はユーザ、パスワードを入力しないといけなかったはず。)

gitリポジトリのURLを入力すると、SSH公開鍵が表示されます。これをGitHubに登録します。

Banners_and_Alerts_と_Jenkins.png

Jenkins-3.png

これで、リポジトリに含まれたJenkinsfileに従って監視が開始されます。

Jenkins___jenkinsfile_sample.png

Jenkinsfileの内容を見てみましょう。

https://github.com/kmdsbng/jenkinsfile_sample/blob/master/Jenkinsfile

pipeline {
  agent {
    docker {
      image 'node:8.12-alpine'
    }
  }

  triggers { pollSCM('H/2 * * * *') }

  stages {
    stage('Npm Build') {
      steps {
        sh 'npm install && npm run build'
      }
    }
  }

  post {
    success {
        echo 'I succeeeded!'
    }
    unstable {
        echo 'I am unstable :/'
    }
    failure {
        echo 'I failed :('
    }
  }
}

このJenkinsfileが設定していること。
* 2分毎にリポジトリの変更を監視
* node:8.12-alpine イメージを使って dockerを起動しそこで処理を行う。
* npmでビルドする

ファイルの記述を見れば、やってることがだいたいわかりますね。

次に、わざとビルドエラーを起こしてみましょう。コンパイルエラーが起こるようにプログラムを修正してからpushしてみます。

Jenkins___jenkinsfile_sample-2.png

jenkins___jenkinsfile_sample___master____3.png

jenkins___jenkinsfile_sample___master____3-2.png

ビルド時にエラーが検知され、エラー内容のログを見ることができます。

Jenkins___jenkinsfile_sample-3.png

プログラムを修正して push しなおすと、エラーがなくなったことを検知しました。

全画面_2018_10_13_15_29.png

Jenkinsの設定の不備でビルドが失敗したときなどは、Branches画面から再度CIを実行することができます。

Jenkinsの終了

sudo docker ps

コマンドで、Jenkinsの Container ID を確認して、

sudo docker stop <Container ID>

コマンドを実行します。

最新のJenkinsに更新

最新のJenkinsに更新するには、sudo docker pull jenkinsci/blueocean して、Jenkinsを再起動すればOK。

まとめ

Jenkinsfile を使って設定することで、これまでの Jenkins のように画面から設定するよりは、設定の手間が下がったと感じます。ただ、Jenkinsfile もそんなに明確に書けるというわけではなく、情報が少ないし、概念もわりと複雑な感じで、別の学習コストはかかるなあという印象です。

Jenkinsの運用方針として、あまりJenkinsのプラグインを使用せず、できるだけ Jenkinsfile で設定できることで目的を達成したほうが良いかなと考えてます。
リポジトリさえ指定すればCIの設定が完了する、という構成にしておいたほうが、Jenkinsサーバを立てるときの運用コストが減りそうなので。

参考資料

Jenkinsfileの書き方については、Jenkins自体に有益なドキュメントが格納されています。

Global Variable Reference

JENKINS_URL/pipeline-syntax/globals

ブランチ名などの Jenkinsfileで利用できるグローバル変数の説明です。

Directive Generator

JENKINS_URL/directive-generator/

Jenkinsfileのディレクティブ文字列のジェネレータです。

Steps Reference

JENKINS_URL/pipeline-syntax/html

Jenkinsfileの書式の資料です。

Installing Jenkins

https://jenkins.io/doc/book/installing/

Jenkinsのインストール方法を説明しています。この記事で紹介した docker を使ったインストール方法に加えて、パッケージをダウンロードしてインストールする手順なども説明しています。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした