☰
CentOS7上从零搭建Jenkins+Maven+Gitee自动化构建环境
2026/10/1 1:37:29 网站建设 项目流程

先说一下写这篇的动机。做 Java 项目最烦的就是手动发版:本地mvn clean package、传包到服务器、备份旧包、重启服务,一套流程少说十分钟,中间哪个环节出错还得重来。后来我把 CI 这一环接上了 Jenkins,让 Gitee 上每次 push 都自动触发构建,代码入库即出包,省下来的时间非常可观。这篇就完整记录我在 Centos7 上从零搭建这套环境的过程,环境组合是:Centos7 + JDK 1.8 + Jenkins 2.346 + Maven + Git + Gitee。

网上围绕这个主题的教程很零散,而且不少在版本兼容性上翻车,特别是 Jenkins 新版本和 JDK8 之间的兼容性坑。我特意选了 Jenkins 2.346 系列,这是官方最后一个能安心跑在 JDK8 上的稳定版本线,对大多数还在用 Java 8 的存量项目非常合适。文章从服务器准备讲起,覆盖 JDK、Jenkins、Maven、Git 的安装配置,一直到和 Gitee 仓库打通、跑通一次自动构建,适合刚接触 CI/CD 的开发测试,以及想在公司内网快速落地一套构建环境的运维同学。跟着操作基本能一次跑通,中途可能会踩的坑我也一并写了。

1. 版本选型与安装思路:为什么是 JDK8 + Jenkins 2.346

1.1 关键版本兼容性,不要在新版上死磕 JDK8

很多人上来就装最新版 Jenkins,然后发现项目是 JDK8 的,构建时各种UnsupportedClassVersionError,或者 Jenkins 本身起都起不来。原因很直接:Jenkins 从 2.357 这一代开始,把运行所依赖的 Java 最低版本提到了 11,越往后越不再照顾 Java 8。如果你还在维护老项目,最好的选择不是去追新,而是锁定 2.346 这条稳定线。

为什么选 2.346 而不是最新的 2.3xx 或者 2.4xx?因为 2.346 系列是社区公认的最后一条默认兼容 JDK8 的稳定版本线,配套的插件生态也成熟。我用的具体版本是 2.346.3,这是 2.346 生命周期内较新的修复版本,安全性和稳定性都有保证。项目跑在 JDK8 上,Jenkins 本身也用 JDK8 启动,这样整条构建链路的环境是一致的,排查问题的时候少一层“版本不对”的干扰。

Maven 版本也要匹配 JDK8。Maven 3.6.3 是经典选择,官方明确支持 JDK8,而且被大量项目验证过。Maven 3.8 以上的版本虽然也能跑在 JDK8 上,但没必要为了一时新意去冒兼容性风险。Git 客户端用 Centos7 自带的 1.8.3.1 就够了,拉取 Gitee 仓库、切换分支、打标签这些基础操作完全够用,不需要额外编译新版本。

1.2 服务器准备与目录规划,先想清楚再动手

安装前先把服务器环境理顺,能省掉后面很多麻烦。我用的是 Centos7 最小化安装,装完第一件事是把系统源切到国内镜像,不然yum install能慢到让人怀疑人生。然后是目录规划,建议统一规范,方便以后维护:

  • JDK 放/usr/local/java/
  • Maven 放/usr/local/maven/
  • Jenkins 的 war 包放/opt/jenkins/
  • Jenkins 的工作目录(JENKINS_HOME)用/var/lib/jenkins/
  • Maven 本地仓库缓存独立放/data/maven-repo/

为什么要单独规划 Maven 本地仓库?因为第一次构建会下载大量依赖 jar 包,如果默认放在 Jenkins 用户家目录的.m2/repository下,一方面后续想清理不方便,另一方面如果换用户执行构建,又得重新下载一轮。独立目录的好处是多个用户、多个任务可以共享同一份依赖缓存,备份和清理也直观。

