Jenkinsについて分かりやすく解説します | Docker連携やPipeline機能も

はじめに

近年のソフトウェア開発において、継続的インテグレーション(CI)や継続的デリバリー(CD)の重要性はますます高まっています。

開発チームが大規模化し、リリースサイクルが短縮されていく中で、高い品質を担保しながら迅速にソフトウェアをリリースすることは困難を伴います。そのような状況を支える代表的なツールの一つがJenkinsです。

Jenkinsはオープンソースの自動化サーバーとして世界中の開発チームで広く利用されています。プラグインが豊富で拡張性に優れており、さまざまな開発言語や環境に適応できる柔軟性が特長です。

本記事では、Jenkinsの基本的な特徴から、近年注目を集めているPipeline機能、さらにDockerとの連携まで、幅広く解説していきます。

Jenkinsとは何か

背景

Jenkinsはもともと、Sun Microsystems(後のOracle)の社員だったKohsuke Kawaguchi氏によって開発されたHudsonというプロジェクトが起源です。

Oracleによる買収後にコミュニティベースで派生したプロジェクトがJenkinsとなり、2011年頃に独立しました。現在はJenkinsプロジェクトとして継続的にアップデートが行われており、世界中で最も有名なCI/CDツールの一つになっています。

主な特徴

  1. オープンソース
    無償で利用できるうえ、ソースコードが公開されています。そのため、多数の開発者が参加し、ドキュメントやプラグインの充実にもつながっています。
  2. 豊富なプラグイン
    Jenkinsには公式・非公式を含め数千以上のプラグインが存在します。各種バージョン管理システム(Git、SVNなど)との連携、ビルド・テストツール(Maven、Gradle、npmなど)の実行、Slackとの通知機能など、多岐にわたる拡張が可能です。
  3. プラットフォームに依存しない
    Javaで開発されているため、Windows、Linux、macOSといった様々なOS上で動作します。Dockerコンテナ上で動かすことも一般的です。
  4. ジョブの自動実行・管理機能
    各種パイプラインやジョブ(ビルド、テスト、デプロイなど)をトリガーによって自動で実行できます。特定の時間に定期実行したり、ソースコードが更新されたタイミングで実行したりなど、柔軟な設定が可能です。

Jenkinsの導入と基本設定

インストール方法

  1. オフィシャルサイトからダウンロード
    Jenkins公式サイト(https://www.jenkins.io)からWARファイルもしくはインストーラを入手し、環境に合わせてインストールを行います。
  2. Dockerを利用した導入
    後述するDockerを使う方法は非常に簡単で、以下のようなコマンド一発でJenkinsのコンテナを起動できます。bashコピーするdocker run -p 8080:8080 -p 50000:50000 jenkins/jenkins:lts この方法を使うと、Jenkins自体をDockerで管理できるため、ホスト環境を汚さずに済むメリットがあります。

初回設定

インストール後、Webブラウザでhttp://<サーバーIP>:8080にアクセスします。初回起動時には管理者パスワードの設定や、推奨プラグインのインストール、Jenkinsの管理者アカウントの作成などが求められます。ここではデフォルトのプラグインをインストールしておくと、一般的な機能はすぐに利用できるようになります。

Jenkins Pipelineとは

近年のJenkinsにおいて特に注目されている機能がPipeline(パイプライン)です。これは、従来のフリースタイルジョブを複数組み合わせるのではなく、Jenkinsfileと呼ばれる設定ファイル(スクリプト)を用いてビルド~テスト~デプロイの一連の流れを定義する仕組みです。

従来のジョブ方式との違い

以前のJenkinsでは、プロジェクトごとに「フリースタイルジョブ」を作り、必要に応じて上流・下流ジョブを連携させることでCI/CDパイプラインを実現していました

しかし、大規模プロジェクトや複雑なプロセスになると、ジョブ間の依存関係が煩雑になり、管理が難しくなるケースがありました。

Pipeline(特にDeclarative Pipeline)を利用することで、以下のようなメリットがあります。

  1. パイプラインの可視化
    JenkinsのWeb UI上でビルドステージごとの進捗や結果を視覚的に把握でき、エラー時にはどのステージが失敗したか即座に判断できます。
  2. スクリプト化によるバージョン管理
    Jenkinsfileをソースコードリポジトリ(Gitなど)に格納することで、開発者全員がパイプラインの定義を共有できます。パイプラインに変更があった場合は、Gitの履歴からいつ誰がどのように変更したかも追跡可能です。
  3. 複雑な処理の簡略化
    たとえば「ビルド」「テスト」「ステージングへのデプロイ」「本番へのデプロイ」といった一連の流れをブロック化し、前段階が成功したら次へ進む、といった分岐や条件分岐もDeclarative Pipelineで簡単に記述できます。

Jenkinsfileの基本構成

以下は、Declarative PipelineのJenkinsfileのごく簡単な例です。

groovyコピーするpipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                echo 'ビルド処理を実行します'
                // 例えばGradleなら ./gradlew build 等
            }
        }
        
        stage('Test') {
            steps {
                echo 'テスト処理を実行します'
                // ./gradlew test など
            }
        }
        
        stage('Deploy') {
            steps {
                echo 'デプロイを実行します'
                // ステージング環境や本番環境へのデプロイ手順
            }
        }
    }
}
  • pipeline: Jenkins Pipelineの開始ブロック
  • agent: パイプラインをどのエージェント(ノード)で動かすかを指定
  • stages: パイプラインをいくつかのステージに分割して定義
  • steps: 各ステージで実行する処理を記述

