使用Docker部署Jenkins并實現(xiàn)自動化部署的全流程
從容器化部署到 Git 觸發(fā)自動化構(gòu)建鏡像,一篇帶你把 Jenkins CI/CD 流水線跑起來(附流程圖)
文章導(dǎo)覽
持續(xù)集成與持續(xù)部署(CI/CD)已成為現(xiàn)代軟件開發(fā)不可或缺的環(huán)節(jié),而 Jenkins 作為全球最流行的開源自動化服務(wù)器,被廣泛應(yīng)用于各類自動化任務(wù)中。結(jié)合 Docker 的輕量化和可移植性,我們可以快速搭建一個高效、靈活且易于擴展的自動化部署環(huán)境。
本文涵蓋:
? Docker 環(huán)境準備與鏡像選擇
? Jenkins 容器部署(單容器 + 權(quán)限配置)
? 初始化與插件安裝
? 核心重點:讓 Jenkins 容器內(nèi)調(diào)用 Docker(兩種方案對比)
? 憑證管理(Git + 容器倉庫)
? Jenkins Pipeline 聲明式流水線編寫(構(gòu)建 → 推送 → 部署)
? 完整流程圖 + 架構(gòu)圖(Mermaid 格式)
? 生產(chǎn)環(huán)境優(yōu)化建議與常見問題排查
一、前置條件
| 項目 | 要求 |
|---|---|
| 操作系統(tǒng) | Linux(Ubuntu 20.04+ / CentOS 7+ / Debian) |
| Docker | 版本 ≥ 20.10(含 docker compose) |
| 硬件配置 | 建議 2 核 4G 以上(Jenkins 運行需一定資源) |
| 代碼倉庫 | GitHub / GitLab / Gitee(任意 Git 倉庫即可) |
| Docker Registry | Docker Hub / 私有 Harbor / 阿里云容器鏡像服務(wù) |
本文基于 Docker 官方 LTS 鏡像
jenkins/jenkins:lts,此版本兼容性最佳,適合生產(chǎn)部署。
二、端到端自動化部署流程總覽

