本文目录导读:

在Jenkins中部署应用到生产环境的脚本编写,核心在于实现自动化、安全、可回滚的流程,以下为你介绍几种主流方式及其对应的Jenkins Pipeline脚本示例。
核心原则
- 自动化:减少人工干预,从代码提交到部署全流程自动化。
- 一致性:确保开发、测试、生产环境部署方式相同。
- 零停机:使用蓝绿部署、滚动更新或金丝雀发布策略。
- 回滚能力:具备快速回滚到上一个稳定版本的能力。
- 安全:生产环境凭证(密码、密钥)通过Jenkins凭据管理,不硬编码。
不同部署方式的Jenkins脚本示例
SSH + 传统应用(如JAR包、Node.js应用)
适用于非容器化应用,通过SSH将构建产物传输到生产服务器,执行远程命令。
部署流程:构建 → 打包 → SCP传输 → SSH连接 → 停止旧服务 → 备份旧版本 → 启动新服务。
pipeline {
agent any
environment {
// SSH凭据ID(在Jenkins凭据中配置)
SSH_CREDENTIALS = credentials('ssh-credentials-id')
PRODUCTION_HOST = 'your-production-server.com'
APP_DIR = '/opt/myapp'
BACKUP_DIR = '/opt/myapp/backups'
}
stages {
stage('构建') {
steps {
echo '构建项目...'
sh 'npm install && npm run build'
}
}
stage('打包构建产物') {
steps {
echo '打包分发文件...'
sh '''
tar -czf app.tar.gz dist/
# 保存当前构建号作为版本标识
echo "${BUILD_NUMBER}" > version.txt
'''
}
}
stage('部署到生产环境') {
steps {
sshagent(['ssh-credentials-id']) {
// 1. 传输构建产物
sh """
scp -o StrictHostKeyChecking=no app.tar.gz version.txt \
user@${PRODUCTION_HOST}:${APP_DIR}/
"""
// 2. 远程执行部署脚本
sh """
ssh user@${PRODUCTION_HOST} "
set -e
# 备份旧版本
mkdir -p ${BACKUP_DIR}
cp -r ${APP_DIR}/current ${BACKUP_DIR}/backup_\$(date +%Y%m%d_%H%M%S) 2>/dev/null || true
# 解压新版本到临时目录
mkdir -p ${APP_DIR}/new_release
tar -xzf ${APP_DIR}/app.tar.gz -C ${APP_DIR}/new_release
# 停止旧应用
systemctl stop myapp || true
# 替换应用目录
rm -rf ${APP_DIR}/current
mv ${APP_DIR}/new_release ${APP_DIR}/current
# 启动新应用
systemctl start myapp
# 清理
rm ${APP_DIR}/app.tar.gz ${APP_DIR}/version.txt
echo '部署完成'
"
"""
}
}
post {
failure {
echo '部署失败,尝试回滚...'
// 回滚逻辑
sshagent(['ssh-credentials-id']) {
sh """
ssh user@${PRODUCTION_HOST} "
systemctl stop myapp || true
rm -rf ${APP_DIR}/current
mv \$(ls -t ${BACKUP_DIR}/ | head -1) ${APP_DIR}/current
systemctl start myapp
"
"""
}
}
}
}
}
}
Docker容器化应用(推荐)
适用于微服务架构和现代应用。
部署流程:构建镜像 → 推送到镜像仓库 → SSH连接生产服务器 → 拉取新镜像 → 重启容器。
pipeline {
agent any
environment {
DOCKER_REGISTRY = 'your-registry.com'
IMAGE_NAME = 'myapp'
IMAGE_TAG = "${BUILD_NUMBER}-${env.GIT_COMMIT.take(7)}"
PRODUCTION_HOST = 'your-production-server.com'
}
stages {
stage('构建Docker镜像') {
steps {
script {
docker.build("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}")
}
}
}
stage('推送镜像到仓库') {
steps {
withDockerRegistry([credentialsId: 'docker-registry-credentials', url: "https://${DOCKER_REGISTRY}"]) {
script {
docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}").push()
// 同时标记为latest方便回滚
docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}").push('latest')
}
}
}
}
stage('部署到生产环境') {
steps {
sshagent(['ssh-credentials-id']) {
sh """
ssh user@${PRODUCTION_HOST} "
set -e
# 拉取新镜像
docker pull ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}
# 停止并删除旧容器(保留旧版本标签)
docker stop myapp || true
docker rm myapp || true
# 启动新容器
docker run -d \\
--name myapp \\
--restart always \\
-p 8080:8080 \\
-e ENV=production \\
${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}
# 清理旧镜像(保留最近5个版本)
docker image prune -a --filter 'until=24h' -f
"
"""
}
}
}
stage('健康检查') {
steps {
sh """
sleep 10
curl -f http://${PRODUCTION_HOST}:8080/health || exit 1
"""
echo '健康检查通过'
}
}
}
post {
failure {
echo '部署失败或健康检查不通过,执行回滚...'
sshagent(['ssh-credentials-id']) {
sh """
ssh user@${PRODUCTION_HOST} "
# 回滚到上一个版本(假设上次使用的标签是latest或上一个构建号)
docker pull ${DOCKER_REGISTRY}/${IMAGE_NAME}:previous
docker stop myapp || true
docker rm myapp || true
docker run -d --name myapp -p 8080:8080 ${DOCKER_REGISTRY}/${IMAGE_NAME}:previous
"
"""
}
}
}
}
Kubernetes集群部署
适用于容器编排场景,最强大也最复杂。
部署流程:构建镜像 → 推送到仓库 → 更新K8s部署配置文件 → 应用配置。
pipeline {
agent any
environment {
K8S_NAMESPACE = 'production'
APP_NAME = 'myapp'
IMAGE_TAG = "${BUILD_NUMBER}-${env.GIT_COMMIT.take(7)}"
DOCKER_REGISTRY = 'your-registry.com'
}
stages {
stage('构建并推送Docker镜像') {
steps {
script {
docker.build("${DOCKER_REGISTRY}/${APP_NAME}:${IMAGE_TAG}")
withDockerRegistry([credentialsId: 'docker-registry-credentials']) {
docker.image("${DOCKER_REGISTRY}/${APP_NAME}:${IMAGE_TAG}").push()
}
}
}
}
stage('更新Kubernetes部署') {
steps {
// 使用kubectl更新镜像版本
withKubeConfig([credentialsId: 'kubeconfig-id']) {
sh """
# 更新部署文件中的镜像版本
sed -i 's|image:.*|image: ${DOCKER_REGISTRY}/${APP_NAME}:${IMAGE_TAG}|' k8s/deployment.yaml
# 应用配置
kubectl apply -f k8s/deployment.yaml -n ${K8S_NAMESPACE}
# 监控滚动更新状态
kubectl rollout status deployment/${APP_NAME} -n ${K8S_NAMESPACE} --timeout=5m
"""
}
}
}
stage('验证部署') {
steps {
withKubeConfig([credentialsId: 'kubeconfig-id']) {
sh """
# 获取pod状态
kubectl get pods -l app=${APP_NAME} -n ${K8S_NAMESPACE}
# 将成功版本记录为稳定版本
kubectl annotate deployment/${APP_NAME} -n ${K8S_NAMESPACE} \
"rollback-version=${IMAGE_TAG}"
"""
}
}
}
}
post {
failure {
echo '部署失败,执行回滚...'
withKubeConfig([credentialsId: 'kubeconfig-id']) {
sh "kubectl rollout undo deployment/${APP_NAME} -n ${K8S_NAMESPACE}"
}
}
}
}
生产环境部署的最佳实践
分阶段发布策略
在pipeline中添加审批环节:
stage('部署到生产环境') {
input {
message "确认部署到生产环境 ${BUILD_NUMBER}?"
ok "确认部署"
parameters {
string(name: 'VERSION_TAG', defaultValue: 'latest', description: '部署版本标签')
}
}
steps {
// 实际部署逻辑
}
}
蓝绿部署实现
stage('蓝绿部署') {
steps {
// 思路:维护两个环境(blue/green),每次部署到非活跃环境
script {
currentActive = sh(script: 'kubectl get svc myapp -n production -o jsonpath="{.spec.selector.color}"', returnStdout: true).trim()
targetColor = (currentActive == 'blue') ? 'green' : 'blue'
// 部署到目标环境
sh "kubectl apply -f k8s/${targetColor}-deployment.yaml -n production"
// 切换流量
sh "kubectl patch svc myapp -n production -p '{\"spec\":{\"selector\":{\"color\":\"${targetColor}\"}}}'"
}
}
}
配置管理
- 敏感信息:通过Jenkins凭据管理,使用
credentials()函数。 - 环境变量:尽量不硬编码,使用全局变量或外部配置中心。
- 配置文件:存放到专门的配置仓库,部署时拉取。
日志和监控
stage('部署完成') {
steps {
// 将部署信息推送到监控系统
sh """
curl -X POST https://monitoring.yourcompany.com/api/deploy \
-H 'Content-Type: application/json' \
-d '{"app":"${APP_NAME}","version":"${BUILD_NUMBER}","env":"production"}'
"""
}
}
权限控制
pipeline {
// 使用Folder/Job级别的权限控制
options {
// 只有特定用户可以触发部署
buildDiscarder(logRotator(numToKeepStr: '10'))
}
}
你可能需要注意的问题
- 回滚策略:始终保留最近N个版本的备份。
- 数据库变更:向后兼容,新代码应兼容旧数据库结构。
- 依赖服务:部署前检查依赖服务是否正常。
- 并发部署:使用
lock资源限制同时部署数量。 - 通知机制:部署成功/失败通知相关团队(邮件、Slack等)。
| 部署方式 | 适用场景 | 复杂度 | 优势 |
|---|---|---|---|
| SSH + 传统应用 | 中小型项目、传统应用 | 低 | 简单直接 |
| Docker容器化 | 微服务、现代应用 | 中 | 一致性高 |
| Kubernetes | 大规模容器编排 | 高 | 弹性、自动化 |
选择哪种方式取决于你的技术栈、团队能力和生产环境要求,对于新项目,Docker容器化 + Kubernetes 是当前的主流趋势。