pipeline { parameters { string(name: 'PROJECT_NAME', defaultValue: 'my-project', description: '项目名称') string(name: 'DOCKER_REPOSITORY_CREDENTIAL_ID', defaultValue: 'docker-repo-cred', description: 'Docker 仓库凭证 ID') string(name: 'HARBOR_HOST', defaultValue: 'harbor.mycompany.com', description: 'Harbor 主机地址') string(name: 'NAMESPACE_NAME', defaultValue: 'my-namespace', description: 'Kubernetes 命名空间') string(name: 'JAVA_TAG', defaultValue: 'latest', description: 'Java 镜像标签') string(name: 'NODE_TAG', defaultValue: 'latest', description: 'Node.js 镜像标签') string(name: 'JAVA_REPLICAS', defaultValue: '2', description: 'Java 部署副本数量') string(name: 'NODE_REPLICAS', defaultValue: '2', description: 'Node.js 部署副本数量') string(name: 'JENKINS_URL', defaultValue: 'http://jenkins.mycompany.com', description: 'Jenkins URL') } environment { JAVA_REPOSITORY_NAME = "ruoyi-java" NODE_REPOSITORY_NAME = "rupyi-node" YAML_PATH = "cloud/deploy/" JAVA_DEPLOYMENT_NAME = "ruoyi-java.yaml" NODE_DEPLOYMENT_NAME = "ruoyi-nginx.yaml" STATUS_URL = "${params.JENKINS_URL}/job/ruoyi/${BUILD_NUMBER}" CONSOLE_URL = "${params.JENKINS_URL}/job/ruoyi/${BUILD_NUMBER}/console" } agent { kubernetes { cloud "kubernetes" yaml """ apiVersion: v1 kind: Pod spec: containers: - name: jnlp image: jenkins/inbound-agent:3107.v665000b_51092-15 args: ['\$(JENKINS_SECRET)', '\$(JENKINS_NAME)'] imagePullPolicy: IfNotPresent volumeMounts: - mountPath: "/etc/localtime" name: "volume-2" readOnly: false - name: maven image: maven:3.6.3-jdk-11 command: ['cat'] tty: true volumeMount: - mountPath: "/usr/share/maven/ref/" name: "maven-repo" subPath: "settings.xml" readOnly: true - mountPath: "/root/.m2" name: "maven-data" - name: nodejs image: node:14 command: ['cat'] tty: true - name: kubectl image: kubesphere/kubectl:v1.22.0 imagePullPolicy: IfNotPresent tty: true command: ["cat"] volumeMounts: - mountPath: "/etc/localtime" name: "volume-2" readOnly: false - mountPath: "/var/run/docker.sock" name: "volume-docker" readOnly: false - mountPath: "/root/.kube/config" subPath: config name: "kubeconfig" readOnly: false - name: docker image: docker:24.0.0-git command: ['cat'] tty: true volumeMounts: - mountPath: "/var/run/docker.sock" name: "volume-docker" readOnly: false volumes: - name: volume-2 hostPath: path: "/usr/share/zoneinfo/Asia/Shanghai" - name: volume-docker hostPath: path: "/var/run/docker.sock" - name: kubeconfig secret: secretName: kubeconfig items: - key: config path: config - name: maven-repo configMap: name: maven-repo - name: maven-data hostPath: path: "/opt/data/m2" """ } } stages { stage('Maven 打包') { steps { container('maven') { sh """ mvn clean package -Dmaven.test.skip=true && cp ruoyi-admin/target/ruoyi-admin.jar cloud/ruoyi-java """ } } post { success { // Maven 打包成功的钉钉消息配置 dingtalk ( robot: '66dc8be5-85f4-46dd-89f5-d4efb3abab12', type: 'MARKDOWN', title: "后端打包成功 ${params.PROJECT_NAME}", text: [ "### 项目 ${params.PROJECT_NAME}", "---", "- 状态:成功", "- 阶段:后端打包", "- 版本:${BUILD_NUMBER}", "- [查看部署详情](${STATUS_URL})", "- [查看日志Console](${CONSOLE_URL})" ], at: ['17694993496'] ) } failure { // Maven 打包失败的钉钉消息配置 dingtalk ( robot: '66dc8be5-85f4-46dd-89f5-d4efb3abab12', type: 'MARKDOWN', title: "后端打包失败 ${params.PROJECT_NAME}", text: [ "### 项目 ${params.PROJECT_NAME}", "---", "- 状态:失败", "- 阶段:后端打包", "- 版本:${BUILD_NUMBER}", "- [查看部署详情](${STATUS_URL})", "- [查看日志Console](${CONSOLE_URL})" ], at: ['17694993496'] ) } } } stage('Node.js 打包') { steps { container('nodejs') { sh """ cd ruoyi-ui && npm install --registry http://registry.npmmirror.com && npm run build:prod && cp -r dist ../cloud/ruoyi-nginx """ } } post { success { // Node.js 打包成功的钉钉消息配置 dingtalk ( robot: '66dc8be5-85f4-46dd-89f5-d4efb3abab12', type: 'MARKDOWN', title: "前端打包成功 ${params.PROJECT_NAME}", text: [ "### 项目 ${params.PROJECT_NAME}", "---", "- 状态:成功", "- 阶段:前端打包", "- 版本:${BUILD_NUMBER}", "- [查看部署详情](${STATUS_URL})", "- [查看日志Console](${CONSOLE_URL})" ], at: ['17694993496'] ) } failure { // Node.js 打包失败的钉钉消息配置 dingtalk ( robot: '66dc8be5-85f4-46dd-89f5-d4efb3abab12', type: 'MARKDOWN', title: "前端打包失败 ${params.PROJECT_NAME}", text: [ "### 项目 ${params.PROJECT_NAME}", "---", "- 状态:失败", "- 阶段:前端打包", "- 版本:${BUILD_NUMBER}", "- [查看部署详情](${STATUS_URL})", "- [查看日志Console](${CONSOLE_URL})" ], at: ['17694993496'] ) } } } stage('构建镜像') { steps { withCredentials([usernamePassword(credentialsId: params.DOCKER_REPOSITORY_CREDENTIAL_ID, passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) { container('docker') { sh """ docker build -t ${params.HARBOR_HOST}/${params.NAMESPACE_NAME}/${env.JAVA_REPOSITORY_NAME}:${params.JAVA_TAG} cloud/ruoyi-java docker build -t ${params.HARBOR_HOST}/${params.NAMESPACE_NAME}/${env.NODE_REPOSITORY_NAME}:${params.NODE_TAG} cloud/ruoyi-nginx docker login ${params.HARBOR_HOST} --username ${env.USERNAME} --password ${env.PASSWORD} docker push ${params.HARBOR_HOST}/${params.NAMESPACE_NAME}/${env.JAVA_REPOSITORY_NAME}:${params.JAVA_TAG} docker push ${params.HARBOR_HOST}/${params.NAMESPACE_NAME}/${env.NODE_REPOSITORY_NAME}:${params.NODE_TAG} """ } } } post { success { // 构建镜像成功的钉钉消息配置 dingtalk ( robot: '66dc8be5-85f4-46dd-89f5-d4efb3abab12', type: 'MARKDOWN', title: "镜像构建成功 ${params.PROJECT_NAME}", text: [ "### 项目 ${params.PROJECT_NAME}", "---", "- 状态:成功", "- 阶段:构建镜像", "- 版本:${BUILD_NUMBER}", "- [查看部署详情](${STATUS_URL})", "- [查看日志Console](${CONSOLE_URL})" ], at: ['17694993496'] ) } failure { // 构建镜像失败的钉钉消息配置 dingtalk ( robot: '66dc8be5-85f4-46dd-89f5-d4efb3abab12', type: 'MARKDOWN', title: "镜像构建失败 ${params.PROJECT_NAME}", text: [ "### 项目 ${params.PROJECT_NAME}", "---", "- 状态:失败", "- 阶段:构建镜像", "- 版本:${BUILD_NUMBER}", "- [查看部署详情](${STATUS_URL})", "- [查看日志Console](${CONSOLE_URL})" ], at: ['17694993496'] ) } } } stage('部署到kubernetes') { steps { container('kubectl') { sh """ sed -i "s/REPLICAS/${params.JAVA_REPLICAS}/;s/HARBOR_HOST/${params.HARBOR_HOST}/;s/NAMESPACE_NAME/${params.NAMESPACE_NAME}/;s/REPOSITORY_NAME/${env.JAVA_REPOSITORY_NAME}/;s/TAG/${params.JAVA_TAG}/" ${env.YAML_PATH}${env.JAVA_DEPLOYMENT_NAME} sed -i "s/REPLICAS/${params.NODE_REPLICAS}/;s/HARBOR_HOST/${params.HARBOR_HOST}/;s/NAMESPACE_NAME/${params.NAMESPACE_NAME}/;s/REPOSITORY_NAME/${env.NODE_REPOSITORY_NAME}/;s/TAG/${params.NODE_TAG}/" ${env.YAML_PATH}${env.NODE_DEPLOYMENT_NAME} kubectl apply -f ${env.YAML_PATH} --record """ } } post { success { // 部署成功的钉钉消息配置 dingtalk ( robot: '66dc8be5-85f4-46dd-89f5-d4efb3abab12', type: 'MARKDOWN', title: "k8s部署成功 ${params.PROJECT_NAME}", text: [ "### 项目 ${params.PROJECT_NAME}", "---", "- 状态:成功", "- 阶段:部署yaml", "- 版本:${BUILD_NUMBER}", "- [查看部署详情](${STATUS_URL})", "- [查看日志Console](${CONSOLE_URL})" ], at: ['17694993496'] ) } failure { // 部署失败的钉钉消息配置 dingtalk ( robot: '66dc8be5-85f4-46dd-89f5-d4efb3abab12', type: 'MARKDOWN', title: "k8s部署失败 ${params.PROJECT_NAME}", text: [ "### 项目 ${params.PROJECT_NAME}", "---", "- 状态:失败", "- 阶段:部署yaml", "- 版本:${BUILD_NUMBER}", "- [查看部署详情](${STATUS_URL})", "- [查看日志Console](${CONSOLE_URL})" ], at: ['17694993496'] ) } } } } }