Jenkins持续交付实战(二)Tomcat、Docker

目录

  1. Tomcat 部署持续交付实战
  2. Docker 部署持续交付实战

一、Tomcat 部署持续交付实战

Tomcat基础知识

  • 目的:将Spring -boot项目部署到Tomcat应用服务器中

  • 了解Tomcat

    • 开源应用服务器
    • 支持Servlet,JSP,..... Java系Web应用
    • 入门简单
  • 运行和配置入门

    • 启动:bin/startup.sh

    • 停止:bin/shutdown.sh

    • 配置文件:conf/server.xml,进入后:set number可添加行号,/8080可定位到8080位置

      image.png

    • 日志:logs/catalina.out

  • 下载位置:https://tomcat.apache.org/

    image.png

  • 安装方法:直接解压unzip apache-tomcat-xxx.zip

    image.png

    image.png

  • 修改文件权限:chmod -R a+x ../apache-tomcat-xxx

    image.png

  • 查看Tomcat进程是否起来:ps -ef | grep java | grep tomcat

    image.png

  • 访问8080端口:


    image.png
  • 环境要求:Java开发和运行时环境


Pipeline任务部署Spring应用到Tomcat

  • 任务描述:

    • 使用Script Pipeline将Spring boot应用部署到Tomcat中运行
  • 将整体任务进行分解拆分,独立出任务子模块

  • 在Script Pipeline中使用Git

  • 在Script Pipeline中使用Maven

  • 在Script Pipeline中引用变量

  • 在Script Pipeline中控制Tomcat

  • 部署流程:将spring-boot的打包成web应用的package放到tomcat中运行

    • 清洗环境是因为在持续交付过程中,可能会有之前版本的spring-boot应用,所以在持续迭代的过程中需要清理环境,删除之前的版本。所以部署之前需要停止Tomcat,部署完成后再启动Tomcat。


      image.png
  1. 配置pipeline 部署任务


    image.png
  2. 设置pipeline代码路径


    image.png
  1. 参数配置


    image.png
  2. 进行构建


    image.png
  3. 访问8080端口


    image.png
  4. Pipeline代码讲解:deploy_tomcat_script_pipeline.groovy

node('master') {
    stage('同步源码') {
            git([url: 'git@gitee.com:11547299/jeesite4.git', branch: '${branch}'])
    }

    stage('maven编译打包') {
        sh '''
            . ~/.bash_profile
            
            export pwd=`pwd`
            export os_type=`uname`
            cd web/src/main/resources/config
            if [[ "${os_type}" == "Darwin" ]]; then
                sed -i "" "s/mysql_ip/${mysql_ip}/g" application.yml
                sed -i "" "s/mysql_port/${mysql_port}/g" application.yml
                sed -i "" "s/mysql_user/${mysql_user}/g" application.yml
                sed -i "" "s/mysql_pwd/${mysql_pwd}/g" application.yml
            else
                sed -i "s/mysql_ip/${mysql_ip}/g" application.yml
                sed -i "s/mysql_port/${mysql_port}/g" application.yml
                sed -i "s/mysql_user/${mysql_user}/g" application.yml
                sed -i "s/mysql_pwd/${mysql_pwd}/g" application.yml
            fi
            
            cd $pwd/root
            mvn clean install -Dmaven.test.skip=true
            
            cd $pwd/web
            mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
        '''
    }

    stage('停止 tomcat') {
        sh '''
            ## 停止tomcat的函数, 参数$1带入tomcat的路径$TOMCAT_PATH
            killTomcat()
            {
                pid=`ps -ef|grep $1|grep java|awk '{print $2}'`
                echo "tomcat Id list :$pid"
                if [ "$pid" = "" ]
                then
                  echo "no tomcat pid alive"
                else
                  kill -9 $pid
                fi
            }
            ## 停止Tomcat
            killTomcat $tomcat_home
        '''
    }

    stage('清理环境') {
        sh '''
            ## 删除原有war包
            rm -f $tomcat_home/webapps/ROOT.war
            rm -rf $tomcat_home/webapps/ROOT
        '''
    }

    stage('部署新的war包') {
        sh '''
            cp web/target/web.war $tomcat_home/webapps/
            cd $tomcat_home/webapps
            mv web.war ROOT.war
        '''
    }

    stage('启动tomcat') {
        sh '''
            JENKINS_NODE_COOKIE=dontkillme
            cd $tomcat_home/bin
            sh startup.sh
        '''
    }
}

二、Docker部署持续交付实战

Pipeline任务部署Spring Docker应用

  • 任务描述
    • 使用Declared Pipeline技术,将Spring boot项目部署Docker镜像中
  • 涉及知识点
    • Declared Pipeline 任务中对Spring boot应用编译、打包
    • Declared Pipeline任务中制作Spring Docker镜像
    • Declared Pipeline 任务启动Docker实例
    • Declared Pipeline 参数与环境变量
    • Declared Pipeline容错控制

任务流程图

image.png

部署过程代码

  • deploy_docker_pipline.groovy 文件
