GitLab+Jenkins CI-CD自动化部署实战

作者:蓝胖的四次元口袋日期:2026/9/21

作者:没有四次元口袋的蓝胖
日期:2026-09-15
标签:CI/CD, GitLab, Jenkins, DevOps


写在前面

这是一篇 CI/CD 自动化部署实战记录。从 GitLab 代码托管、分支规范制定,到 Jenkins 自动化构建部署,完整记录了团队从零搭建 CI/CD 流水线的全过程。


一、项目背景

团队之前的部署流程:每次代码提交后,需要 手动登录服务器mvn clean package → 上传 jar/war 包 → 重启 Tomcat,流程繁琐且容易出错。

目标:引入 GitLab + Jenkins,实现"代码推送即自动构建,构建完成即自动部署"。


二、GitLab 分支规范与代码管理

2.1 Git Flow 分支策略

分支用途保护策略
master生产环境代码Protected,禁止直接 push,必须通过 MR
develop开发测试环境Protected,禁止直接 push,必须通过 MR
feature/*功能开发分支从 develop 拉出,开发完提 MR 回 develop
hotfix/*紧急修复从 master 拉出,修复完同时合并到 master 和 develop

2.2 分支保护配置

GitLab → Settings → Repository → Protected branches:

  • master、develop 均设置为 Protected
  • Allowed to merge:Maintainers
  • Allowed to push and merge:No one(禁止直接 push)
  • Require approval:至少 1 人审核

这样所有代码合并必须走 MR 流程,从制度上保障代码质量。

2.3 🎯 面试高频问题

Q:MR(Merge Request)和 PR(Pull Request)有什么区别?

本质一样,只是叫法不同。MR 是 GitLab 的叫法,PR 是 GitHub 的叫法。都是"我改了代码,请审核后再合并"。

Q:为什么不直接 push 到 master?

没有审核流程 = 任何人都能把未测试的代码推上线。MR 机制强制 Code Review + 构建验证,是生产环境的基本保障。


三、Jenkins 环境搭建

3.1 安装 Jenkins

Jenkins 基于 Java,需要先装好 JDK。这里选择用 Tomcat 部署 WAR 包的方式:

1# 1. 下载 Jenkins WAR 
2wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/latest/jenkins.war
3
4# 2. 放到 Tomcat  webapps 目录下
5cp jenkins.war /opt/tomcat/webapps/
6
7# 3. 启动 Tomcat
8/opt/tomcat/bin/startup.sh
9
10# 4. 访问 http://服务器IP:8080/jenkins
11# 首次访问需要输入初始密码
12cat /root/.jenkins/secrets/initialAdminPassword
13

3.2 插件安装

首次进入 Jenkins 选择"安装推荐插件",之后手动补充关键插件:

插件作用
Git Plugin从 GitLab 拉取代码
Maven Integration支持 Maven 项目构建
Publish Over SSH将构建产物传输到远程服务器
Email Extension构建结果邮件通知
GitLab Plugin与 GitLab 集成(Webhook + 构建状态回传)

3.3 全局工具配置

Jenkins → 系统管理 → 全局工具配置:

  • JDK:指定 JAVA_HOME 路径
  • Maven:指定 Maven 安装目录
  • Git:指定 git 可执行文件路径

3.4 凭据管理

Jenkins → Credentials → 添加凭据,配置 GitLab 的访问凭证:

  • 类型选择:SSH Username with private key(推荐)或 Username with password
  • Scope:Global(全局可用)

💡 最佳实践:所有密码、Token 都通过 Jenkins Credentials 管理,不要在脚本中硬编码!

3.5 🎯 常见坑点

坑1:Jenkins 的 SSH 密钥权限问题

Jenkins 以 jenkins 用户运行,生成 SSH 密钥后要确保 .ssh 目录权限是 700,密钥文件权限是 600,否则 SSH 连接会被拒绝。

坑2:Maven 构建时内存不足

默认 Jenkins 的 JVM 内存可能不够,大项目构建时 OOM。解决方法:修改 jenkins.xml 或启动脚本中的 -Xmx 参数。


四、Freestyle 项目配置(核心)

4.1 创建项目

Jenkins → 新建任务 → 输入项目名称 → 选择"构建一个自由风格的软件项目"。

4.2 第一阶段:源码管理

  • Source Code Management:选择 Git
  • Repository URL:填写 GitLab 仓库 SSH 地址(如 git@gitlab.example.com:group/project.git
  • Credentials:选择之前配置的 GitLab 凭据
  • Branch Specifier*/develop(根据项目环境选择分支)

4.3 第二阶段:构建触发器