防火墙和 SELinux 也需要处理。如果是自己学习用的测试机,可以直接systemctl stop firewalld加setenforce 0,省心;如果是在生产环境,我建议只放行 8080 端口,而不是粗暴关闭防火墙。SELinux 这块,Centos7 默认 enforcing 会对 Jenkins 读写某些目录有影响,稳妥做法是先在测试环境关闭,跑通后再根据实际日志逐个放行。下面给一组常用的放行命令:

# 放行 8080 端口 firewall-cmd --permanent --add-port=8080/tcp firewall-cmd --reload # 临时关闭 SELinux(重启前有效) setenforce 0

2. JDK 1.8 安装与环境变量配置

2.1 用 tar.gz 方式安装 JDK,避免 yum 版本混乱

Centos7 上安装 JDK 有几种方式:yum install java-1.8.0-openjdk、用 Oracle JDK 的 rpm 包、或者用 tar.gz 解压。我最推荐的是 tar.gz 解压方式,原因有三:第一,目录结构完全可控,JAVA_HOME 指向哪里一目了然;第二,不依赖系统包管理,不会出现多个 JDK 版本互相干扰;第三,卸载时删目录就行,干净利落。

我安装的是jdk-8u202-linux-x64.tar.gz。为什么选 8u202?8u211 开始 Oracle JDK 的授权条款发生了变化,8u202 被普遍认为是最后一个“技术圈默认使用”的 Oracle JDK 8 版本。如果你用的是 OpenJDK,就无所谓这个版本卡点,但目录结构可能略有差异。

下载地址建议用国内镜像,Oracle 官网现在下载需要登录,容易卡在账号环节。可以用华为云镜像这类国内源下载,命令如下:

mkdir -p /usr/local/java cd /usr/local/java wget https://repo.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gz tar -zxvf jdk-8u202-linux-x64.tar.gz

解压完成之后,确认/usr/local/java/jdk1.8.0_202目录存在。如果下载失败,可以换一个镜像站,或者用本地下载后再通过scp/rz上传到服务器,关键是拿到 tar.gz 包,后面的步骤完全一样。

2.2 JAVA_HOME 环境变量配置与验证

JDK 解压完只是第一步,接下来要配置环境变量。打开/etc/profile文件,在末尾追加以下内容:

cat >> /etc/profile <<'EOF' export JAVA_HOME=/usr/local/java/jdk1.8.0_202 export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar EOF source /etc/profile

为什么把环境变量写到/etc/profile而不是~/.bashrc?因为 Jenkins 的 systemd 服务不读这两个文件,但后续在命令行里调试 java、mvn 命令时,/etc/profile对所有登录用户都生效,更适合这类全局工具。CLASSPATH那一行在 JDK9 以后已经不需要了,但 JDK8 时代很多项目还是会引用,写上也无害。

配置完成后验证:

echo $JAVA_HOME java -version javac -version

如果之前服务器上装过 openjdk,java -version可能会显示系统的 openjdk 版本。这时可以用alternatives --config java切换默认版本,或者保证 PATH 环境变量中$JAVA_HOME/bin排在/usr/bin前面。我遇到过一次 source 之后当前终端正常,新开终端又变回 openjdk 的情况,后来发现是 bash 的hash缓存了旧命令路径,执行hash -r清一下就好。

2.3 环境变量不生效的排查思路

环境变量不生效是高频问题,总结下来无外乎几种原因。第一种,改完/etc/profile后没有重新登录,新开的终端如果是图形终端或某些非登录 shell,不会主动读取/etc/profile,这时要么执行source /etc/profile,要么重新 SSH 登录。第二种,系统中存在多个 JDK,which java发现指向的是/usr/bin/java而不是$JAVA_HOME/bin/java,需要用alternatives调整,或者调整 PATH 顺序。第三种,某些服务进程是启动时才读取环境变量的,修改完环境变量后旧进程必须重启才生效,比如后面要讲的 Jenkins 服务。

