Linux使用Jenkins实现自动化部署的完整指南
一、为什么选择 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自动化部署的资料请关注脚本之家其它相关文章!
相关文章
在Apache服务器上利用Varnish优化移动端访问的方法
这篇文章主要介绍了在Apach服务器上利用Varnish优化移动端访问的方法,包括清除缓存等常用操作的介绍,需要的朋友可以参考下2015-06-06


最新评论