このように、Declarative Pipelineは単純明快な構文でステージを定義しやすくなっています。

Dockerとの連携

Dockerについては以下の記事を参考にしてください。

【入門編】Dockerとは何かを分かりやすく解説します | Docker HubやDocker Desktopも

なぜDockerと連携するのか

開発やデプロイのプロセスにおいて、Dockerとの連携は非常に多くのメリットをもたらします。たとえば次のようなケースがあります。

  1. 環境を統一できる
    Jenkinsが稼働しているサーバーとは別に、ビルド・テストを行うための環境をDockerイメージにまとめておけば、OSやライブラリのバージョン差異を気にせずにジョブを実行できます。
  2. テストの信頼性向上
    Dockerコンテナ内でテストを実行する場合、テスト環境が常に同じ状態から始まります。これにより、テストの再現性が高まり、「テストが通ったり通らなかったりする」という不安定さを低減できます。
  3. スケーリングが容易
    Jenkinsのノード(エージェント)をDockerコンテナとして起動すれば、負荷が高まった際にコンテナを追加起動することでスケールアウトが可能です。

JenkinsとDockerの基本的な接続方法

  1. Dockerプラグインのインストール
    Jenkinsのプラグイン管理画面から「Docker plugin」や「Docker Pipeline」をインストールしておきます。これらのプラグインにより、パイプラインの中からDockerイメージのビルドやコンテナ起動などを行いやすくなります。
  2. Dockerサーバー(デーモン)との連携設定
    JenkinsからDockerデーモンへアクセスするために、UnixソケットやTCPソケットを使用します。DockerのインストールされているサーバーにJenkinsをインストールしている場合は、/var/run/docker.sockへの権限設定などを正しく行う必要があります。
  3. パイプラインでのDocker操作
    Jenkinsfile内でDocker関連のステートメントを利用することができます。たとえば以下はDeclarative PipelineでDockerイメージをビルドし、コンテナ内でコマンドを実行する例です。groovyコピーするpipeline { agent any stages { stage('Build Docker Image') { steps { script { docker.build('my-app-image') } } } stage('Run Docker Container') { steps { script { docker.image('my-app-image').inside { sh 'echo "コンテナ内でスクリプトを実行"' // コンテナ内でビルド、テスト、デプロイなどを実行 } } } } } }

このように、Jenkinsのパイプライン上で直接Dockerイメージをビルドしたり、コンテナ内で処理を行うことが可能です。CI/CDのプロセスをコンテナ上で完結させたい場合に非常に便利です。

具体的な導入例

ここでは、ReactやNode.jsのアプリケーションをDockerコンテナとしてビルド・テストし、その後ステージング環境にデプロイする簡単な例を考えてみましょう。

  1. ソースコード管理
    GitHubまたはGitLabなどでソースコードを管理。リポジトリ内に以下のファイルが含まれているとします。
    • Dockerfile
    • Jenkinsfile
    • package.json & yarn.lock (あるいはpackage-lock.json)
    • src/ ディレクトリなど
  2. Dockerfileの例dockerfileコピーするFROM node:14 WORKDIR /app COPY package.json yarn.lock ./ RUN yarn install COPY . . RUN yarn build CMD ["yarn", "start"]
  3. Jenkinsfileの例groovyコピーするpipeline { agent any stages { stage('Checkout') { steps { checkout scm } } stage('Build Docker Image') { steps { script { docker.build("my-react-app:${env.BUILD_NUMBER}") } } } stage('Test') { steps { script { docker.image("my-react-app:${env.BUILD_NUMBER}").inside { sh "yarn test" } } } } stage('Deploy to Staging') { steps { // ステージング環境へのデプロイ処理 // docker push, kubectl apply, scp など各プロジェクトに応じた手順 echo 'Staging環境へデプロイを行います' } } } }
    • Checkoutステージでリポジトリから最新のソースコードを取得
    • Build Docker ImageステージでDockerイメージをビルド
    • Testステージでビルドしたイメージをコンテナ化し、テストコマンドを実行
    • Deploy to Stagingステージでステージング環境へのデプロイを実行
  4. 実行フロー
    Gitリポジトリにプッシュまたはプルリクエストが行われたタイミングで、自動的にパイプラインが実行されます。テストをクリアしたらステージング環境にデプロイするため、開発者はリポジトリに対してコードをプッシュするだけで簡単にCI/CDフローを回せます。

Jenkins運用のベストプラクティス

  1. プラグインの管理
    Jenkinsはプラグインで機能を拡張できる反面、プラグインが増えすぎると更新や互換性の問題が出てくることがあります。定期的に不要なプラグインを整理し、アップデート状況を確認しましょう。
  2. ジョブやパイプラインのバックアップ
    Jenkinsの設定ファイル($JENKINS_HOMEディレクトリ配下)を定期的にバックアップすることが重要です。万が一の障害時にスムーズに復旧できるように備えておきましょう。
  3. セキュリティ強化
    JenkinsはCI/CDという重要なパイプラインを担うため、アクセス制限や認証、暗号化などの設定をきちんと行う必要があります。LDAPやSSOとの連携、APIトークンの管理など、運用ルールを明確にすることが大切です。
  4. スケーラビリティ
    ビルドが増えたり大規模化したりすると、単一のJenkinsサーバーでは処理が追いつかなくなる場合があります。その際はMaster-Agent構成(分散ビルド)を採用して負荷を分散するか、Kubernetesやクラウド環境を利用してJenkinsエージェントを自動スケールさせる手段を検討しましょう。
  5. 組織内での周知・共有
    パイプラインの定義や運用ルールをドキュメント化し、チームメンバー全員がJenkinsの利用方法を理解していることが重要です。定期的に勉強会やハンズオンを行い、ナレッジの共有を促進しましょう。

まとめ

Jenkinsは長きにわたり信頼されてきたCI/CDツールであり、豊富なプラグインやコミュニティによって支えられています。とりわけPipeline機能を活用することで、コードを使ったパイプラインの宣言的管理が可能になり、大規模かつ複雑なソフトウェア開発プロセスを整理しやすくなります。また、Dockerと組み合わせることで、ビルド環境やテスト環境をコンテナ化し、統一された環境でのCI/CDを実現できます。

ソフトウェア開発における品質とスピードを両立させるためには、自動化できる工程は極力自動化し、人間が注力すべきクリエイティブな部分にリソースを割くことが不可欠です。Jenkinsは、その実現を支援する有力なツールとして今後も活躍し続けるでしょう。もしまだPipelineやDockerとの連携を試していない場合は、ぜひ本記事を参考に導入を検討してみてください。