还有一个很容易被忽略的细节:如果你把 JDK 解压到了/root或者其他管理员目录下,tomcat、jenkins 这类以普通用户身份运行的程序可能会因为权限不足读不到。所以 JDK 这种全局工具,统一解压到/usr/local/下面比较稳妥,普通用户至少要有可读和可执行权限。

3. Jenkins 2.346 安装与初始化

3.1 用 war 包 + systemd 部署,锁定版本更可控

安装 Jenkins 常见有 yum 源安装和 war 包部署两种方式。yum 方式看似省事,但有个很现实的问题:Jenkins 官方 yum 源当前已经切到新版本系列,你yum install装出来的大概率不是 2.346,而是要求 JDK11+ 的新版本,和我们要锁定的 JDK8 环境直接冲突。所以我强烈建议用 war 包方式,版本完全自己控制,配合 systemd 管理也有模有样。

先创建目录、下载 war 包:

mkdir -p /opt/jenkins /var/lib/jenkins /var/cache/jenkins/war cd /opt/jenkins wget https://get.jenkins.io/war-stable/2.346.3/jenkins.war

如果官方下载比较慢,可以从清华镜像下载:

wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/2.346.3/jenkins.war

然后创建 Jenkins 运行用户并授权目录:

useradd -m -s /bin/bash jenkins chown -R jenkins:jenkins /var/lib/jenkins /var/cache/jenkins /opt/jenkins

接下来写 systemd 服务文件/etc/systemd/system/jenkins.service:

[Unit] Description=Jenkins Continuous Integration Server After=network.target [Service] User=jenkins Group=jenkins Environment="JENKINS_HOME=/var/lib/jenkins" Environment="JAVA_HOME=/usr/local/java/jdk1.8.0_202" ExecStart=/usr/local/java/jdk1.8.0_202/bin/java -Xms512m -Xmx1024m -Duser.timezone=Asia/Shanghai -Dfile.encoding=UTF-8 -jar /opt/jenkins/jenkins.war --httpPort=8080 --webroot=/var/cache/jenkins/war Restart=on-failure RestartSec=10 WorkingDirectory=/var/lib/jenkins [Install] WantedBy=multi-user.target

这个文件里有几个细节值得说明。Environment=JAVA_HOME=...是必须的,因为 systemd 启动的进程不会读取/etc/profile,不以这种方式传进去,Jenkins 就找不到 JDK。-Duser.timezone=Asia/Shanghai解决 Jenkins 页面时区显示 UTC 的问题,-Dfile.encoding=UTF-8解决构建日志中文乱码的问题,这两个参数建议直接写死在启动命令里。

启动和设置开机自启:

systemctl daemon-reload systemctl start jenkins systemctl enable jenkins

查看服务状态:systemctl status jenkins。如果启动失败,用journalctl -fu jenkins看详细日志,大部分问题都能在这里看到原因。

3.2 初始化 Jenkins,先不装推荐插件

浏览器访问http://服务器IP:8080,第一次进入会要求输入解锁密码。密码存放在 Jenkins 工作目录下:

cat /var/lib/jenkins/secrets/initialAdminPassword

把输出的密码复制进去,进入自定义插件安装页面。这里我建议不要选 “Install suggested plugins”,推荐插件数量多、耗时长,在国内网络环境下很容易卡在下载步骤。直接选 “Select plugins to install”,手动选择几个刚需插件——Git、Timestamper、Gitee 这些后面会用到。其他插件后续在 Manage Plugins 里按需安装就行。

插件安装完成后创建管理员账号,填写用户名密码邮箱。这里有个小坑:保存 Jenkins URL 时,默认往往填的是http://localhost:8080,如果你后续要配置 Gitee Webhook,这个地址必须是其他机器能访问到的地址,建议直接改成服务器公网 IP 或者内网可访问的地址,不然后面回调会打到 localhost 上。

3.3 时区与国内插件源加速