核心閉環(huán):代碼提交 → Webhook 觸發(fā) → Jenkins 構(gòu)建 → 鏡像推送 → 自動部署,全程無需人工干預(yù)。
三、Docker 環(huán)境下部署 Jenkins
3.1 拉取 Jenkins 官方鏡像
我們選擇 Jenkins 長期支持(LTS)版本,它不僅穩(wěn)定,而且是目前生產(chǎn)環(huán)境的主力選擇:
docker pull jenkins/jenkins:lts
若拉取較慢,可配置國內(nèi)鏡像加速源或使用阿里云加速器。
3.2 創(chuàng)建數(shù)據(jù)持久化目錄
mkdir -p /data/jenkins_home chown -R 1000:1000 /data/jenkins_home
設(shè)置權(quán)限為 1000:1000 是因為 Jenkins 容器內(nèi)的默認運行用戶 jenkins 的 UID 正是 1000,確保容器能夠正常讀寫該目錄,避免使用 777(生產(chǎn)環(huán)境權(quán)限應(yīng)最小化)。
3.3 啟動 Jenkins 容器(基礎(chǔ)版)
docker run -d \ --name jenkins \ --restart always \ -p 8080:8080 \ -p 50000:50000 \ -v /data/jenkins_home:/var/jenkins_home \ -e TZ="Asia/Shanghai" \ jenkins/jenkins:lts
關(guān)鍵參數(shù)說明:
| 參數(shù) | 作用 |
|---|---|
-p 8080:8080 | Web 管理界面訪問端口 |
-p 50000:50000 | Jenkins Master-Slave 通信端口 |
-v | Jenkins 數(shù)據(jù)持久化 |
-e TZ="Asia/Shanghai" | 設(shè)置容器時區(qū) |
--restart always | 保障容器異常退出后自動拉起 |
此時一個基礎(chǔ)的 Jenkins 容器已經(jīng)運行起來。但是請注意:這個容器內(nèi)無法執(zhí)行 Docker 命令——流水線中的 docker build 等指令會直接報錯。接下來我們要解決這個核心問題。
四、核心配置:讓 Jenkins 能調(diào)用 Docker
這是本教程的核心重點。Jenkins 要構(gòu)建 Docker 鏡像,就必須具備 Docker 能力。
4.1 兩種技術(shù)路線對比
| 對比維度 | 方案 A:掛載 Docker Socket | 方案 B:Docker-in-Docker (DinD) |
|---|---|---|
| 原理 | Jenkins 容器直接調(diào)用宿主機 Docker | 在 Jenkins 旁啟動一個獨立的 Docker 守護進程容器 |
| 容器大小 | 輕量 | 稍重 |
| 隔離性 | 較低(同宿主共享 Docker 引擎) | 高(獨立的 Docker 進程) |
| 適用階段 | 測試/預(yù)發(fā)布環(huán)境 | 生產(chǎn)環(huán)境(隔離要求高時) |
| 安全風(fēng)險 | 容器獲得宿主機 root-like 權(quán)限 | --privileged 運行但存在獨立隔離 |
| 官方示例 | 較為常見 | 官方推薦 DinD 保持環(huán)境純凈 |
4.2 方案 A:掛載 Socket(推薦入門)
docker run -d \ --name jenkins \ --restart always \ -p 8080:8080 \ -p 50000:50000 \ -v /data/jenkins_home:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker \ -e TZ="Asia/Shanghai" \ jenkins/jenkins:lts
核心選項:
-v /var/run/docker.sock:/var/run/docker.sock:讓 Jenkins 容器與宿主機 共享 Docker 守護進程-v /usr/bin/docker:/usr/bin/docker:讓容器內(nèi)的dockerCLI 可執(zhí)行- 在容器內(nèi)驗證是否成功:
docker exec jenkins docker ps
安全提示:該方案相當(dāng)于將宿主機的 Docker 完全“借”給 Jenkins 容器,務(wù)必確保 Jenkins 流水線中不能執(zhí)行惡意命令。
4.3 方案 B:Docker-in-Docker(DinD,更隔離)
適用場景:K8s 環(huán)境、高安全性 CI/CD 集群、多租戶場景
步驟一:創(chuàng)建專用 Docker 網(wǎng)絡(luò)
docker network create jenkins
步驟二:啟動 DinD 守護進程容器
docker run --name jenkins-docker \ --rm --detach \ --privileged \ --network jenkins \ --network-alias docker \ -e DOCKER_TLS_CERTDIR=/certs \ -v jenkins-docker-certs:/certs/client \ -p 2376:2376 \ docker:dind \ --storage-driver overlay2
步驟三:啟動 Jenkins 并連接到 DinD
docker run --name jenkins-blueocean \ --restart=on-failure \ --detach \ --network jenkins \ -e DOCKER_HOST=tcp://docker:2376 \ -e DOCKER_CERT_PATH=/certs/client \ -e DOCKER_TLS_VERIFY=1 \ -p 8080:8080 \ -v jenkins-data:/var/jenkins_home \ -v jenkins-docker-certs:/certs/client:ro \ jenkins/jenkins:lts
關(guān)鍵解釋:
--network-alias docker:為 DinD 容器設(shè)置了固定的網(wǎng)絡(luò)別名,Jenkins 可通過tcp://docker:2376與之通信DOCKER_TLS_VERIFY=1:啟用 TLS 加密驗證:ro:只讀掛載證書,進一步增強安全性
五、Jenkins 初始化與插件配置
5.1 獲取初始解鎖密碼
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
執(zhí)行后會打印一長串字符串,復(fù)制備用。
5.2 Web 初始化流程
- 瀏覽器訪問
http://<服務(wù)器IP>:8080 - 粘貼解鎖密碼進入安裝向?qū)?/li>
- 選擇 “安裝推薦插件”(后續(xù)可按需增刪)
- 創(chuàng)建管理員用戶并完成基礎(chǔ)設(shè)置
5.3 必裝插件清單
安裝完成之后,建議手動補充以下插件(路徑:Dashboard → Manage Jenkins → Plugins → Available plugins):
| 插件名稱 | 用途 |
|---|---|
| Git Plugin | 從 Git 倉庫拉取代碼 |
| Pipeline | Jenkins 核心流水線支持 |
| Blue Ocean(可選) | 可視化流水線界面,提升排錯效率 |
| Docker Pipeline | 提供 Jenkinsfile 中的 docker.build(), docker.withRegistry() 語法 |
| Credentials Binding | 安全管理憑證信息(避免在腳本中硬編碼) |
| GitHub Integration / Gitee | 實現(xiàn) Git 觸發(fā) Webhook |
安裝 Docker Pipeline 后,在流水線中即可調(diào)用豐富的 Docker 操作語法。
六、憑證管理(核心安全配置)
6.1 憑證類型與使用場景
| 憑證類型 | 典型使用場景 |
|---|---|
Username with password | 登錄 Docker Hub / 私有鏡像倉庫 |
SSH Username with private key | Jenkins 免密拉取 Git 倉庫(推薦 GitHub 部署密鑰) |
Secret text | API Token(如 GitHub Personal Access Token) |
Certificate | PKCS#12 證書文件 |
在 Jenkins 中配置憑證的位置:Dashboard → 系統(tǒng)管理 → 憑證 → 系統(tǒng) → 全局憑據(jù) → 添加憑據(jù)。
6.2 添加 Git 拉取憑證(SSH 方式)
這是確保 Jenkins 能拉取私有倉庫代碼的必備操作。
在 Jenkins 服務(wù)器上生成 SSH 密鑰對
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
生成的文件:
~/.ssh/id_rsa—— 私鑰(內(nèi)容粘貼到 Jenkins)~/.ssh/id_rsa.pub—— 公鑰(添加到 GitHub/GitLab 賬戶的 SSH Keys)
將公鑰添加到代碼倉庫
- GitHub:Settings → SSH and GPG keys → New SSH key
- GitLab:Preferences → SSH Keys
在 Jenkins 中添加私鑰
添加憑證時選擇 SSH Username with private key:
- Username:填寫代碼倉庫賬戶(如
git或 GitHub 用戶名) - Private Key → Enter directly → 粘貼
id_rsa私鑰的完整內(nèi)容(包含-----BEGIN OPENSSH PRIVATE KEY-----頭尾) - 輸入可選的 Passphrase(若生成密鑰時設(shè)置了密碼短語)
6.3 添加容器鏡像倉庫憑證
選擇 Username with password 類型:
| 注冊表類型 | Username | Password | 憑證 ID 示例 |
|---|---|---|---|
| Docker Hub | Docker Hub 用戶名 | Docker Hub 密碼/Access Token | dockerhub-creds |
| 阿里云容器鏡像 | 阿里云賬號名 | 鏡像倉庫訪問密碼 | aliyun-acr-creds |
關(guān)鍵提示:為憑證填寫一個有意義的 ID(如 dockerhub-credentials、git-ssh-key),因為在 Jenkinsfile 中要引用這個 ID,而不是直接硬編碼用戶名密碼。
Pipeline 中的憑證引用示例
withCredentials([usernamePassword(
credentialsId: 'dockerhub-credentials',
usernameVariable: 'DOCKER_USER',
passwordVariable: 'DOCKER_PASS'
)]) {
sh 'echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin'
}
七、Jenkinsfile 自動化部署流水線
7.1 流程圖速覽