pipeline {
    agent {
        label 'master'
    }

    environment {
        docker_image_name = 'jeesite4'
        docker_container_name = 'iJeesite4'
    }

    parameters {
        string(name: 'branch', defaultValue: 'master', description: 'Git branch')
    }

    stages{
        stage('同步源码') {
            steps {
                git url:'git@gitee.com:11547299/jeesite4.git', branch:"$params.branch"
            }
        }

        stage('设定配置文件'){
            steps{
                sh '''
                    . ~/.bash_profile
            
                    export os_type=`uname`
                    cd ${WORKSPACE}/web/bin/docker
                    if [[ "${os_type}" == "Darwin" ]]; then
                        sed -i "" "s/mysql_ip/${mysql_docker_ip}/g" application-prod.yml
                        sed -i "" "s/mysql_port/${mysql_port}/g" application-prod.yml
                        sed -i "" "s/mysql_user/${mysql_user}/g" application-prod.yml
                        sed -i "" "s/mysql_pwd/${mysql_pwd}/g" application-prod.yml
                    else
                        sed -i "s/mysql_ip/${mysql_docker_ip}/g" application-prod.yml
                        sed -i "s/mysql_port/${mysql_port}/g" application-prod.yml
                        sed -i "s/mysql_user/${mysql_user}/g" application-prod.yml
                        sed -i "s/mysql_pwd/${mysql_pwd}/g" application-prod.yml
                    fi
                '''
            }
        }

        stage('Maven 编译'){
            steps {
                sh '''
                    . ~/.bash_profile 
                    
                    cd ${WORKSPACE}/root
                    mvn clean install -Dmaven.test.skip=true
                    
                    cd ${WORKSPACE}/web
                    mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
                '''
            }
        }

        stage('停止 / 删除 现有Docker Container/Image '){
            steps {
                script{
                    try{
                        sh 'docker stop $docker_container_name'
                    }catch(exc){
                        echo 'The container $docker_container_name does not exist'
                    }

                    try{
                        sh 'docker rm $docker_container_name'
                    }catch(exc){
                        echo 'The container $docker_container_name does not exist'
                    }

                    try{
                        sh 'docker rmi $docker_image_name'
                    }catch(exc){
                        echo 'The docker image $docker_image_name does not exist'
                    }
                }
            }
        }

        stage('生成新的Docker Image'){
            steps {
                sh '''
                    cd ${WORKSPACE}/web/bin/docker
                    rm -f web.war
                    cp ${WORKSPACE}/web/target/web.war .
                    docker build -t $docker_image_name .
                '''
            }
        }

        stage('启动新Docker实例'){
            steps {
                sh '''
                    docker run -d --name $docker_container_name -p 8981:8980 $docker_image_name
                '''
            }
        }
    }
}
  • application-prod.yaml 文件
#======================================#
#========== Project settings ==========#
#======================================#

# 产品或项目名称、软件开发公司名称
productName: JeeSite 生产环境
companyName: ThinkGem

# 产品版本、版权年份
productVersion: V4.1
copyrightYear: 2020

#是否演示模式
demoMode: false

#======================================#
#========== Server settings ===========#
#======================================#

server:

  port: 8980
  servlet:
    context-path: /
  tomcat:
    uri-encoding: UTF-8

  # 将请求协议转换为 https
  schemeHttps: false

#======================================#
#========== Database sttings ==========#
#======================================#
# 数据库连接
jdbc: 
  
  # Mysql 数据库配置
  type: mysql
  driver: com.mysql.jdbc.Driver
  url: jdbc:mysql://mysql_ip:mysql_port/jeesite?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true
  username: mysql_user
  password: mysql_pwd
  testSql: SELECT 1

# MyBatis 相关
mybatis:

  # Mapper文件刷新线程
  mapper:
    refresh:
      enabled: false
      
# 文件相关
file:

  # 文件上传根路径,设置路径中不允许包含“userfiles”,在指定目录中系统会自动创建userfiles目录,如果不设置默认为contextPath路径
  baseDir: /root/jeesite

Dockerfile 代码

  • 起点alpine-java:jdk8-slim镜像
  • 加载应用web.war
  • 解压缩web.war
  • 配置java启动参数
  • 添加yml配置文件
  • 配置应用启动命令
  • 添加暴露端口
FROM frolvlad/alpine-java:jdk8-slim
MAINTAINER ThinkGem@163.com
ENV TZ "Asia/Shanghai"
ENV LANG C.UTF-8
VOLUME /tmp

WORKDIR /app
ADD web.war .
RUN jar -xvf web.war

WORKDIR /app/WEB-INF
ENV JAVA_OPTS "-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m"
ENV JAVA_OPTS "$JAVA_OPTS -Dspring.profiles.active=prod"

ADD application-prod.yml ./classes/config

ENTRYPOINT java -cp /app $JAVA_OPTS org.springframework.boot.loader.WarLauncher

EXPOSE 8980

部署

  1. 创建Pipeline任务,部署Spring Docker应用
image.png
  1. 构建任务
image.png
image.png
  1. 访问8981端口


    image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容