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:6007/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:6007/library/rapid-demo-back:v2.1.2

4、删除本地镜像

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

5、Dockerfile内容

# jdk版本
FROM moxm/java:1.8-full

# 临时文件目录
VOLUME /tmp

ADD target/*.jar app.jar

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

二、前端打包

1、checkout代码下载

2、nodeJs打包

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

3、docker打包

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

4、推送到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:6007/library/rapid-demo-web:v2.1.2
}

5、删除本地镜像

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

6、Dockerfile内容

FROM nginx:alpine
# 作者信息
MAINTAINER lvlinguang <635074566@qq.com>
# 复制html页面
COPY ./dist ./usr/share/nginx/html/
# 复制nginx配置文件
COPY ./default.conf /etc/nginx/conf.d/

7、default.conf

server {
    listen       8080;
    #listen  [::]:80;
    server_name  localhost;

    gzip            on;
    gzip_min_length 1000;
    gzip_comp_level 6;
    gzip_types      text/plain application/xml application/javascript application/x-javascript text/css application/xml;

    gzip_vary on;
    
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

# 后端接口代理
#    location /screen {
#      proxy_set_header Host $http_host;
#      proxy_set_header X-Real-IP $remote_addr;
#      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#      proxy_set_header X-Forwarded-Proto $scheme;
#      proxy_pass http://192.168.3.15:6032/;
#    }

    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:6007/library/rapid-demo-back:v2.1.2

4、启动容器

docker run -d --name rapid-demo-back --restart=always -p 6001:8080 192.168.3.12:6007/library/rapid-demo-back:v2.1.2

四、完整代码

1、pipeline script

pipeline {
  agent any
  environment{
    dockerRegistry="192.168.3.12:6007"
    //后端变量
    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: true, description: 'docker后端构建')
    booleanParam(name: 'ENABLE_FRONTEND_BUILD', defaultValue: true, description: 'docker前端构建')
    booleanParam(name: 'ENABLE_BACKEND_DEPLOY', defaultValue: true, description: 'docker后端部署')
    booleanParam(name: 'ENABLE_FRONTEND_DEPLOY', defaultValue: true, description: 'docker前端部署')
  }
  post {
      always {
          // 删除工作目录
          cleanWs()
      }
  }
  stages {
    stage('初始化') {
        steps {
            echo '初始化。。。'
        }
    }
    stage('后端打包'){
        when{
            expression{params.ENABLE_BACKEND_BUILD}
        }
        steps{
            script{
                // 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: '6a2f3d27-7641-4666-90e1-833c39afde8d', passwordVariable: 'password', usernameVariable: 'username')]) {
                    sh "docker login -u ${username} -p ${password} ${dockerRegistry}"
                }
                // docker推送至Harbor
                sh "docker push ${backDockerImage}"
                // 删除镜像
                sh "docker rmi ${backDockerImage}"
                echo '打包完成。。。'
            }
        }
    }
    //前端打包
    stage('前端打包'){
        when {
            expression { params.ENABLE_FRONTEND_BUILD }
        }
        steps {
            script {
                echo '前端打包。。。'
                // git代码拉取。。。
                gitClone(frontGitUrl, frontBranch);
                // nodejs的npm进行打包。。。
                nodejs('node-v12.20.0') {
                    sh 'npm install --registry=https://registry.npm.taobao.org'
                    sh 'npm run build'
                }
                // docker打包。。。
                sh "docker build -t ${frontDockerImage} ."
                // harbor登录
                withCredentials([usernamePassword(credentialsId: '6a2f3d27-7641-4666-90e1-833c39afde8d', passwordVariable: 'password', usernameVariable: 'username')]) {
                    sh "docker login -u ${username} -p ${password} ${dockerRegistry}"
                }
                // docker推送至Harbor
                sh "docker push ${frontDockerImage}"
                // 删除镜像
                sh "docker rmi ${frontDockerImage}"
                echo '打包完成。。。'
            }
        }
    }
    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_FRONTEND_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='6c17706c-f96f-4711-91e4-719234985cba'){
    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 = 'abd46afe-05df-4de1-a683-edefb9319110') {
    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" --restart=always -p"${port}":"${serverPort}" $imageName
echo "容器启动成功"

五、发布测试

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

2、发布测试

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

4、访问测试:192.168.3.15:7002

六、优化方案

1、使用docker-build工程,请参考我的另一篇文章

七、源码地址

八、参考

posted @ 2021-11-11 19:28  吕林光  阅读(1061)  评论(0编辑  收藏  举报