选择 Build when a change is pushed to GitLab

  • Jenkins 会生成一个 Webhook URL,格式类似:
1http://jenkins-server:8080/project/项目名称  
  • 将此 URL 填入 GitLab → Settings → Webhooks
  • 勾选 Push events
  • 点击 Add webhook

Webhook 工作原理

1git push  GitLab 检测到 push   Jenkins  HTTP POST  Jenkins 触发构建
2

⚠️ 注意:GitLab 服务器必须能访问到 Jenkins 的地址。如果是内网环境,需要确保网络互通。

4.4 第三阶段:构建步骤(Build)

选择 Execute shell,填入构建脚本:

1#!/bin/bash
2echo "===== 开始构建 ====="
3
4# 设置环境变量
5export JAVA_HOME=/usr/local/java/jdk1.8
6export MAVEN_HOME=/usr/local/maven
7export PATH=$MAVEN_HOME/bin:$JAVA_HOME/bin:$PATH
8
9# Maven 编译打包(跳过测试)
10mvn clean package -DskipTests
11
12# 检查打包结果
13if [ $? -ne 0 ]; then
14    echo "构建失败!"
15    exit 1
16fi
17
18echo "===== 构建成功 ====="
19ls -lh target/*.jar
20

4.5 第四阶段:部署(Publish Over SSH)

Publish Over SSH 插件配置

Jenkins → 系统管理 → 系统配置 → Publish over SSH:

  • Path to key:SSH 私钥路径
  • SSH Servers:添加目标服务器信息
    • Name:自定义标识
    • Hostname:目标服务器 IP
    • Username:登录用户名
    • Remote Directory:远程基础路径

每个项目的 Post-build Action 配置

  • Source filestarget/*.jar(要传输的文件)
  • Remove prefixtarget(去掉路径前缀)
  • Remote directory/opt/app/project-name(部署目录)
  • Exec command(传输后执行的远程脚本):
1#!/bin/bash
2# 进入部署目录
3cd /opt/app/project-name
4
5# 备份旧版本
6cp app.jar app.jar.bak.$(date +%Y%m%d%H%M)
7
8# 停止旧进程
9pid=$(ps -ef | grep app.jar | grep -v grep | awk '{print $2}')
10if [ -n "$pid" ]; then
11    kill -9 $pid
12    echo "已停止旧进程: $pid"
13fi
14
15# 启动新应用(nohup 后台运行)
16nohup java -jar app.jar --spring.profiles.active=prod > /dev/null 2>&1 &
17echo "应用启动成功!"
18

4.6 🎯 面试高频问题

Q:构建和部署是怎么分开的?

构建在 Jenkins 所在的服务器执行 mvn clean package,产出 jar/war 文件。部署通过 Publish Over SSH 插件,将构建产物传输到目标服务器,再通过远程 Shell 脚本重启应用。两步分离的好处:构建服务器不需要和应用服务器是同一台,职责清晰。

Q:部署脚本里为什么要备份旧版本?

方便回滚。如果新版本上线后发现问题,可以快速把 .bak 文件改名恢复,不用重新构建。


五、多环境部署策略

环境分支触发方式说明
开发环境develop自动触发(git push 即构建部署)快速迭代,方便开发自测
生产环境master手动触发(Jenkins 点击"立即构建")安全可控,防止未经审核的代码上线

为什么生产环境要手动触发?

  • 防止误操作把未审核的代码推上线
  • 生产发布需要运维或负责人确认发布时间窗口
  • 可以配合上线前的检查清单(数据库变更、配置变更等)

六、构建通知与质量门禁

6.1 邮件通知

Jenkins → 项目配置 → Post-build Actions → E-mail Notification:

  • 勾选 Send separate e-mails to individuals who broke the build
  • 构建失败时自动通知相关开发者

6.2 GitLab 构建状态集成

安装 GitLab Plugin 后:

  • MR 页面会显示 Jenkins 构建状态(✅ Success / ❌ Failure)
  • 构建不通过 → 禁止合并,从流程上保障代码质量

6.3 🎯 常见坑点

坑1:邮件通知发不出去

Jenkins 默认邮件配置需要设置 SMTP 服务器。如果用 QQ/163 邮箱,需要在邮箱设置中开启 SMTP 服务并获取授权码,不是登录密码。

坑2:Webhook 配置了但不触发构建

排查步骤:

  1. 检查 Webhook URL 是否正确(注意端口和项目名称)
  2. 检查 Jenkins 项目是否勾选了 “Build when a change is pushed to GitLab”
  3. 在 GitLab Webhook 页面点 “Test” → “Push events”,查看返回状态码
  4. 检查网络:GitLab 服务器能否访问 Jenkins 地址

七、整体部署架构图

1┌──────────┐     git push      ┌──────────┐    Webhook     ┌──────────┐
2 Developer  ───────────────→   GitLab    ────────────→   Jenkins  
3  (本地)                      (代码仓库)                 (构建服务器)│
4└──────────┘                   └──────────┘               └─────┬────┘
5                                                                
6                                                     SSH 传输 jar/war
7                                                                
8                                                                
9                                                          ┌──────────┐
10                                                           App Server│
11                                                           (Tomcat)  
12                                                          └──────────┘
13                                                                
14                                                         用户访问
15                                                                
16                                                          ┌──────────┐
17                                                            Browser  
18                                                          └──────────┘
19

八、写在最后

学习建议

  1. Shell 脚本是运维的基本功awksedgrepfind 必须熟练,部署脚本离不开它们
  2. Jenkins Freestyle 适合入门,但工作中更推荐 Pipeline(Jenkinsfile),支持代码化配置、并行执行、阶段控制,建议后续学习
  3. CI/CD 不仅仅是工具配置,更重要的是理解流程设计——分支策略、环境隔离、安全门禁、回滚机制
  4. 实操建议:自己搭一套 GitLab + Jenkins 环境,从 push 到自动部署跑通全流程,面试时才能讲得清楚

🎯 面试高频三连问

Q1:描述一下你做的 CI/CD 流程?

开发在本地完成功能后,push 到 feature 分支 → 提 MR 到 develop → Jenkins 通过 Webhook 自动触发构建 → 构建成功后通过 Publish Over SSH 部署到开发环境 → 测试通过后提 MR 到 master → 运维手动触发构建部署到生产环境。

Q2:Jenkins Freestyle 和 Pipeline 有什么区别?

Freestyle 通过界面配置,适合简单场景;Pipeline 通过 Jenkinsfile 代码化配置,支持 stage、parallel、agent 等高级语法,适合复杂流程,且可以纳入 Git 版本管理。

Q3:如果 Jenkins 构建的包在目标服务器跑不起来,你怎么排查?

  1. 检查 JDK 版本是否一致;2. 检查环境变量是否齐全;3. 查看应用日志定位启动报错;4. 检查配置文件(application.yml)的环境是否匹配;5. 对比本地能跑的环境和服务器环境的差异。

GitLab+Jenkins CI-CD自动化部署实战》 是转载文章,点击查看原文


相关推荐


uni-app 安卓自有证书完全指南
90后晨仔2026/9/13

本文参考 DCloud 官方文档《Android平台签名证书(.keystore)生成指南》(ask.dcloud.net.cn/article/357… Oracle 官方 keytool 文档与 Android 签名机制原理整理而成。 一、核心前提:Android 只需要一套自有证书 在 Android 平台,签名的规则非常明确:同一个包名(Package Name)的应用,必须使用同一个证书签名,才能覆盖安装和更新。如果包名相同但签名不同,Android 系统会在安装时报错,用户必须先卸


ArcGIS JS 基础教程(30):体元系列 - VoxelSlice 体元切片
非科班Java出身GISer2026/9/5

ArcGIS JS 基础教程(30):体元系列 - VoxelSlice 体元切片 零、写在前面一、功能介绍二、功能实现2.1 创建并添加切片2.2 切片的三个核心属性2.3 管理集合(增删改) 三、功能应用四、核心代码五、在线示例六、关键 API 说明七、系列导航 零、写在前面 📌 本系列教程完整目录:ArcGIS JS 系列基础教程(100个项目常用热门功能) 💡 在线示例:完整可运行的 HTML 示例,无需任何环境配置,可直接在浏览器中打开体验 🗂️ 专


0823Keepalived + LVS(DR) + MariaDB主主 小白完整实战教程
Void 出逃2026/8/28

文章目录 Keepalived + LVS(DR) + MariaDB主主 小白完整实战教程一、业务背景与架构选型数据库业务四大刚性需求传统架构痛点本套方案组件分工项目预期收益 二、MariaDB主从/主主复制原理核心日志与线程完整同步流程 三、实验环境规划四、基础环境初始化(所有机器)1. 修改主机名、网卡IP2. router路由器开启IP转发 五、部署MariaDB,配置主主双向复制db1配置db2配置第一步:db2作为从库,同步db1(db1→db2)第二步:db1作


【系列:TDengine 工业物联网实战:从零搭起可运行系统 · 第 7 篇】
jufeng13072026/8/20

第 4 篇我们搭好了写入管线,背压、攒批、并发 worker 都就位了。可管线再高效,也得有数据往里喂。今天回到源头:数据从哪来?两条路——模拟器直接造,采集器从三源收,最终都汇入同一条 pipeline。这篇就讲四件事:物理模型、确定性 seed、归一化漏斗、坏数据去向。读完你能回答:模拟器的物理模型为什么这么设计?三源各适合什么场景?坏数据去哪了? 两条路径,一个入口 先看全局。整个系统的数据入口分成两条路,但最终汇聚到同一个 WritePipeline——就是第 4 篇讲背压、攒批、并发


uni-app 生命周期深度解析(iOS / Android / 鸿蒙 / Vue3 四端对照)
90后晨仔2026/8/7

📌 本文定位: 面向同时具备 iOS、Android、鸿蒙原生开发经验,正在转向 uni-app 的资深工程师。所有技术点均基于 uni-app 官方文档 及 Vue3 官方文档整理。 一、先搞懂一个 JS 语法问题:为什么说"与 data/methods 平级的叫生命周期"? 很多原生工程师初学 uni-app 时会对这句话感到困惑。我们从 JavaScript 语言层面彻底讲清楚。 1.1 Options API 的本质是一个"配置对象" 在 Vue2/Vue3 的 Options A


GPT 5.6 的真正变革:从"最强模型"到"最合适模型",AI 工程范式正在重置
浮生望2026/7/29

摘要: GPT 5.6以Sol、Terra、Luna三层架构重新定义AI使用方式。跑分不再决定竞争力,真正的差距在于把什么任务分给什么模型,用更少Token和更少返工完成更高质量交付。AI正从顾问变成协作者。 每次新模型发布,人们都在问同一个问题,但那个问题已经过时了 GPT 5.6 发布后,讨论一如既往地集中在几个老问题上:跑分涨了多少?代码能力有没有超过 Claude?谁又成了"最强模型"? 这些问题很重要,但如果你只盯着它们,就错过了 GPT 5.6 真正改变游戏规则的地方。 Open


影像创作领域的GitHub!深度体验了这个国产AI,我卸了3个AI视频工具!
程序员X小鹿2026/7/21

大家好,我是X小鹿,今天分享一个不一样的 AI 视频工具。 以前做一条 AI 短片,从剧本创作、脚本编写、到角色定妆、场景道具生成、再到分镜生成、视频生成,以及最后的剪辑成片,每一步都需要用到单独的工具。 生成一条短片,需要在多个工具间来回切换。 后来也陆续出现了一些 AI 视频工具,把上面的很多流程都集成在了一个平台上,用起来确实比之前方便了不少。 最近用了 AI 视频创作平台 updream ,发现它虽然也是将很多功能集成在了一起,但和之前接触的一些 AI 视频工具又不太一样。 体验下来,


图像的分辨率
元來2026/7/12

一、什么是分辨率 图像分辨率表示: 图像能够表示多少空间细节,或者图像在水平和垂直方向上包含多少个像素。 日常最常见的分辨率写法是: 宽度 × 高度 例如: 1920 × 1080 4096 × 4096 6144 × 6144 其中: 1920表示图像水平方向有1920个像素;1080表示图像垂直方向有1080个像素。 因此一张1920 × 1080的图像,像素总数为:1920×1080=2,073,600 即大约207万个像素,也可以称为约200万像素图像。 二、


OpenCV-Python实战(31)——实时面部情绪检测与识别系统
盼小辉丶2026/7/4

OpenCV-Python实战(31)——实时面部情绪检测与识别系统 0. 前言1. 规划应用程序1. 人脸检测1.1 基于 Haar 的级联分类器1.2 预训练的级联分类器1.3 使用预训练的级联分类器1.4 FaceDetector 类 2. 收集数据2.1 构建训练数据集2.2 运行应用程序2.3 实现数据收集器 GUI 3. 面部情绪识别3.1 处理数据集3.2 多层感知机3.3 构建 MLP用于面部表情识别 4. 整合所有内容小结系列链接 0. 前言 我


2026年6月远程控制软件横评:UU远程、ToDesk、向日葵全方位对比
凤年徐2026/6/26

2026远程控制软件横评:UU远程、ToDesk、向日葵全方位对比 远程控制早已不是“应急连一下电脑”那么简单了。开发者用它连服务器改代码,设计师用它调家里的渲染机,留学生用它操作国内的网盘和银行App,甚至游戏玩家也用它“云挂机”。市面上主流的三款工具——UU远程、ToDesk、向日葵——各有拥趸,但到底谁在哪个场景下更顺手?这篇横评不吹不黑,直接把你最关心的七个核心能力摆在一起,逐项对比。 一、终端能力:谁能让开发者真正扔掉SSH客户端? 对于开发者、运维和AI训练者来说,远程命令行是最

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 聚合阅读