jenkins项目发布

目录
  • 一、简介
  • 二、docker打包
    • 一、后端打包
    • 二、前端打包
  • 三、启动容器
  • 四、完整代码
  • 五、发布测试
  • 六、优化方案
  • 七、源码地址:
  • 八、参考

一、简介

1、该章节基于jenkins、Harbor、pipeline来做发布,如对这些不熟悉,请按以下进入学习

2、jenkins学习地址:https://www.cnblogs.com/lvlinguang/p/15163691.html

3、Harbor学习地址:https://www.cnblogs.com/lvlinguang/p/15500171.html

4、pipeline学习地址:https://www.cnblogs.com/lvlinguang/p/15512349.html

二、docker打包

一、后端打包

1、git代码拉取

# 使用checkout拉取代码
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'a8db6793-cc2b-4d82-bd3d-c5beb1c5149e', url: 'https://gitee.com/lvlinguang/rapid-demo-back.git']]])

# 使用git branch拉取代码
git branch: 'master', credentialsId: 'a8db6793-cc2b-4d82-bd3d-c5beb1c5149e', url: 'https://gitee.com/lvlinguang/rapid-demo-back.git'

2、mvn打包

mvn -U clean install -Dmaven.test.skip=true

3、docker打包

  • 使用maven插件打包并推送到Harbor
mvn dockerfile:build dockerfile:push
  • 使用docker打包并推送到Harbor
# docker打包
docker build -t 192.168.3.12:1180/library/rapid-demo-back:v2.1.2 .

// harbor登录
withCredentials([usernamePassword(credentialsId: '8d4ff3de-9b05-427d-a211-23be72f65bbb', passwordVariable: 'password', usernameVariable: 'username')]) {
    sh "docker login -u ${username} -p ${password} ${dockerRegistry}"
}

# docker推送到Harbor
docker push 192.168.3.12:1180/library/rapid-demo-back:v2.1.2

4、删除本地镜像

docker rmi 192.168.3.12:1180/library/rapid-demo-back:v2.1.2

5、Dockerfile内容

# jdk版本
FROM  java:8

# 临时文件目录
VOLUME /tmp