初始化完成后,第一件事就是处理时区和插件源。时区方面,如果 systemd 配置里已经带了-Duser.timezone=Asia/Shanghai,重启后页面就是北京时间。如果没配,可以在 Manage Jenkins → Script Console 里执行:

System.setProperty('org.apache.commons.jelly.tags.fmt.timeZone', 'Asia/Shanghai') System.setProperty('user.timezone', 'Asia/Shanghai')

插件源加速也一样重要。默认插件源在海外,安装插件慢不说,还经常超时失败。在 Manage Jenkins → Manage Plugins → Advanced 页面,把 Update Site 改成清华镜像:

https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

如果之前已经拉取过插件元数据,/var/lib/jenkins/updates/default.json里还存着旧的下载地址,可以用 sed 把下载域名替换成镜像地址:

sed -i 's#https://updates.jenkins.io/download#https://mirrors.tuna.tsinghua.edu.cn/jenkins#g' /var/lib/jenkins/updates/default.json

改完重启 Jenkins,再去安装插件,速度会有质的提升。

4. Maven 与 Git 的安装配置

4.1 Maven 在 Jenkins 里到底负责什么

很多刚入门的人会把 Maven 和 Git 搞混,这里捋一下。Git 管的是代码版本,谁改了什么、分支怎么切换、历史怎么回溯,都是 Git 的事;Maven 管的是项目构建和依赖,它读pom.xml这个“菜谱”,从中央仓库“买菜”(下载依赖 jar),然后“做菜”(编译、测试、打包)。Jenkins 则是“调度员”,它负责在代码变更时喊一声:该去拉代码了,拉完叫 Maven 干活,干完了把产物收起来。

所以 Jenkins 所在的机器上必须有 Maven,而且 Jenkins 用户要能访问到 Maven 的目录,还要能写本地仓库目录。如果 Jenkins 构建时报mvn: command not found,大概率就是环境变量只在 root 用户下配了,Jenkins 用户根本找不到命令,这个下面会细说。

4.2 安装 Maven 并配置阿里云镜像

Maven 下载同样建议用国内镜像。我在/usr/local/maven目录下安装:

mkdir -p /usr/local/maven && cd /usr/local/maven wget https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz tar -zxvf apache-maven-3.6.3-bin.tar.gz

解压后配置环境变量,同样追加到/etc/profile:

cat >> /etc/profile <<'EOF' export MAVEN_HOME=/usr/local/maven/apache-maven-3.6.3 export PATH=$MAVEN_HOME/bin:$PATH EOF source /etc/profile mvn -version

看到输出了 Java version 和 Maven home,说明安装成功。但光装完还不够,不配镜像的话,第一次构建就会卡在从中央仓库下载依赖这一步,慢到怀疑人生。修改 Maven 的settings.xml:

vi /usr/local/maven/apache-maven-3.6.3/conf/settings.xml

把本地仓库路径改成独立目录:

<localRepository>/data/maven-repo</localRepository>

然后在<mirrors>节点里加阿里云镜像:

<mirror> <id>aliyunmaven</id> <mirrorOf>central</mirrorOf> <name>aliyun public</name> <url>https://maven.aliyun.com/repository/public</url> </mirror>

最后创建目录并授权给 Jenkins 用户,因为构建时是 Jenkins 用户在写依赖缓存:

mkdir -p /data/maven-repo chown -R jenkins:jenkins /data/maven-repo

4.3 Git 安装与 Jenkins 用户初始化

Centos7 安装 Git 很简单:

yum install -y git git --version

版本号是 1.8.3.1,别看它老,配合 Jenkins 拉取 Gitee 仓库完全没问题。Git 装完后,顺手给 Jenkins 用户配置全局身份信息,有些 Jenkins 插件需要user.name和user.email才能正常工作:

su - jenkins -s /bin/bash -c 'git config --global user.name "jenkins"' su - jenkins -s /bin/bash -c 'git config --global user.email "jenkins@buildserver.local"'

这一步不是必须的,但提前配置可以避免某些插件在构建时因为缺少身份信息报奇怪的错误。

