一、为什么选择 jenkins?
jenkins 是一个开源的自动化服务器,它可以帮助我们实现:
- ✅ 持续集成(ci)
- ✅ 持续交付(cd)
- ✅ 自动化测试
- ✅ 自动化部署
- ✅ 多环境支持(开发、测试、预发布、生产)
- ✅ 插件生态丰富(超过1800+插件)
相比 gitlab ci、github actions、circleci 等工具,jenkins 在企业私有化部署、复杂流水线控制、权限管理方面具有明显优势。
官方网站:https://www.jenkins.io
二、linux 环境准备
我们假设你有一台运行 ubuntu 22.04 lts 或 centos stream 9 的服务器。以下操作均基于命令行完成。
2.1 更新系统包
# ubuntu sudo apt update && sudo apt upgrade -y # centos sudo dnf update -y
2.2 安装 java 环境(jenkins 依赖)
jenkins 推荐使用 openjdk 11 或 17:
# ubuntu 安装 openjdk 17 sudo apt install openjdk-17-jdk -y # centos 安装 openjdk 17 sudo dnf install java-17-openjdk-devel -y # 验证安装 java -version
你应该看到类似输出:
openjdk version "17.0.9" 2023-10-17 openjdk runtime environment (build 17.0.9+8-ubuntu-122.04) openjdk 64-bit server vm (build 17.0.9+8-ubuntu-122.04, mixed mode, sharing)
三、安装与配置 jenkins
3.1 添加 jenkins 官方仓库
# 导入 gpg key curl -fssl https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \ /usr/share/keyrings/jenkins-keyring.asc > /dev/null # 添加仓库源(ubuntu) echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \ https://pkg.jenkins.io/debian-stable binary/ | sudo tee \ /etc/apt/sources.list.d/jenkins.list > /dev/null # 更新包索引 sudo apt update
如果你是 centos 用户,请访问官方文档获取对应安装方式。
3.2 安装 jenkins
sudo apt install jenkins -y
3.3 启动并设置开机自启
sudo systemctl start jenkins sudo systemctl enable jenkins sudo systemctl status jenkins
你应该看到 active (running) 表示服务正常运行。
3.4 防火墙配置(如启用)
# ubuntu 使用 ufw sudo ufw allow 8080 # centos 使用 firewalld sudo firewall-cmd --permanent --add-port=8080/tcp sudo firewall-cmd --reload
3.5 获取初始管理员密码
sudo cat /var/lib/jenkins/secrets/initialadminpassword
复制输出的密码,稍后用于首次登录。
四、首次访问 jenkins web 控制台
打开浏览器,访问:
http://<your-server-ip>:8080
输入刚才获取的初始密码,进入插件安装界面。
推荐选择 “install suggested plugins” —— 这会自动安装常用插件,包括 git、maven、pipeline、ssh 等。
安装完成后,创建第一个管理员用户:
- 用户名:admin
- 密码:strongpassword123!
- 全名:administrator
- 邮箱:admin@example.com
然后设置 jenkins url(默认即可),点击 “save and finish”。
恭喜!jenkins 已成功安装并初始化!
五、基础配置与插件安装
5.1 安装必要插件
进入 manage jenkins → plugins → available plugins
搜索并安装以下插件:
- 📦 git parameter —— 支持 git 分支参数化构建
- 📦 publish over ssh —— 用于远程部署
- 📦 maven integration —— 构建 maven 项目
- 📦 pipeline utility steps —— 增强 pipeline 功能
- 📦 blue ocean —— 现代化流水线视图(可选但推荐)
安装后重启 jenkins:
sudo systemctl restart jenkins
六、创建第一个 java 项目
为了演示自动化部署,我们先创建一个简单的 spring boot 项目。
6.1 创建 maven 项目结构
mkdir -p ~/jenkins-demo-app cd ~/jenkins-demo-app
6.2 pom.xml 文件内容
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://maven.apache.org/pom/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0</modelversion>
<groupid>com.example</groupid>
<artifactid>jenkins-demo-app</artifactid>
<version>1.0.0</version>
<packaging>jar</packaging>
<parent>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>3.1.5</version>
<relativepath/>
</parent>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceencoding>utf-8</project.build.sourceencoding>
</properties>
<dependencies>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-test</artifactid>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
<configuration>
<mainclass>com.example.jenkinsdemoappapplication</mainclass>
<finalname>${project.artifactid}-${project.version}</finalname>
</configuration>
</plugin>
</plugins>
</build>
</project>6.3 创建主启动类
src/main/java/com/example/jenkinsdemoappapplication.java
package com.example;
import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.restcontroller;
@springbootapplication
@restcontroller
public class jenkinsdemoappapplication {
public static void main(string[] args) {
springapplication.run(jenkinsdemoappapplication.class, args);
}
@getmapping("/health")
public string healthcheck() {
return "✅ jenkins demo app is running! version: " + getclass().getpackage().getimplementationversion();
}
@getmapping("/info")
public appinfo getappinfo() {
return new appinfo("jenkins demo app", "1.0.0", system.getproperty("java.version"));
}
static class appinfo {
private final string name;
private final string version;
private final string javaversion;
public appinfo(string name, string version, string javaversion) {
this.name = name;
this.version = version;
this.javaversion = javaversion;
}
// getters(省略 setter,保持不可变)
public string getname() { return name; }
public string getversion() { return version; }
public string getjavaversion() { return javaversion; }
}
}6.4 创建单元测试(可选但推荐)
src/test/java/com/example/jenkinsdemoappapplicationtests.java
package com.example;
import org.junit.jupiter.api.test;
import org.springframework.boot.test.context.springboottest;
import org.springframework.boot.test.web.client.testresttemplate;
import org.springframework.boot.test.web.server.localserverport;
import org.springframework.http.responseentity;
import static org.assertj.core.api.assertions.assertthat;
@springboottest(webenvironment = springboottest.webenvironment.random_port)
class jenkinsdemoappapplicationtests {
@localserverport
private int port;
private final testresttemplate resttemplate = new testresttemplate();
@test
void contextloads() {
// 测试应用是否能正常启动
}
@test
void healthendpointreturnsok() {
responseentity<string> response = resttemplate.getforentity(
"http://localhost:" + port + "/health", string.class);
assertthat(response.getstatuscode().is2xxsuccessful()).istrue();
assertthat(response.getbody()).contains("running");
}
@test
void infoendpointreturnsjson() {
responseentity<string> response = resttemplate.getforentity(
"http://localhost:" + port + "/info", string.class);
assertthat(response.getstatuscode().is2xxsuccessful()).istrue();
assertthat(response.getbody()).contains("name");
assertthat(response.getbody()).contains("version");
}
}6.5 本地构建测试
在项目根目录执行:
mvn clean package
如果一切顺利,你会在 target/ 目录下看到生成的 jar 文件:
target/jenkins-demo-app-1.0.0.jar
运行它:
java -jar target/jenkins-demo-app-1.0.0.jar
访问 http://localhost:8080/health 应该返回健康状态信息。
七、将项目推送到 git 仓库
虽然我们不提供 github 地址,但你可以将项目推送到任意支持 git 的代码托管平台(如 gitlab、gitee、bitbucket 等)。
git init git add . git commit -m "initial commit: jenkins demo app" git remote add origin <your-git-repo-url> git push -u origin main
确保 jenkins 服务器可以访问该仓库(如果是私有仓库,需配置凭据)。
八、创建 jenkins 自由风格项目(freestyle project)
8.1 新建项目
点击 new item → 输入名称 jenkins-demo-app → 选择 freestyle project → 点击 ok。
8.2 配置源码管理
在 source code management 中选择 git:
- repository url:
https://your-git-server.com/your-group/jenkins-demo-app.git - credentials: 添加你的 git 凭据(用户名/密码或 ssh key)
8.3 配置构建触发器
勾选 build periodically,填写:
h */2 * * * # 每两小时构建一次
或勾选 poll scm:
h/5 * * * * # 每5分钟检查一次代码变更
8.4 配置构建环境
勾选 add timestamps to the console output(方便查看日志时间)
8.5 添加构建步骤
点击 add build step → 选择 invoke top-level maven targets
- maven version: 选择已安装的 maven(若未安装,需先在全局工具配置中添加)
- goals:
clean package
8.6 添加构建后操作
点击 add post-build action → archive the artifacts
- files to archive:
target/*.jar
再添加一个 → publish junit test result report
- test report xmls:
**/target/surefire-reports/test-*.xml
九、配置自动化部署(publish over ssh)
9.1 配置 ssh 服务器
进入 manage jenkins → configure system
滚动到 publish over ssh 区域:
- passphrase: (留空或设置密钥密码)
- path to key:
/var/lib/jenkins/.ssh/id_rsa(推荐使用密钥认证) - key: (粘贴私钥内容,或留空使用文件路径)
在 ssh servers 下点击 add
- name:
prod-server - hostname:
your-production-server-ip - username:
deploy - remote directory:
/home/deploy/apps
点击 test configuration,应显示 “success”。
提示:确保目标服务器上已创建 deploy 用户,并赋予相应目录写入权限。
9.2 添加部署脚本
在目标服务器(生产机)上创建部署脚本:
# 登录生产服务器 ssh deploy@your-production-server-ip # 创建部署目录 mkdir -p /home/deploy/apps/scripts mkdir -p /home/deploy/apps/logs # 创建部署脚本 nano /home/deploy/apps/scripts/deploy.sh
脚本内容如下:
#!/bin/bash
app_name="jenkins-demo-app"
version=$1
jar_file="$app_name-$version.jar"
app_dir="/home/deploy/apps"
log_dir="$app_dir/logs"
pid_file="$app_dir/app.pid"
# 创建日志目录
mkdir -p $log_dir
# 停止旧进程
if [ -f "$pid_file" ]; then
pid=$(cat $pid_file)
if ps -p $pid > /dev/null; then
echo "stopping existing process $pid..."
kill $pid
sleep 5
if ps -p $pid > /dev/null; then
kill -9 $pid
echo "force killed process $pid"
fi
fi
rm -f $pid_file
fi
# 启动新应用
echo "starting $jar_file..."
nohup java -jar $app_dir/$jar_file \
--server.port=8081 \
> $log_dir/app.log 2>&1 &
# 保存新进程id
echo $! > $pid_file
echo "application started with pid $(cat $pid_file)"
sleep 3
# 检查是否启动成功
if ps -p $(cat $pid_file) > /dev/null; then
echo "✅ deployment successful!"
exit 0
else
echo "❌ deployment failed!"
exit 1
fi赋予执行权限:
chmod +x /home/deploy/apps/scripts/deploy.sh
9.3 在 jenkins 中配置部署步骤
回到 jenkins 项目配置页面,在 构建后操作 中添加:
send build artifacts over ssh
- ssh server:
prod-server - source files:
target/jenkins-demo-app-*.jar - remove prefix:
target/ - remote directory:
/home/deploy/apps - exec command:
cd /home/deploy/apps version=$(echo jenkins-demo-app-*.jar | sed 's/jenkins-demo-app-\(.*\)\.jar/\1/') chmod +x scripts/deploy.sh ./scripts/deploy.sh $version
保存配置。
十、手动触发第一次构建
点击 build now,观察控制台输出。
如果一切顺利,你应该看到:
- 从 git 拉取代码 ✅
- maven 编译打包 ✅
- 单元测试通过 ✅
- jar 文件上传到生产服务器 ✅
- 远程执行部署脚本 ✅
- 应用成功启动 ✅
访问生产服务器上的应用:
http://<production-server-ip>:8081/health
应该看到:
✅ jenkins demo app is running! version: 1.0.0
自动化部署成功!
十一、可视化部署流程
下面是一个典型的 jenkins 自动化部署流程图:

这个流程涵盖了从代码提交到生产部署的全过程,确保每次部署都是可追踪、可验证、可回滚的。
十二、进阶:使用 pipeline 替代 freestyle 项目
虽然自由风格项目易于上手,但在复杂场景下,pipeline 更具优势:
- ✍️ 代码即配置(jenkinsfile)
- 🔄 支持阶段化构建(stage)
- 🧭 可视化流程图
- 🔄 支持并行任务
- 📦 更好的错误处理和重试机制
12.1 创建 jenkinsfile
在项目根目录创建 jenkinsfile:
pipeline {
agent any
tools {
maven 'maven 3.8.6'
jdk 'openjdk 17'
}
environment {
app_name = 'jenkins-demo-app'
server_ip = 'your-production-server-ip'
deploy_user = 'deploy'
artifact_dir = 'target'
}
stages {
stage('checkout') {
steps {
checkout scm
script {
env.build_version = sh(script: 'echo ${pom_version}', returnstdout: true).trim()
}
echo "building version: ${env.build_version}"
}
}
stage('build') {
steps {
sh 'mvn clean package -dskiptests'
}
}
stage('test') {
steps {
sh 'mvn test'
}
post {
always {
junit '**/target/surefire-reports/test-*.xml'
}
}
}
stage('deploy to production') {
when {
branch 'main'
}
steps {
sshpublisher(
publishers: [
sshpublisherdesc(
configname: 'prod-server',
transfers: [
sshtransfer(
sourcefiles: "${artifact_dir}/${app_name}-${build_version}.jar",
removeprefix: "${artifact_dir}/",
remotedirectory: "/home/deploy/apps"
)
],
usepromotiontimestamp: false,
useworkspaceinpromotion: false,
verbose: true
)
]
)
// 执行远程部署脚本
sshcommand(
remote: 'prod-server',
command: """
cd /home/deploy/apps
version=\$(echo ${app_name}-*.jar | sed 's/${app_name}-\\(.*\\)\\.jar/\\1/')
chmod +x scripts/deploy.sh
./scripts/deploy.sh \$version
"""
)
}
}
}
post {
success {
echo '✅ build and deployment completed successfully!'
// 可添加邮件、slack、钉钉等通知
}
failure {
echo '❌ build or deployment failed!'
// 发送告警通知
}
}
}12.2 创建 pipeline 项目
- new item → 输入名称 → 选择 pipeline
- 在 pipeline 区域选择 pipeline script from scm
- scm 选择 git
- repository url 填写你的 git 地址
- script path 填写
jenkinsfile - 保存并构建
pipeline 将自动读取 jenkinsfile 并执行定义的流程。
十三、多环境部署策略
真实项目通常需要多个环境:
- 🟢 开发环境(dev)
- 🟡 测试环境(qa)
- 🟠 预发布环境(staging)
- 🔴 生产环境(production)
我们可以扩展 pipeline 支持多环境:

对应的 jenkinsfile 片段:
stage('deploy') {
when {
anyof {
branch 'develop'
branch 'main'
branch 'release/*'
}
}
steps {
script {
def targetenv = ""
def serverconfig = ""
if (env.branch_name == 'develop') {
targetenv = 'qa'
serverconfig = 'qa-server'
} else if (env.branch_name.startswith('release/')) {
targetenv = 'staging'
serverconfig = 'staging-server'
} else if (env.branch_name == 'main') {
targetenv = 'production'
serverconfig = 'prod-server'
timeout(time: 5, unit: 'minutes') {
input message: "确认部署到生产环境?", ok: "部署"
}
}
echo "deploying to ${targetenv} environment..."
sshpublisher(
publishers: [
sshpublisherdesc(
configname: serverconfig,
transfers: [
sshtransfer(
sourcefiles: "${artifact_dir}/${app_name}-${build_version}.jar",
removeprefix: "${artifact_dir}/",
remotedirectory: "/home/deploy/apps"
)
]
)
]
)
sshcommand(
remote: serverconfig,
command: """
cd /home/deploy/apps
version=\$(echo ${app_name}-*.jar | sed 's/${app_name}-\\(.*\\)\\.jar/\\1/')
./scripts/deploy.sh \$version
"""
)
}
}
}这样,不同分支的代码会自动部署到对应环境,且生产环境部署前需要人工确认,避免误操作。
十四、监控与日志
14.1 jenkins 控制台日志
每次构建都会生成详细日志,可通过点击构建编号 → console output 查看。
14.2 应用日志收集
在部署脚本中,我们已经将日志重定向到文件:
> $log_dir/app.log 2>&1 &
你可以使用 tail -f 实时查看:
tail -f /home/deploy/apps/logs/app.log
14.3 健康检查端点
我们的 java 应用提供了 /health 和 /info 端点,可用于:
- 🤖 自动化健康检查
- 📊 监控系统集成(如 prometheus + grafana)
- 🚨 故障告警
示例 curl 检查:
curl http://localhost:8081/health # 输出:✅ jenkins demo app is running! version: 1.0.0
十五、安全加固建议
15.1 使用凭据管理
不要在 jenkinsfile 或配置中硬编码密码。使用 credentials binding:
withcredentials([usernamepassword(credentialsid: 'git-credentials', usernamevariable: 'git_user', passwordvariable: 'git_pass')]) {
sh "git clone https://${git_user}:${git_pass}@your-git-server/repo.git"
}
15.2 限制访问权限
- 启用 矩阵授权策略(matrix authorization strategy)
- 为不同团队分配不同权限
- 禁用匿名用户访问
15.3 定期备份
备份 jenkins 主目录:
sudo tar -czvf jenkins-backup-$(date +%y%m%d).tar.gz /var/lib/jenkins
建议每天自动备份并上传到异地存储。
十六、常见问题与解决方案
问题1:maven 构建内存不足
现象:outofmemoryerror: java heap space
解决:
# 修改 jenkins 启动参数 sudo nano /etc/default/jenkins # 添加或修改: java_opts="-xmx2g -xms512m"
然后重启 jenkins:
sudo systemctl restart jenkins
问题2:ssh 连接被拒绝
现象:failed to connect to server
解决:
- 检查目标服务器 ssh 服务是否运行:
systemctl status sshd - 检查防火墙:
sudo ufw status - 测试手动 ssh 连接:
ssh deploy@server-ip - 确保 jenkins 用户有权限读取私钥文件
问题3:部署后应用无法访问
排查步骤:
# 1. 检查进程是否存在 ps aux | grep jenkins-demo-app # 2. 检查端口监听 netstat -tlnp | grep :8081 # 3. 查看应用日志 tail -f /home/deploy/apps/logs/app.log # 4. 检查防火墙 sudo ufw status sudo ufw allow 8081 # 5. 本地测试 curl http://localhost:8081/health
十七、性能优化技巧
17.1 使用构建节点(agent)
当主节点负载过高时,可以添加构建节点:
pipeline {
agent { label 'java-builder' }
// ... 其他配置
}
在 manage jenkins → manage nodes 中添加新节点。
17.2 并行构建
对于多模块项目,可以并行构建:
stage('parallel build') {
parallel {
stage('module a') {
steps {
dir('module-a') {
sh 'mvn clean package'
}
}
}
stage('module b') {
steps {
dir('module-b') {
sh 'mvn clean package'
}
}
}
}
}17.3 缓存依赖
避免每次构建都下载 maven 依赖:
stage('build with cache') {
steps {
sh 'mkdir -p ~/.m2'
stash includes: '.m2/**', name: 'maven-cache'
sh 'mvn clean package'
unstash 'maven-cache'
}
}
或者使用 artifact manager 插件进行更高级的缓存管理。
十八、集成通知系统
18.1 邮件通知
安装 email extension plugin,在 post 部分添加:
post {
success {
emailext (
subject: "success: job '${env.job_name}'",
body: """<p>构建成功!</p>
<p>版本: ${env.build_version}</p>
<p><a href="${env.build_url}" rel="external nofollow" rel="external nofollow" >查看构建详情</a></p>""",
recipientproviders: [[$class: 'developersrecipientprovider']]
)
}
failure {
emailext (
subject: "failed: job '${env.job_name}'",
body: """<p>构建失败!</p>
<p>请尽快修复。</p>
<p><a href="${env.build_url}" rel="external nofollow" rel="external nofollow" >查看构建详情</a></p>""",
recipientproviders: [[$class: 'developersrecipientprovider']]
)
}
}
18.2 slack/钉钉通知
安装对应插件,在 pipeline 中调用:
// slack 示例
slacksend channel: '#builds', message: "构建${currentbuild.result}: ${env.job_name} #${env.build_number}"
十九、自动化测试扩展
除了单元测试,还可以集成:
- 🧪 集成测试
- 🕸️ api 测试(postman/newman)
- 🖥️ ui 测试(selenium)
- 🐞 代码质量检查(sonarqube)
示例:集成 sonarqube
stage('code quality') {
steps {
withsonarqubeenv('sonar-server') {
sh 'mvn sonar:sonar'
}
}
}
stage('quality gate') {
steps {
timeout(time: 1, unit: 'hours') {
waitforqualitygate abortpipeline: true
}
}
}二十一、总结
通过本文,你已经掌握了:
✅ 在 linux 上安装配置 jenkins
✅ 创建 java spring boot 项目
✅ 编写 jenkins pipeline 实现自动化构建
✅ 通过 ssh 实现自动化部署到生产环境
✅ 设计多环境部署策略
✅ 添加监控、日志、通知机制
✅ 解决常见问题和性能优化
jenkins 作为老牌 ci/cd 工具,虽然界面不如新兴工具现代化,但其稳定性、灵活性和强大的插件生态使其在企业环境中依然占据重要地位。
随着云原生和 kubernetes 的普及,jenkins 也在不断进化,通过 jenkins x、tekton 等项目拥抱新时代。但对于大多数传统企业应用,标准 jenkins 仍然是最佳选择。
二十二、未来演进方向
当你熟练掌握基础自动化部署后,可以考虑:
- 🐳 容器化部署(docker + jenkins)
- ☸️ kubernetes 集成
- 🔄 蓝绿部署 / 金丝雀发布
- 📊 集成监控告警系统(prometheus + alertmanager)
- 🧩 微服务架构下的多服务协同部署
自动化部署不是终点,而是 devops 旅程的起点。持续改进、持续交付、持续反馈,才能真正提升软件交付效率和质量。
记住:自动化不是为了取代人,而是让人专注于更有价值的工作。让机器去做重复、易错的任务,让开发者去创造、去创新、去解决问题。
以上就是linux使用jenkins实现自动化部署的完整指南的详细内容,更多关于linux jenkins自动化部署的资料请关注代码网其它相关文章!
发表评论