Jenkins流水线

  以下是完整的Jenkins流水线配置和SSH远程部署脚本,实现从Maven构建、Docker打包推送Harbor到远程部署的全流程。

一、前置准备

  1. 环境要求

    • Jenkins服务器:安装Pipeline​、Docker​、SSH Pipeline Steps插件
    • Agent节点:安装Maven​、Docker​,配置Docker登录Harbor权限(docker login harbor地址
    • 远程部署服务器:安装Docker​、docker-compose(可选,用于启动容器)
    • Harbor私服:创建项目(如myproject​),记录仓库地址(如harbor.example.com
  2. 凭证管理

    • 在Jenkins中添加以下凭证(类型:Username with password):

      • 凭证ID:harbor-cred → Harbor的用户名/密码
      • 凭证ID:ssh-deploy-cred → 远程服务器的SSH登录用户名/密码(或使用SSH密钥)

二、Jenkins流水线脚本(Jenkinsfile

pipeline {
    agent {
        label 'maven-agent' // 运行Maven和Docker的Agent节点标签
    }
    
    environment {
        // 项目配置(根据实际情况修改)
        PROJECT_NAME = 'my-app'       // 项目名称
        APP_VERSION = '1.0.0'         // 版本号(可从pom.xml提取,见备注)
        HARBOR_URL = 'harbor.example.com' // Harbor私服地址
        HARBOR_PROJECT = 'myproject'  // Harbor项目名
        REMOTE_HOST = '192.168.1.100' // 远程部署服务器IP
        REMOTE_PORT = 22              // 远程服务器SSH端口
        REMOTE_DEPLOY_DIR = '/opt/deploy' // 远程服务器部署目录
    }
    
    stages {
        stage('拉取代码') {
            steps {
                checkout scm // 从版本控制拉取代码(需在Jenkins项目中配置仓库)
            }
        }
        
        stage('Maven构建') {
            steps {
                script {
                    // 使用Agent节点的Maven构建(确保已配置MAVEN_HOME)
                    sh '''
                        mvn clean package -DskipTests
                        # 查看构建产物
                        ls -l target/*.jar
                    '''
                }
            }
        }
        
        stage('构建Docker镜像') {
            steps {
                script {
                    // 构建镜像并标记Harbor标签
                    sh """
                        docker build -t ${PROJECT_NAME}:${APP_VERSION} .
                        docker tag ${PROJECT_NAME}:${APP_VERSION} ${HARBOR_URL}/${HARBOR_PROJECT}/${PROJECT_NAME}:${APP_VERSION}
                    """
                }
            }
        }
        
        stage('推送镜像到Harbor') {
            steps {
                withCredentials([usernamePassword(credentialsId: 'harbor-cred', passwordVariable: 'HARBOR_PWD', usernameVariable: 'HARBOR_USER')]) {
                    sh """
                        # 登录Harbor
                        docker login ${HARBOR_URL} -u ${HARBOR_USER} -p ${HARBOR_PWD}
                        # 推送镜像
                        docker push ${HARBOR_URL}/${HARBOR_PROJECT}/${PROJECT_NAME}:${APP_VERSION}
                        # 登出(可选)
                        docker logout ${HARBOR_URL}
                    """
                }
            }
        }
        
        stage('SSH远程部署') {
            steps {
                script {
                    // 通过SSH发送部署脚本到远程服务器并执行
                    sshCommand(
                        credentialsId: 'ssh-deploy-cred',
                        host: env.REMOTE_HOST,
                        port: env.REMOTE_PORT,
                        command: """
                            # 创建部署目录
                            mkdir -p ${REMOTE_DEPLOY_DIR}
                        """,
                        failOnError: true
                    )
                    
                    // 发送本地部署脚本到远程服务器(脚本内容见下方)
                    sshPut(
                        credentialsId: 'ssh-deploy-cred',
                        host: env.REMOTE_HOST,
                        port: env.REMOTE_PORT,
                        from: 'deploy.sh', // 本地项目根目录下的部署脚本
                        into: "${REMOTE_DEPLOY_DIR}/"
                    )
                    
                    // 执行远程部署脚本
                    sshCommand(
                        credentialsId: 'ssh-deploy-cred',
                        host: env.REMOTE_HOST,
                        port: env.REMOTE_PORT,
                        command: """
                            cd ${REMOTE_DEPLOY_DIR}
                            chmod +x deploy.sh
                            ./deploy.sh ${HARBOR_URL} ${HARBOR_PROJECT} ${PROJECT_NAME} ${APP_VERSION}
                        """,
                        failOnError: true
                    )
                }
            }
        }
    }
    
    post {
        always {
            // 清理工作(可选)
            sh "docker rmi ${PROJECT_NAME}:${APP_VERSION} ${HARBOR_URL}/${HARBOR_PROJECT}/${PROJECT_NAME}:${APP_VERSION} || true"
        }
        success {
            echo "构建部署成功!"
        }
        failure {
            echo "构建部署失败!"
        }
    }
}

三、Dockerfile(项目根目录下)

# 基础镜像(根据项目JDK版本选择)
FROM openjdk:17-jdk-slim

# 作者信息
LABEL maintainer="yourname@example.com"

# 工作目录
WORKDIR /app

# 复制Maven构建的jar包到容器(注意jar包名称与实际一致)
COPY target/*.jar app.jar

# 暴露端口(根据项目实际端口修改)
EXPOSE 8080

# 启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]

四、远程部署脚本(deploy.sh,项目根目录下)

#!/bin/bash
# 接收Jenkins传递的参数
HARBOR_URL=$1
HARBOR_PROJECT=$2
PROJECT_NAME=$3
APP_VERSION=$4

# 镜像完整路径
IMAGE="${HARBOR_URL}/${HARBOR_PROJECT}/${PROJECT_NAME}:${APP_VERSION}"

# 远程服务器登录Harbor(如果未持久化登录状态)
echo "登录Harbor私服..."
docker login ${HARBOR_URL} -u admin -p Harbor12345  # 替换为实际Harbor账号密码

# 停止并删除旧容器
echo "停止旧容器..."
docker stop ${PROJECT_NAME} || true
echo "删除旧容器..."
docker rm ${PROJECT_NAME} || true

# 拉取最新镜像
echo "拉取镜像: ${IMAGE}"
docker pull ${IMAGE}

# 启动新容器(映射端口8080:8080,根据项目修改)
echo "启动新容器..."
docker run -d \
  --name ${PROJECT_NAME} \
  --restart always \
  -p 8080:8080 \
  ${IMAGE}

# 清理悬空镜像(可选)
echo "清理无用镜像..."
docker image prune -f

echo "部署完成!"

五、关键说明

  1. 版本号动态获取
    若需从pom.xml​提取版本号,可在Maven构建阶段添加:

    APP_VERSION = sh(script: 'mvn help:evaluate -Dexpression=project.version -q -DforceStdout', returnStdout: true).trim()
    
  2. SSH插件说明
    流水线中使用sshCommand​和sshPut​需安装SSH Pipeline Steps​插件,语法参考官方文档

  3. Docker权限
    确保Agent节点和远程服务器的jenkins​用户已加入docker​组(usermod -aG docker jenkins),避免权限问题。

  4. 安全优化

    • Harbor和SSH凭证建议使用Jenkins凭证管理,避免明文暴露。
    • 远程部署脚本中的Harbor登录信息可改为从远程服务器的环境变量或配置文件读取。
  5. 扩展建议
    若需更复杂的部署(如多实例、滚动更新),可改用docker-compose​,在deploy.sh​中调用docker-compose up -d

  通过以上配置,Jenkins将自动完成从代码拉取、构建、打包镜像到远程部署的全流程,实现持续集成和持续部署(CI/CD)。