5. 将 JDK、Maven、Git 配置进 Jenkins 并与 Gitee 打通

5.1 Global Tool Configuration:把三个工具登记进 Jenkins

系统装了 JDK、Maven、Git,Jenkins 并不知道路径在哪里,需要手动登记。进入 Manage Jenkins → Tools,也就是 Global Tool Configuration。

JDK 部分点击 Add JDK,名称填jdk-1.8,关键一步是取消勾选 “Install automatically”。默认勾选后 Jenkins 会尝试自己下载 JDK,网络慢外加版本选择麻烦,我们既然已经手动装好了,就直接把自动安装关掉,填 JAVA_HOME 路径/usr/local/java/jdk1.8.0_202。

Git 部分在 Git 一栏把 Path to Git executable 填/usr/bin/git。

Maven 部分点击 Add Maven,名称填maven-3.6.3,同样取消 “Install automatically”,填 MAVEN_HOME/usr/local/maven/apache-maven-3.6.3。

这里多说一句:很多教程没提取消自动安装这一步,导致配置完保存后 Jenkins 后台尝试下载工具,半天没反应,还以为卡死了。手动装好的工具,一定要取消自动安装选项,路径填准,保存即可。

5.2 添加 Gitee 访问凭据,推荐用私人令牌

Jenkins 要拉取 Gitee 上的私有仓库,必须配置凭据。最佳实践不是直接填 Gitee 密码,而是用 Gitee 私人令牌,好处是可以单独授权、单独吊销,不会暴露主账号密码。

在 Gitee 网页上:头像 → 设置 → 安全设置 → 私人令牌 → 生成新令牌,权限勾选 projects 相关的读取权限就行。生成的令牌只会显示一次,记得复制保存。

然后在 Jenkins 里:Manage Jenkins → Manage Credentials → Global credentials → Add credentials,类型选 “Username with password”:

  • Username:你的 Gitee 用户名
  • Password:粘贴刚刚生成的私人令牌
  • ID:填gitee-token,方便后续任务里识别

保存后,后面新建任务时就能直接选这个凭据了。

5.3 新建自由风格任务并跑通一次构建

配置完成后,新建一个自由风格项目测试一下。在 Jenkins 首页点击 New Item,输入项目名称,选择 “Freestyle project”,确定。

源码管理选择 Git:

Repository URL: https://gitee.com/你的用户名/仓库名.git Credentials: gitee-token Branches to build: */main

分支名根据 Gitee 仓库默认分支来,如果仓库默认是 master 就填*/master。填完 URL 后,如果凭据配置正确,一般不会报红色错误。

构建环境勾选 “Add timestamps to the Console Output”,这样构建日志里会显示时间,排查问题方便。构建步骤选择 “Invoke top-level Maven targets”:

  • Maven Version:选maven-3.6.3
  • Goals:填clean package
  • Settings file:选择 “Use custom settings”,路径填/usr/local/maven/apache-maven-3.6.3/conf/settings.xml

为什么要显式指定 settings.xml?因为 Jenkins 运行任务时不一定能读到/etc/profile里的环境变量,Maven 默认配置也不一定是我们刚改过的那份。显式指定后,阿里云镜像和本地仓库目录就能稳定生效。

保存后点击 “Build Now”,再点击构建历史里的项目进入 Console Output,第一次构建会花不少时间下载依赖,看到BUILD SUCCESS就是跑通了。构建产物在这个位置:

ls -lh /var/lib/jenkins/workspace/项目名称/target/

5.4 配置 Gitee Webhook,实现 push 自动触发构建

手动触发构建只是第一步,真正的 CI 是 Gitee 上代码一 push,Jenkins 自动构建。使用 Gitee Plugin 可以实现。

先在 Manage Jenkins → Manage Plugins 里搜索安装 “Gitee Plugin”,然后在 Manage Jenkins → System 页面找到 Gitee Configuration,确认链接地址是https://gitee.com,保存。