7.2 完整聲明式 Pipeline 模板
在代碼倉庫的根目錄下創(chuàng)建一個 Jenkinsfile(以 Spring Boot Java 應(yīng)用為例,實際可靈活適配):
pipeline {
agent any
environment {
// ==================== 請根據(jù)實際修改此處 ====================
DOCKER_REGISTRY = 'your-registry.cn-hangzhou.cr.aliyuncs.com' // 鏡像倉庫地址
IMAGE_NAME = 'your-namespace/your-app' // 鏡像名稱
// ==========================================================
}
stages {
// Stage 1: 從 Git 倉庫拉取最新代碼
stage('Checkout') {
steps {
checkout scm
script {
// 生成唯一的鏡像標(biāo)簽: 構(gòu)建號-提交哈希前7位(保證可追溯)
SHORT_COMMIT = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
TAG = "${env.BUILD_NUMBER}-${SHORT_COMMIT}"
echo "鏡像標(biāo)簽: ${TAG}"
}
}
}
// Stage 2: 【構(gòu)建】根據(jù)項目類型調(diào)整
stage('Build') {
steps {
// Java/Maven 項目示例
sh 'mvn clean package -DskipTests'
// Node.js 示例: sh 'npm install && npm run build'
}
}
// Stage 3: 【打包】基于項目 Dockerfile 構(gòu)建鏡像(利用宿主機 Docker)
stage('Build Docker Image') {
steps {
script {
// 方案 A(掛載 socket)語法:
docker.build("${DOCKER_REGISTRY}/${IMAGE_NAME}:${TAG}")
// 方案 B(DinD)語法:
// docker.withServer('tcp://docker:2376', 'docker-certs') {
// docker.build("${DOCKER_REGISTRY}/${IMAGE_NAME}:${TAG}")
// }
}
}
}
// Stage 4: 【推送】登錄私有鏡像倉庫并推送鏡像
stage('Push to Registry') {
steps {
script {
// 使用之前配置的 Docker Hub / 私有倉庫憑證
docker.withRegistry("https://${DOCKER_REGISTRY}", 'dockerhub-credentials') {
docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${TAG}").push()
// 可選: 為 latest 標(biāo)簽也推送一次
docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${TAG}").push('latest')
}
}
echo "? 鏡像推送完成: ${DOCKER_REGISTRY}/${IMAGE_NAME}:${TAG}"
}
}
// Stage 5: 【部署】在目標(biāo)服務(wù)器上拉取并運行新版本容器
stage('Deploy to Server') {
steps {
script {
// 方式一: 如果部署在本地宿主機(直接 docker run 更新)
sh """
docker pull ${DOCKER_REGISTRY}/${IMAGE_NAME}:${TAG}
docker stop my-app || true
docker rm my-app || true
docker run -d --name my-app -p 80:8080 ${DOCKER_REGISTRY}/${IMAGE_NAME}:${TAG}
"""
// 方式二: 如果部署在遠程服務(wù)器(通過 SSH 執(zhí)行命令)
// 需要安裝 SSH Pipeline Steps 插件并配置遠程主機憑證
// sshagent(['remote-server-ssh-key']) {
// sh "scp ... && ssh user@remote-server 'docker pull ... && docker run ...'"
// }
}
}
}
}
post {
// 每個階段結(jié)束后自動清理工作空間殘留
always {
cleanWs()
}
success {
echo "?? 流水線執(zhí)行成功!鏡像已推送并部署。"
}
failure {
echo "? 流水線執(zhí)行失敗,請檢查日志。"
}
}
}
7.3 關(guān)鍵代碼解讀
| 代碼塊 | 作用 |
|---|---|
checkout scm | 自動拉取觸發(fā)此次構(gòu)建的 Git 倉庫對應(yīng)分支的最新代碼 |
SHORT_COMMIT + BUILD_NUMBER | 組合鏡像標(biāo)簽,保證唯一性且易于回溯提交記錄 |
docker.build(...) | Docker Pipeline 插件提供的原生鏡像構(gòu)建命令,底層調(diào)用 docker build |
docker.withRegistry | 安全登錄鏡像倉庫并推送,全程無需暴露明文密碼 |
post -> always/cleanWs | Jenkins Pipeline 的“最終執(zhí)行塊”,保證每次構(gòu)建完畢清理殘留文件,避免磁盤占滿 |
八、多分支流水線配置(推薦生產(chǎn)環(huán)境)
8.1 多分支流水線的價值
多分支 Pipeline 是 Jenkins 提供的一種高級功能,它可以自動掃描 Git 倉庫中所有分支,并為每個分支獨立創(chuàng)建和觸發(fā)對應(yīng)的流水線。這意味著:
- 開發(fā)分支(
develop)自動構(gòu)建并部署到測試環(huán)境 - 主干分支(
main/master)自動構(gòu)建并部署到預(yù)發(fā)環(huán)境 - 發(fā)布分支(
release/*)自動構(gòu)建并部署到生產(chǎn)環(huán)境 - 無需為每個分支單獨配置 Jenkins Job
8.2 配置步驟
- 在 Jenkins 首頁點擊 新建任務(wù)
- 輸入項目名稱,選擇 Multibranch Pipeline(多分支流水線)
- 在 Branch Sources 中添加 Git 倉庫 URL 并選擇之前配置的 SSH 憑證
- 在 Build Configuration 中指定 Jenkinsfile 的路徑(默認為倉庫根目錄的
Jenkinsfile) - 點擊 保存,Jenkins 將自動掃描全部分支并啟動構(gòu)建
九、整體架構(gòu)圖(UML 部署圖)
渲染錯誤: Mermaid 渲染失敗: Lexical error on line 8. Unrecognized text. ...e
配置 + 插件 + 構(gòu)建歷史] end -----------------------^
此圖展示了 Jenkins Master 與宿主機 Docker Engine、代碼倉庫、鏡像倉庫、以及部署目標(biāo)之間的關(guān)聯(lián)關(guān)系。
十、常見問題排查與優(yōu)化建議
10.1 容器內(nèi)無法執(zhí)行 docker 命令
現(xiàn)象:構(gòu)建階段報 docker: command not found 或 Cannot connect to the Docker daemon。
解決方案:
- 確認啟動容器時已掛載
/var/run/docker.sock和/usr/bin/docker - 進入容器驗證:
docker exec jenkins docker ps - 檢查宿主機 Docker 是否正常運行:
systemctl status docker
10.2 Webhook Git 推送不觸發(fā)構(gòu)建
現(xiàn)象:代碼已 push 到倉庫,但 Jenkins 未自動觸發(fā)構(gòu)建。
解決方案:
- 確認 Jenkins 能夠被外網(wǎng)/Git倉庫訪問(檢查安全組或防火墻是否放行 8080 端口)
- GitHub 倉庫的 Settings → Webhooks 中添加 Payload URL:
http://<jenkins-公網(wǎng)IP>:8080/github-webhook/ - GitLab 的 Webhook URL 為:
http://<jenkins-公網(wǎng)IP>:8080/project/<項目名> - Jenkins 全局安全配置中勾選 “GitHub 自動觸發(fā)” 相關(guān)選項
10.3 Docker socket 權(quán)限不足
現(xiàn)象:Got permission denied while trying to connect to the Docker daemon socket
解決方案:
# 查看 /var/run/docker.sock 的屬主 ls -l /var/run/docker.sock # 將 Jenkins 容器用戶加入 docker 組 sudo usermod -aG docker $USER newgrp docker # 或修改 socket 權(quán)限(不推薦生產(chǎn)環(huán)境) sudo chmod 666 /var/run/docker.sock
10.4 Jenkins 頻繁崩潰或內(nèi)存不足
現(xiàn)象:容器 502 無法訪問,日志顯示 OutOfMemoryError。
解決方案:
- 啟動容器時增加資源限制:
--memory="4g" --memory-swap="4g" - 在
docker run參數(shù)中加入--shm-size=256m - 定期清理構(gòu)建歷史:系統(tǒng)管理 → 構(gòu)建記錄管理器 → 配置規(guī)則
10.5 生產(chǎn)環(huán)境安全強化清單
| 類別 | 推薦實踐 |
|---|---|
| 網(wǎng)絡(luò)隔離 | Jenkins 置于專用 Docker 網(wǎng)絡(luò),不與其他服務(wù)混用 |
| HTTPS | 前置 Nginx/Traefik 反向代理并啟用 Let’s Encrypt 自動簽發(fā)證書 |
| 權(quán)限最小化 | 避免容器以 root 運行:--user 1000:1000 |
| 憑證輪換 | 鏡像倉庫 Token 每 90 天輪換一次,Git SSH Key 與個人用戶嚴格區(qū)分 |
| 數(shù)據(jù)備份 | 每日凌晨自動備份 /data/jenkins_home:tar -zcvf jenkins_backup_$(date +%Y%m%d).tar.gz /data/jenkins_home |
| 日志輪轉(zhuǎn) | 配置 Jenkins 系統(tǒng)日志保留 30 天,避免磁盤寫滿 |
十一、總結(jié)
本文系統(tǒng)地介紹了使用 Docker 部署 Jenkins 并實現(xiàn)自動化部署的完整路徑:
| 章節(jié) | 核心收獲 |
|---|---|
| 三、部署 Jenkins | 掌握 docker run 和 docker-compose 兩種容器化部署方式 |
| 四、Docker 集成 | 理解 掛載 socket 與 Docker-in-Docker 兩種方案的原理與適用場景,并根據(jù)安全要求做出正確選擇 |
| 六、憑證管理 | 學(xué)會安全存儲 Git 和鏡像倉庫的登錄憑據(jù),避免密鑰泄露 |
| 七、Jenkinsfile | 能夠獨立編寫聲明式 Pipeline,完成從代碼拉取到鏡像推送再到部署的自動化閉環(huán) |
| 八、多分支 | 掌握多分支流水線的配置,讓不同分支的 CI/CD 策略獨立運行 |
完成本教程后,你可以將這套 CI/CD 流水線快速集成到團隊的 Spring Boot、Node.js、Python 等項目之中,實現(xiàn)“一次提交,自動構(gòu)建,一鍵部署”的 DevOps 全流程。
十二、快速命令參考集
# 1. 啟動 Jenkins(掛載 socket 方案) docker run -d --name jenkins --restart always \ -p 8080:8080 -p 50000:50000 \ -v /data/jenkins_home:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ -e TZ=Asia/Shanghai \ jenkins/jenkins:lts # 2. 獲取解鎖密碼 docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword # 3. 進入容器調(diào)試 docker exec -it jenkins bash # 4. 查看實時日志 docker logs -f jenkins # 5. 重啟 Jenkins docker restart jenkins # 6. 停止并刪除容器(保留數(shù)據(jù)在 /data/jenkins_home) docker stop jenkins && docker rm jenkins # 7. 升級 Jenkins(先保留數(shù)據(jù)目錄,再用新鏡像啟動) docker pull jenkins/jenkins:lts docker stop jenkins && docker rm jenkins docker run ... # 使用相同的掛載目錄重新啟動
以上就是使用Docker部署Jenkins并實現(xiàn)自動化部署的全流程的詳細內(nèi)容,更多關(guān)于Docker部署Jenkins并自動化部署的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
docker環(huán)境調(diào)用mysqldump進行數(shù)據(jù)備份方式
這篇文章主要介紹了docker環(huán)境調(diào)用mysqldump進行數(shù)據(jù)備份方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-06-06
解決docker啟動容器錯誤:docker:Error response from dae
這篇文章主要介紹了解決docker啟動容器錯誤:docker:Error response from daemon:OCI runtime create failed問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05
Docker中鏡像構(gòu)建與緩存優(yōu)化實戰(zhàn)指南
在實際項目中,我們需要一套完善的鏡像構(gòu)建與緩存優(yōu)化方案,以提升構(gòu)建速度,降低帶寬與存儲成本,保證構(gòu)建穩(wěn)定性,下面我們就來看看具體實現(xiàn)方法吧2025-07-07