ADD target/*.jar app.jar

ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

二、前端打包

1、checkout代码下载

2、nodeJs打包

  • 打包后目录下会生成dist文件
nodejs('node-v12.20.0') {
    sh 'npm install --registry=https://registry.npm.taobao.org'
    sh 'npm run build'
}

3、复制文件

mv ../build_fronted_dist/dist ./dist
mv ../build_fronted_dist/Dockerfile ./Dockerfile
mv ../build_fronted_dist/nginx.conf ./nginx.conf

4、docker打包

docker build -t 192.168.3.12:1180/library/rapid-demo-web:v2.1.2 .

5、推送到Harbor

withCredentials([usernamePassword(credentialsId: '8d4ff3de-9b05-427d-a211-23be72f65bbb', passwordVariable: 'password', usernameVariable: 'username')]) {
    // harbor登录
    sh "docker login -u ${username} -p ${password} ${dockerRegistry}"
    // 推送Harbor
    docker push 192.168.3.12:1180/library/rapid-demo-web:v2.1.2
}

6、删除本地镜像

docker rmi 192.168.3.12:1180/library/rapid-demo-web:v2.1.2

7、Dockerfile内容

FROM nginx:alpine
COPY ./dist/ /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/nginx.conf

8、nginx.conf

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
  worker_connections  1024;
}
http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
  access_log  /var/log/nginx/access.log  main;
  sendfile        on;
  keepalive_timeout  65;
  server {
    listen       8080;
    server_name  localhost;
    location / {
      root   /usr/share/nginx/html;
      index  index.html index.htm;
      try_files $uri $uri/ /index.html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   /usr/share/nginx/html;
    }
  }
}

三、启动容器

1、查询容器是否存在,存在则删除

# 容器id
containerId=$(docker ps -a | grep -w "rapid-demo-back" | awk '{print $1}')
if [ "$containerId" != "" ] ;
then
  #停掉容器
  docker stop "$containerId"
  #删除容器
  docker rm "$containerId"
fi

2、查询镜像是否存在,存在则删除

# 镜像id
imageId=$(docker images | grep -w "rapid-demo-back" | awk '{print $3}')
if [ "$imageId" != "" ] ;
then
  #删除镜像
  docker rmi -f "$imageId"
fi

3、下载镜像

docker pull 192.168.3.12:1180/library/rapid-demo-back:v2.1.2

4、启动容器

docker run -d --name rapid-demo-back -p 6001:8080 192.168.3.12:1180/library/rapid-demo-back:v2.1.2

四、完整代码

1、pipeline script

pipeline {
  agent any
  environment{
    dockerRegistry="192.168.3.12:1180"
    //后端变量
    backPort= 7001
    backServerPort=8080
    backName="rapid-demo-back"
    backGitUrl="https://gitee.com/lvlinguang/rapid-demo-back.git"
    backBranch="*/master"
    backDockerImage="${dockerRegistry}/library/${backName}:v2.1.2"
    //前端变量
    frontPort= 7002
    frontServerPort=8080
    frontName="rapid-demo-web"
    frontGitUrl="https://gitee.com/lvlinguang/rapid-demo-web.git"
    frontBranch="*/master"
    frontDockerImage="${dockerRegistry}/library/${frontName}:v2.1.2"
  }
  parameters {
    booleanParam(name: 'ENABLE_BACKEND_BUILD', defaultValue: false, description: '开启后端构建')
    booleanParam(name: 'ENABLE_FRONTED_BUILD', defaultValue: false, description: '开启前端构建')
    booleanParam(name: 'ENABLE_BACKEND_DEPLOY', defaultValue: false, description: '开启后端部署')
    booleanParam(name: 'ENABLE_FRONTED_DEPLOY', defaultValue: false, description: '开启前端部署')
  }
  stages {
    stage('初始化') {
        steps {
            echo '初始化。。。'
        }
    }
    stage('后端打包'){
        when{
            expression{params.ENABLE_BACKEND_BUILD}
        }
        steps{
            script{
                ws("backend_build"){
                    dir("build_backend_docker"){
                        // git代码拉取。。。
                        gitClone(backGitUrl, backBranch);
                        // mvn打包。。。
                        sh "/usr/local/apache-maven-3.8.2/bin/mvn -U clean install -Dmaven.test.skip=true"
                        // docker打包。。。
                        sh "docker build -t ${backDockerImage} ."
                        // harbor登录
                        withCredentials([usernamePassword(credentialsId: '8d4ff3de-9b05-427d-a211-23be72f65bbb', passwordVariable: 'password', usernameVariable: 'username')]) {
                            sh "docker login -u ${username} -p ${password} ${dockerRegistry}"
                        }
                        // docker推送至Harbor
                        sh "docker push ${backDockerImage}"
                        // 删除镜像
                        sh "docker rmi ${backDockerImage}"
                    }
                    echo '打包完成。。。'
                    // 删除backend_build工作目录
                    cleanWs()
                }
            }
        }
    }
    //前端打包
    stage('前端打包'){
        when {
            expression { params.ENABLE_FRONTED_BUILD }
        }
        steps {
            script {
                echo '前端打包。。。'
                ws("fronted_build"){
                    dir("build_fronted_dist"){
                       // git代码拉取。。。
                       gitClone(frontGitUrl, frontBranch);
                       // nodejs的npm进行打包。。。
                       nodejs('node-v12.20.0') {
                           sh 'npm install --registry=https://registry.npm.taobao.org'
                           sh 'npm run build'
                       }
                    }
                    dir("build_fronted_docker"){
                        // 复制dist、dockerfile、nginx文件。。。
                        sh "mv ../build_fronted_dist/dist ./dist"
                        sh "mv ../build_fronted_dist/Dockerfile ./Dockerfile"
                        sh "mv ../build_fronted_dist/nginx.conf ./nginx.conf"
                        // docker打包。。。
                        sh "docker build -t ${frontDockerImage} ."
                        // harbor登录
                        withCredentials([usernamePassword(credentialsId: '8d4ff3de-9b05-427d-a211-23be72f65bbb', passwordVariable: 'password', usernameVariable: 'username')]) {
                            sh "docker login -u ${username} -p ${password} ${dockerRegistry}"
                        }
                        // docker推送至Harbor
                        sh "docker push ${frontDockerImage}"
                        // 删除镜像
                        sh "docker rmi ${frontDockerImage}"
                    }
                    echo '打包完成。。。'
                    // 删除backend_build工作目录
                    cleanWs()
                }
            }
        }
    }
    stage('测试') {
        steps {
            echo '测试。。。'
        }
    }
    stage('后端发布') {
        when{
            expression{params.ENABLE_BACKEND_DEPLOY}
        }
        steps {
            script {
                echo '后端发布。。。'
                // 远程服务器
                def sshServer = getRemoteServer('192.168.3.15')
                //remote发布
                sshCommand remote: sshServer, command: "/usr/local/java/deploy.sh $backName $backDockerImage $backPort $backServerPort"
            }
        }
    }
    stage('前端发布') {
        when{
            expression{params.ENABLE_FRONTED_DEPLOY}
        }
        steps {
            script{
                echo '前端发布。。。'
                 // 远程服务器
                 def sshServer = getRemoteServer('192.168.3.15')
                 //remote发布
                 sshCommand remote: sshServer, command: "/usr/local/java/deploy.sh $frontName $frontDockerImage $frontPort $frontServerPort"
            }
        }
    }
  }
}