打开刚才创建的任务,左侧菜单里能看到 “Gitee Webhook” 链接,点开会显示回调 URL 和 token,形式大致是:

http://你的Jenkins地址:8080/gitee-webhook/ token: 一串随机字符

到 Gitee 仓库页面:管理 → WebHooks → 添加 WebHook:

  • URL 填上面的回调地址
  • 密码(推送秘密)填上面显示的 token
  • 事件勾选 Push

保存后可以先点“测试”按钮,如果返回正常,说明回调通。然后本地git push一次,Jenkins 就会自动触发构建。

有个前提必须说清楚:Jenkins 所在服务器必须能被 Gitee 公网访问到。如果 Jenkins 部署在内网,Webhook 回调会失败,这种情况暂时只能手动触发或者用定时构建过渡,等有了公网地址或反向代理再启用。

6. 常见问题与排查经验速查

6.1 高频报错与解决对照表

整套流程走下来,新手容易在这几个地方卡住:

问题现象常见原因解决办法
8080 端口访问超时防火墙未放行 / 云安全组未开放firewall-cmd --permanent --add-port=8080/tcp并 reload,同时检查云平台安全组
解锁密码找不到JENKINS_HOME 路径被修改过find / -name initialAdminPassword全局搜索
插件安装慢或失败默认插件源在海外修改 Update Site 为清华镜像,修改updates/default.json中的下载域名
构建任务里 mvn 命令找不到systemd 或 Jenkins 进程没加载/etc/profile使用 Maven 构建步骤并选择已配置的 Maven,而不是在 shell 里写裸命令
Gitee 仓库拉取 401/403凭据未配置或 token 权限不足重新添加凭据,检查 token 是否勾选了 projects 权限
构建日志显示 UTC 时间未设置时区参数在 JVM 启动参数里加-Duser.timezone=Asia/Shanghai后重启
中文乱码编码未指定在 systemd 启动参数加-Dfile.encoding=UTF-8,Maven 配置里也声明 UTF-8
Webhook 测试返回 404Jenkins 地址不可公网访问 / Gitee 插件未装确认 Webhook URL 和 token 正确,Jenkins 上安装 Gitee Plugin 并配置

6.2 三个值得说一说的踩坑经历

第一个坑是 yum 源装了新版 Jenkins。早期我图省事直接走 yum,结果装出来的 Jenkins 版本要求 JDK11,项目环境是 JDK8,最后服务起不来。后来统一改用 war 包 + systemd 方式固定 2.346.3,问题一次解决。现在我对生产环境的工具版本态度很明确:锁定版本比追新重要,尤其是 CI 这种链条中间环节,任何一个依赖版本漂移都可能引发连锁故障。

第二个坑是环境变量不生效。我在/etc/profile里配好了 JAVA_HOME,命令行测试一切正常,结果 Jenkins 服务就是起不来,报找不到 Java。查了半天发现 systemd 启动进程不读/etc/profile,必须在 service 文件里通过 Environment 参数显式传入。这个问题在 cron 定时任务里也会遇到,统一规律是:脱离登录 shell 的进程,都要显式指定关键环境变量。

第三个坑是第一次构建时依赖下载缓慢。当时没用 Maven 镜像,构建任务卡在下载依赖停了很久,最后超时失败。配置阿里云镜像和独立本地仓库后,构建速度提升非常明显。后来我干脆把/data/maven-repo和/var/lib/jenkins/workspace从系统盘挪到了数据盘,既避免系统盘空间不足,也方便备份。

这套环境搭完,我的习惯是先手动 Build Now 跑通一次,确认 BUILD SUCCESS 再去接 Webhook,这样出问题时排查范围更小。后续还可以继续扩展:构建完把 war/jar 包通过 Publish Over SSH 推到测试服务器、用流水线把 Jenkinsfile 放进仓库管理、加钉钉或企业微信的通知。先把这篇里的链路跑通,后面每一步都是在这个基础上加砖添瓦。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询