本文目录导读:

在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 是当前的主流趋势。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播