//获取远程服务器
def getRemoteServer(String ip='192.168.3.15',String credentialsId='67cc51e8-9614-43c2-9ea1-2070ee9407c6'){
    def remote = [:]
    remote.name = ip
    remote.host = ip
    remote.port = 22
    remote.allowAnyHosts = true
    withCredentials([usernamePassword(credentialsId: credentialsId, passwordVariable: 'password', usernameVariable: 'username')]) {
        remote.user = "${username}"
        remote.password = "${password}"
    }
    return remote
}

//git代码下载
def gitClone(String gitUrl, String gitBranch, String credentialsId = 'b494c748-17fd-4356-8218-5131b5ea5b92') {
    checkout([
            $class           : 'GitSCM',
            branches         : [[name: gitBranch]],
            extensions       : [],
            userRemoteConfigs: [[
                                        credentialsId: credentialsId,
                                        url          : gitUrl
                                ]]
    ])
}

2、deploy.sh

#接收外部参数,由jenkinsfile执行部署脚本时传递
projectName=$1
imageName=$2
port=$3
serverPort=$4

echo "镜像名: $imageName"
echo "项目名: $projectName"

# 容器id
containerId=$(docker ps -a | grep -w "${projectName}" | awk '{print $1}')
if [ "$containerId" != "" ] ;
then
  #停掉容器
  docker stop "$containerId"
  #删除容器
  docker rm "$containerId"
  echo "成功删除容器"
fi

# 镜像id
imageId=$(docker images | grep -w "${projectName}" | awk '{print $3}')
if [ "$imageId" != "" ] ;
then
  #删除镜像
  docker rmi -f "$imageId"
  echo "成功删除镜像"
fi

# 镜像下载
docker pull "$imageName"

# 启动容器
docker run -d --name "$projectName" -p"${port}":"${serverPort}" $imageName
echo "容器启动成功"

五、发布测试

1、jenkins新建pipeline项目,使用上面的pipeline script

jenkins项目发布_第1张图片

2、发布测试

jenkins项目发布_第2张图片

jenkins项目发布_第3张图片

3、服务器查看项目是否启动

4、访问测试:192.168.3.15:7002

六、优化方案

1、新建docker-build工程,如下

jenkins项目发布_第4张图片

2、新建pipeline项目

jenkins项目发布_第5张图片
jenkins项目发布_第6张图片

2、目录介绍

  • config:项目配置信息,config.json配置了项目地址、docker信息、发布信息等
  • scripts:打包脚本和发布脚本
    • 公共变量:common_var.groovy
    • 工具类:common_util.groovy
    • 后端打包:build_backend.groovy
    • 前端打包:build_fronted.groovy
    • 后端发布:publish_backend.groovy
    • 前端发布:publish_fronted.groovy
  • Jenkinsfile:pipeline脚本,jenkins项目选择该文件
  • build_back:脚本备份,deploy.sh通用发布,Jenkinsfile未优化版

七、源码地址:

  • 前端源码:https://gitee.com/lvlinguang/rapid-demo-web
  • 后端源码:https://gitee.com/lvlinguang/rapid-demo-back
  • docker-build:https://gitee.com/lvlinguang/docker-build

八、参考

  • https://www.jianshu.com/p/1401e2fe4711
  • remote ssh使用:https://www.cnblogs.com/dreamer-fish/p/13524138.html
  • nodeJs安装:https://blog.csdn.net/liumiaocn/article/details/102618269
  • npm淘宝镜像设置:https://www.jianshu.com/p/1d8debb671a7
  • vue项目部署:https://www.cnblogs.com/blue-rain/p/12463133.html
  • vue项目部署:https://blog.csdn.net/mumushuiding/article/details/94452574

你可能感兴趣的:(jenkins项目发布)