JenkinsをDockerで動かすなら、公式のjenkins/jenkinsイメージに名前付きボリュームを付けて起動し、ビルドは別コンテナのエージェントで回す構成が基本です。この記事では、2026年11月時点のLTS 2.580.2を前提に、イメージのタグ選びからdocker runとDocker Composeでの起動、プラグインとJCasCを入れたカスタムイメージ、Pipelineのagent { docker }によるコンテナ内ビルドまでを、コピーして動かせる設定例つきで説明します。コンテナからdockerを呼ぶときのdocker.sockマウントの危険や、バックアップと版上げの手順も説明の対象です。Jenkins自体の機能や料金はJenkinsとは?料金・無料の範囲とインストールから使い方までで解説しています。
まとめ:Jenkins Dockerは公式イメージ・名前付きボリューム・エージェント分離で組む
イメージはjenkins/jenkins:2.580.2-lts-jdk21のように版番号まで固定したタグを使い、/var/jenkins_homeは名前付きボリュームに置きます。Docker Hubのjenkins(公式ライブラリ)は非推奨なので使いません。データの永続化はこの1点で決まります。
ビルドはコントローラーで実行せず、jenkins/inbound-agentか、Docker Engineを入れた別マシンのエージェントへ渡します。コントローラーのコンテナにホストのdocker.sockをマウントする方法は手軽ですが、ジョブを書ける人にホストのroot相当の権限を渡すことになるため、本番では採りません。プラグインと設定はplugins.txtとJCasCでコード化しておきます。
jenkins/jenkinsイメージのタグ選びとホスト側で用意する前提条件
最初に決めるのは、使うタグとデータの置き場所の2点です。ここを誤ると、版上げやコンテナの作り直しで設定が消えたり、起動しなくなったりします。
lts-jdk21とlts-jdk25、版番号固定タグ2.580.2の使い分け
Docker Hubのjenkins/jenkinsには、2026年10月28日公開の2.580.2に対して2.580.2-lts-jdk21・2.580.2-lts-jdk25・lts-jdk21・lts-jdk25などのタグがあります(2026年11月13日にDocker Hub APIで確認)。版番号の無いlts-jdk21は新しいLTSが出るたびに中身が変わるので、本番のcompose.yamlやDockerfileでは版番号つきのタグを書きます。
JDKは21か25を選びます。Java Support Policyでは、Java 17を動かせる最後のLTSが2.541.3で、Java 21のサポートは2027年9月、Java 25は2029年9月までと計画されています。新しく組むならjdk25のタグを選ぶと、Javaの入れ替えが当面不要です。古いプラグインがJava 25で動かない場合に限ってjdk21に留めます。最新のLTSの版番号はLTS Changelogで確認できます。
名前付きボリュームとバインドマウントで変わるUID 1000の権限
Jenkinsの設定・ジョブ・プラグイン・ビルド履歴は、すべて/var/jenkins_homeに入ります。公式イメージのREADMEは、ここに名前付きボリュームを使う形を推奨しています。ホストのディレクトリをバインドマウントすると権限エラーで起動しないことがあるためです。
コンテナ内のJenkinsは、UID 1000のjenkinsユーザーで動きます。どうしてもホストのディレクトリを使う場合は、所有者をUID 1000にするか、-uで実行ユーザーを指定してください。バックアップの取りやすさだけが理由なら、名前付きボリュームのまま後述のtarで書き出すほうが楽です。
docker runでJenkinsを起動して初期管理者パスワードで初回設定を終える
まずは1コンテナで起動し、画面にログインするところまでを確かめます。LinuxやmacOS、WindowsのDocker Desktopで同じコマンドが通ります。
8080と50000の2ポートを公開するdocker runの最小コマンド
8080はWeb画面、50000はインバウンド型エージェントがTCPで接続するためのポートです。READMEによると、SSH接続のエージェントやWebSocket接続だけを使う場合、50000は公開しなくて構いません。
# 名前付きボリューム jenkins_home にデータを置いて起動する
docker run -d --name jenkins \
-p 8080:8080 -p 50000:50000 \
--restart=on-failure \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:2.580.2-lts-jdk21
# 起動ログの確認(初回は1〜2分ほどで画面が開く)
docker logs -f jenkins
--restart=on-failureは、Jenkinsが異常終了したときだけコンテナを再起動させる指定で、READMEの例と同じ値です。
initialAdminPasswordの取得とセットアップウィザードの進め方
ブラウザでhttp://localhost:8080を開くと、初期管理者パスワードの入力を求められます。パスワードは起動ログにも出ますが、次のコマンドでファイルから直接取り出すほうが確実です。
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
続く画面では「推奨プラグインをインストール」を選び、管理者ユーザーを作成します。入ったプラグインはボリュームに残りますが、何を入れたかの記録はどこにも残りません。2台目を同じ構成で立てる予定があるなら、後述のカスタムイメージへ早めに移します。
Docker ComposeでJenkins本体とinbound-agentを並べる構成
コントローラーとエージェントを1つのcompose.yamlにまとめると、起動・停止・版上げを1コマンドで扱えます。Composeの書式そのものはdocker-composeとは?複数コンテナをymlで定義し一括管理する仕組みで解説しています。
compose.yamlでJenkins本体とinbound-agentを定義する書き方
エージェントには公式のjenkins/inbound-agentを使います。このイメージはコントローラーへ自分から接続しに行く型で、READMEの実行例どおり、接続先URL・シークレット・エージェント名を引数で渡します。init: trueは、READMEがサブプロセスの後始末に必要としている--initと同じ指定です。
# compose.yaml
services:
jenkins:
image: jenkins/jenkins:2.580.2-lts-jdk21
restart: on-failure
ports:
- "8080:8080"
volumes:
- jenkins_home:/var/jenkins_home
agent:
image: jenkins/inbound-agent:latest-jdk21
init: true
restart: on-failure
depends_on:
- jenkins
command:
- "-url"
- "http://jenkins:8080"
- "-workDir=/home/jenkins/agent"
- "${AGENT_SECRET}"
- "agent-1"
volumes:
jenkins_home:
エージェントは同じComposeネットワークの中からjenkinsというサービス名でコントローラーに接続します。そのため、この構成では50000番をホストに公開していません。別のマシンのエージェントをつなぐときだけ"50000:50000"を足します。${AGENT_SECRET}は、同じディレクトリの.envファイルに書いた値への置き換えです。GitBucketなど他のサービスを同じファイルに並べる例は、GitBucketをDockerで構築する手順とJenkins連携にあります。
ノード登録とシークレットの受け渡し、コントローラーのエグゼキューター0
エージェントは、コントローラー側にノードを登録してからでないと接続できません。手順は次のとおりです。
docker compose up -d jenkinsでコントローラーだけを起動し、初回設定を終える- 「Jenkinsの管理」から「ノード」を開き、名前
agent-1・ラベルlinuxで新しいノードを作る - 起動方法に「Launch agent by connecting it to the controller」(コントローラーへ接続する型)を選び、リモートFSルートを
/home/jenkins/agentにする - 保存後のノード画面に表示されるシークレットを
.envのAGENT_SECRET=に書く docker compose up -d agentを実行し、ノード一覧で接続済みになったことを確かめる
つながったら、コントローラー自身のエグゼキューター数を0にします。READMEによると既定値は2で、Jenkinsプロジェクトはコントローラーでビルドを動かさない設定を推奨しています。コントローラー上のビルドはjenkins_homeを書き換えられるためです。
プラグイン入りのカスタムイメージをDockerfileとplugins.txtで作る手順
画面でプラグインを入れる運用で困るのは、検証環境をもう1台作るときや、障害で作り直すときです。プラグインと設定をイメージに含めておけば、docker compose buildで同じ状態を再現できます。
jenkins-plugin-cliとplugins.txtでプラグインを版ごと固定する
公式イメージにはjenkins-plugin-cliが入っていて、plugins.txtに書いたプラグインをビルド時に取得します。書式は1行1プラグインの名前:版です。版はplugins.jenkins.ioのAPIで2026年11月13日に確認した値です。
# plugins.txt
workflow-aggregator:608.v67378e9d3db_1
git:5.11.0
docker-workflow:653.v2f2c08eff0ec
configuration-as-code:2147.v8a_8d38668c72
# Dockerfile
FROM jenkins/jenkins:2.580.2-lts-jdk21
COPY --chown=jenkins:jenkins plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN jenkins-plugin-cli -f /usr/share/jenkins/ref/plugins.txt
COPY --chown=jenkins:jenkins casc/ /usr/share/jenkins/casc/
ENV CASC_JENKINS_CONFIG=/usr/share/jenkins/casc/
Docker Pipeline(docker-workflow)は2.541.3以降、Configuration as Codeは2.541.1以降のJenkinsを要求します。版を固定すると、イメージを作り直してもプラグインの組み合わせが変わりません。更新するときは、READMEにある--available-updatesで新しい版を一覧にしてplugins.txtを書き換えます。Dockerfileの命令の書き方はDockerfileとは|書き方・主要命令とsyntaxの版を参照してください。
JCasCのjenkins.yamlでエグゼキューター数などの画面設定をコード化
Configuration as Codeプラグインは、環境変数CASC_JENKINS_CONFIGが指すフォルダやファイルからYAMLを読み込み、画面の設定に反映します。上のDockerfileでは、設定ファイルをjenkins_homeの外に置いています。ボリュームの中に入れると、2回目以降のイメージ更新が反映されなくなるためです。
# casc/jenkins.yaml
jenkins:
systemMessage: "Jenkins configured by JCasC"
numExecutors: 0
認証方式やエージェントの定義も同じファイルに書けます。書き方は、Configuration as Codeの管理画面で現在の設定をYAMLに書き出して確かめるのが早道です。パスワードやトークンはYAMLに直接書かず、環境変数で渡してください。
Pipelineのagent dockerでビルドをコンテナ内で回す書き方
エージェントにJDKやNode.jsを直接入れていくと、プロジェクトごとに必要な版がぶつかります。Docker Pipelineプラグインを入れると、ステージごとに指定したイメージのコンテナの中でコマンドを実行できます。
Docker Pipelineプラグインとagent docker指定の基本構文
Using Docker with Pipelineによると、宣言的パイプラインでdocker型のエージェントを使うにはDocker Pipelineプラグインが必要です。また、コンテナを起動するのはエージェント側のDocker Engineです。jenkins/inbound-agentのイメージにはDocker Engineが入っていないため、Docker Engineを入れたマシンをエージェントとして登録し、dockerのラベルを付けておきます。
// Jenkinsfile
pipeline {
agent none
stages {
stage('Build') {
agent {
docker {
image 'maven:3.9.16-eclipse-temurin-21'
label 'docker'
args '-v $HOME/.m2:/root/.m2'
}
}
steps {
sh 'mvn -B -DskipTests package'
}
}
}
}
label 'docker'で、Docker Engineを持つエージェントだけに割り当てます。macOSやWindowsのエージェントなどDockerを動かせないノードが混ざる環境では、このラベル指定を省くとジョブが失敗します。
.m2キャッシュのargsマウントとreuseNodeによるワークスペース共有
イメージのタグmaven:3.9.16-eclipse-temurin-21は、2026年11月13日にDocker Hubで実在を確認した版です。上の例のargs '-v $HOME/.m2:/root/.m2'は、公式ドキュメントの例と同じく、エージェント側のMavenキャッシュをコンテナに渡す指定です。これが無いと、ビルドのたびに依存ライブラリを全部ダウンロードし直します。npmやGradleのキャッシュも同じ形で渡せます。
前のステージの成果物を同じワークスペースで使いたい場合は、dockerブロックにreuseNode trueを足します。外側で確保したエージェントとワークスペースをそのまま使い、コンテナにマウントする指定です。リポジトリのDockerfileからビルド用イメージを作る場合は、agent { dockerfile true }を使います。ビルドしたイメージの脆弱性検査をパイプラインに足す方法はDockerの脆弱性診断をCI/CDに組み込む手順で扱っています。
コンテナ内のJenkinsからdockerを呼ぶ3方式とdocker.sockの危険
Docker上のJenkinsからさらにdockerコマンドを使う方式は3つあります。よく見かける手順は1つ目ですが、本番で採ってよいのは3つ目です。
docker.sockマウント・DinD・エージェント分離の権限と用途の比較
| 方式 | 仕組み | ジョブに渡る権限 | 使ってよい場面 |
|---|---|---|---|
| docker.sockマウント | ホストのデーモンを直接操作 | ホストのroot相当 | 個人の検証機だけ |
| DinD | 特権コンテナ内の別デーモン | 特権コンテナ全体 | 学習・公式チュートリアル |
| エージェント分離 | 別マシンのDocker Engine | そのマシンの範囲 | 本番・共用環境 |
jenkins.ioのDocker上へのインストール手順は2つ目の方式で、docker:dindを--privilegedで起動し、TLSで接続します。特権コンテナを常時動かすため、共用サーバーへそのまま持ち込む構成ではありません。
docker.sockをコントローラーに渡さない理由と例外的に許せる条件
DockerのDocker Engine securityは、デーモンが原則としてroot権限で動くこと、デーモンを操作できるのは信頼できるユーザーに限るべきことを明記しています。ホストのディレクトリをマウントしたコンテナは、ホストのファイルシステムを制限なく書き換えられるという記述も同じ文書にあり、マウントした範囲がそのままコンテナの権限の範囲です。docker.sockをマウントしたJenkinsでは、Jenkinsfileを書き換えられる人なら誰でも、/をマウントしたコンテナを起動してホストを操作できます。
許せるのは、ホストが使い捨ての検証機で、ジョブを書くのが自分1人の場合だけです。チームで共用するJenkinsや、プルリクエストのJenkinsfileをそのまま実行する構成では採りません。デーモンをroot以外で動かしたい場合は、rootlessモードやPodmanという選択肢があり、違いはPodmanとdockerの違い(デーモンレス・rootlessの仕組み)で整理しています。リモートのデーモンへTCPで接続するなら、Protect the Docker daemon socketのとおりSSHかTLSで保護します。
Docker上のJenkinsを本番で使う条件と、バックアップ・版上げの手順
コンテナ化したJenkinsの定常作業は、バックアップと版上げの2つです。どちらも数行のコマンドで済みます。
jenkins_homeボリュームのバックアップとタグ差し替えによる版上げ
バックアップは、書き込み途中のファイルを取り込まないよう、コントローラーを止めてからtarで書き出します。
# 停止してからボリュームを tar.gz に書き出す
docker compose stop jenkins
docker run --rm \
-v jenkins_home:/var/jenkins_home:ro \
-v "$PWD":/backup \
alpine:3.24 tar czf /backup/jenkins_home.tgz -C /var/jenkins_home .
docker compose start jenkins
版上げは、compose.yamlかDockerfileのタグを新しいLTSに書き換え、docker compose pull(カスタムイメージならdocker compose build)の後にdocker compose up -dを実行します。データはボリュームに残るため、コンテナを作り直しても設定は消えません。注意点が1つあります。READMEによると、ボリュームに既に入っているプラグインは、イメージ側のplugins.txtを新しくしても自動では上書きされません。イメージ側の版で揃えたいときは、環境変数PLUGINS_FORCE_UPGRADE=trueを付けて起動します。
Docker上のJenkinsを選ぶ場面と、マネージドCIへ移すべき場面
Docker上のJenkinsを選ぶのは、社内ネットワークの中のサーバーや検証機器にビルドから直接アクセスする必要があり、外部のCIサービスからは届かない場合です。既存のJenkinsfileや共有ライブラリが多く、作り直すより基盤だけコンテナに移すほうが安い場合も、この構成が合います。VMへ直接入れた古いJenkinsの延命策としても、更新がタグの書き換えで済む点は効きます。
一方、リポジトリがGitHubやGitLabにあり、ビルドが社内資源に依存しないなら、Jenkinsを新たにコンテナで立てる理由は薄くなります。プラグインの更新とコントローラーの保守を誰が続けるかを決められない組織では、GitHub ActionsやGitLab CIへ移すほうが運用の負担は確実に軽くなるため、移行を選ぶ判断が妥当です。移す場合の書き換え手順はJenkins移行の手順:JenkinsfileをGitHub Actions・GitLab CIへ書き換える方法にまとめています。コンテナ化と移行のどちらにするか、エージェントの配置をどう分けるかの設計から相談したい場合は、一創のDevOps・CI/CD導入支援で、既存ジョブの棚卸しから構築まで対応しています。
よくある質問
JenkinsをDockerで動かすときに、よく確認される点をまとめました。
JenkinsのDockerイメージはどれを使えばよいですか?
Docker Hubのjenkins/jenkinsを使います。名前が似ているjenkins(公式ライブラリのイメージ)は、2年以上前から非推奨とされていて、Docker Hubのページでもjenkins/jenkins:ltsへの切り替えが案内されています。タグは2.580.2-lts-jdk21や2.580.2-lts-jdk25のように版番号とJDKまで固定すると、意図しない版上げが起きません。
Docker上のJenkinsでデータが消えないようにするにはどうすればよいですか?
/var/jenkins_homeに名前付きボリュームをマウントします。ボリュームが残っていれば、コンテナを作り直しても状態は戻ります。ボリュームを付けずに起動したコンテナをdocker rmすると、設定もビルド履歴も消えるので注意してください。ボリューム自体の損失には、定期的なtarの書き出しで備えます。
JenkinsのジョブでDockerコマンドが見つからないと出るのはなぜですか?
公式のjenkins/jenkinsとjenkins/inbound-agentのイメージには、Docker CLIもDocker Engineも入っていないためです。ジョブからdockerを使うには、Docker Engineを入れたマシンをエージェントとして登録し、そこでジョブを動かしてください。ホストのdocker.sockをマウントする方法は、共用環境では避けます。
WindowsでもJenkinsをDockerで動かせますか?
Docker Desktopを入れれば、Linuxコンテナとして同じdocker runやcompose.yamlで動かせます。jenkins.ioのインストール手順にもWindows向けの書き方が併記されています。Windowsのビルドツールが要るジョブには、windowsservercoreタグのエージェントイメージか、Windowsマシンへ直接入れたエージェントを用意してください。
Docker ComposeでJenkinsを動かすとき、ポート50000の公開は必要ですか?
同じComposeネットワークの中のエージェントだけを使うなら、ホストへの公開は不要です。別のマシンからインバウンド型のエージェントをTCPでつなぐ場合だけ"50000:50000"を公開してください。SSH接続やWebSocket接続のエージェントは、50000番自体を使いません。
関連記事
- Jenkinsとは?料金・無料の範囲とインストールから使い方まで【LTS 2.580対応】:Jenkinsの仕組みと、aptやWindowsへの直接インストールの手順です
- GitBucketをDockerで構築する手順|4.48.0の配布先・旧版からの移行・Jenkins連携:Compose上でGitBucketとJenkinsをWebhookでつなぐ構成です
- Jenkins移行の手順:JenkinsfileをGitHub Actions・GitLab CIへ書き換える対応表と詰まり所【2026年11月】:コンテナ化せずにマネージドCIへ移す場合の手順です
- CI/CDツール比較|主要11製品の無料枠・料金と選び方【2026年10月】:Jenkins以外のCIツールと料金を比べるときに使えます
- Dockerの脆弱性診断をCI/CDに組み込む手順|Trivy・Docker Scout・Grypeの終了コードと結果の直し方:Jenkinsでビルドしたイメージの検査をパイプラインに足す方法です