Jenkins+maven+gitlab+Tomcat auto deployment version update and rollback

Keywords: jenkins Tomcat git ssh

Implementation effect of this blog: combined with maven+gitlab, you can use Jenkins to implement version iterative update and version rollback operations for tomcat servers in different environments (test and online environments). After deployment, you only need to click a few times.

1, Environmental preparation

system IP host name Running services
Centos7.3 192.168.171.131 Jenkins Jenkins+gitlab+Maven
Centos7.3 192.168.171.134 Tomcat1 Tomcat
Centos7.3 192.168.171.135 Tomcat2 Tomcat

For service deployment of Jenkins and gitlab, please refer to: Deploying Jenkins+Gitlab for continuous integration
Tomcat1 is used for test environment and Tomcat2 is used for production environment. For deployment, please refer to: Tomcat installation and optimization
Before making a real configuration, it is a priority to ensure that you have access to the following pages:
1,gitlab

2,Jenkins

3. Visit tomcat1

4. Visit tomcat2

2, Deployment and configuration
1. Install JDK environment on Jenkins server

[root@jenkins ~]# rpm -qa | grep jdk
copy-jdk-configs-1.2-1.el7.noarch
java-1.8.0-openjdk-headless-1.8.0.102-4.b14.el7.x86_64
java-1.8.0-openjdk-1.8.0.102-4.b14.el7.x86_64
java-1.7.0-openjdk-1.7.0.111-2.6.7.8.el7.x86_64
java-1.7.0-openjdk-headless-1.7.0.111-2.6.7.8.el7.x86_64
#Uninstall the following two packages
[root@jenkins ~]# rpm -e --nodeps java-1.8.0-openjdk-headless-1.8.0.102-4.b14.el7.x86_64
[root@jenkins ~]# rpm -e --nodeps java-1.7.0-openjdk-headless-1.7.0.111-2.6.7.8.el7.x86_64
#Deploy the jdk package I provided
[root@jenkins ~]# tar zxf jdk-8u211-linux-x64.tar.gz -C /usr/local/
[root@jenkins ~]# vim /etc/profile
export  JAVA_HOME=/usr/local/jdk1.8.0_211
export  JRE_HOME=/usr/local/jdk1.8.0_211/jre
export  CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
export  PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
[root@jenkins ~]# . /etc/profile
[root@jenkins ~]# java -version
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)

2. Deploy Maven services

[root@jenkins ~]# tar zxf apache-maven-3.6.1-bin.tar.gz 
[root@jenkins ~]# mv apache-maven-3.6.1/ /usr/local/maven
[root@jenkins ~]# vim /etc/profile
export MAVEN_HOME=/usr/local/maven
export PATH=$PATH:$MAVEN_HOME/bin
[root@jenkins ~]# . /etc/profile
[root@jenkins ~]# mvn -v               #Execute the command, as long as the following content appears, the deployment is successful (because this is a binary deployment)
Apache Maven 3.6.1 (d66c9c0b3152b2e69ee9bac180bb8fcc8e6af555; 2019-04-05T03:00:29+08:00)
Maven home: /usr/local/maven
Java version: 1.8.0_211, vendor: Oracle Corporation, runtime: /usr/local/jdk1.8.0_211/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-514.el7.x86_64", arch: "amd64", family: "unix"

3. Specify Alibaba cloud warehouse

[root@jenkins ~]# vim /usr/local/maven/conf/settings.xml
#Write the following under line 158
<mirror>
      <id>aliyun</id>
      <mirrorOf>central</mirrorOf>
      <name>aliyun maven</name>
      <url>https://maven.aliyun.com/nexus/content/groups/public/</url>
    </mirror>
  </mirrors>       #Add above this line

4. Solve the problem that Jenkins can't start
So far, the maven service has been successfully deployed. However, Jenkins is also deployed here. The startup of Jenkins depends on the previous Java environment. The deployment of maven service reconfigures the Java environment. Therefore, Jenkins cannot be started normally at present. Now, it is necessary to make a soft connection to the Java command

[root@jenkins ~]# ln -sf /usr/local/jdk1.8.0_211/bin/java /usr/bin/
[root@jenkins ~]# /etc/init.d/jenkins restart         #Restart Jenkins and make sure it can be started successfully
Restarting jenkins (via systemctl):                        [  OK  ]

5. maven builds test code and uploads it to gitlab

[root@jenkins ~]# mvn archetype:generate -DgroupId=cn.test.testweb -DartifactId=testweb -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
[root@jenkins ~]# cd testweb/
[root@jenkins testweb]# vim src/main/webapp/index.jsp 
<html>
<body>
<h2>Hello World! test1 web</h2>  #Change this line to differentiate between versions
</body>
</html>
#Delete the files before the local gitlab library and submit them to the gitlab Library
[root@jenkins test1]# rm -rf *
[root@jenkins test1]# git commit -m "del"
[root@jenkins test1]# git push origin master
#Copy the project built by maven to this directory and submit it to gitlab remote library
[root@jenkins test1]# cd ~/testweb/
[root@jenkins testweb]# cp -r pom.xml src/ ~/test1/
[root@jenkins testweb]# cd ~/test1/
[root@jenkins test1]# git add *
[root@jenkins test1]# git commit -m "test1 web"
[root@jenkins test1]# git push origin master 

6. Configure Jenkins password free login tomcat server

#Because Jenkins is required to copy code and add directory to Tomcat server, password free login needs to be configured
#By default, when gitlab is configured, the secret key pair of the current user has been generated, so there is no need to regenerate
#Send the public key to two tomcat servers respectively, enter "yes" for confirmation, and the root password of tomcat
[root@jenkins test1]# ssh-copy-id root@192.168.171.135
[root@jenkins test1]# ssh-copy-id root@192.168.171.134

7. Modify the running user of Jenkins
In the same way, it is also for the convenience of Jenkins service to have some permissions to create directories or write files in the running process. In order to facilitate this, I will directly change to root user to run Jenkins. In the production environment, we need to consider the permissions well

[root@jenkins test1]# sed -i 's/JENKINS_USER="jenkins"/JENKINS_USER="root"/g' /etc/sysconfig/jenkins
[root@jenkins test1]# /etc/init.d/jenkins restart 

8. Configure the web interface installation plug-in of Jenkins


Follow the instructions below to install one by one Plug-in unit Extraction code: 08n5 (you can install plug-ins online by yourself, and do your own research). There are 7 plug-ins in total. In addition to installing jquery plug-ins first and then installing jquery UI plug-ins, other plug-ins can be uploaded in any order. Note: only one plug-in can be uploaded at a time


9. Configure Jenkins' web interface to specify the installation path of maven and jdk
1) Configure maven
Click (from Jenkins homepage): System Management > > global tool configuration > >

2) Configure jdk
Click (from Jenkins homepage): System Management > > global tool configuration > >

10. Build maven project




Add the second option parameter:

Write content and add text parameters:



Enter clean package -Dmaven.test.skip=true in the Build box below

The following script can directly copy the following content (note that you need to modify the IP field of the host defined below according to the actual situation. It is recommended to read the script carefully to see the function of the script)
This script is the key to the iterative upgrade and rollback of the version!!!
This script is the key to the iterative upgrade and rollback of the version!!!
This script is the key to the iterative upgrade and rollback of the version!!!

##Deploy tomcat 

war_bak="/data/war/bak"
tomcat_deploy="/usr/local/tomcat/webapps"
#WAR_PATH="${WORKSPACE}/${MODULE_NAME}/target/*.war"
WAR_PATH="${WORKSPACE}/target/*.war"
#Here is the definition of test server and online server
test_host="192.168.171.134"    #Test server, IP can write multiple, but pay attention to the format
stag_host="192.168.171.135"    #Online server, similarly, IP can write multiple
port="8080"

echo "Build environment:${deploy} entry name:${JOB_NAME} Build time:`date +%F` This online version:${GIT_COMMIT}" >> /var/log/${JOB_NAME}.log

### status deploy or rollback

##Judge whether git is empty, and prompt if it is empty
if [ "${git}" = "" ];then

echo "Please enter git Edition #############"
exit 1

else

## Judge publisher or rollback
if [ "${Status}" = "Deploy" ];then

### Determine whether it is a test environment
    if [ "${deploy}" = "test" ];then
            ### Build host
               for i in ${test_host}
                 do
               ssh ${i} "mkdir -p ${war_bak}/${JOB_NAME}/${git}"
                 scp ${WAR_PATH} ${i}:${war_bak}/${JOB_NAME}/${git}/ROOT.war
                 ssh ${i} rm -rf ${tomcat_deploy}/*
                 ssh ${i} cp ${war_bak}/${JOB_NAME}/${git}/ROOT.war ${tomcat_deploy}
                 ssh ${i} /etc/init.d/tomcat  restart
          ### Judge whether tomcat is normal      
                     for http in `seq 1 5`
                   do
                        tomcat_status=`curl -I ${i}:${port} -s|awk -F "[ ]" '{print $2}' |sed -n '1p'`
                    if  [[ "$tomcat_status" -ne 200 ]] || [[ "$tomcat_status" = "" ]];then
                        echo -e "\033[5;34m Please wait a moment, the service is starting........ \033[0m"
                              sleep 5
                      else
                        echo -e "\033[5;34m structure ${i}Environment released normally,Return value[${tomcat_status}] \033[0m"
                              break
                      fi
                  done

                      if [[ "${tomcat_status}" -ne 200 ]] || [[ "${tomcat_status}" = "" ]];then
                          if [[ "${tomcat_status}" = "" ]];then
                      echo -e "\033[5;34m structure ${i}Service start exception \033[0m"
                      exit 1
                          fi
                        echo -e "\033[5;34m structure ${i}Environment publishing exception,Return value[${tomcat_status}] \033[0m"
                    fi
              done
                echo -e "\033[5;34m This construction ${test_host}Host,This environment ${deploy} \033[0m"
## Judged as pre release environment
    elif [ "${deploy}" = "stag" ];then
               for i in "${stag_host}"
                 do
               ssh ${i} mkdir -p ${war_bak}/${JOB_NAME}/${git}
                 scp ${WAR_PATH} ${i}:${war_bak}/${JOB_NAME}/${git}/ROOT.war
                 ssh ${i} rm -rf ${tomcat_deploy}/*
                 ssh ${i} cp ${war_bak}/${JOB_NAME}/${git}/ROOT.war ${tomcat_deploy}
                 ssh ${i} /etc/init.d/tomcat restart
          ### Judge whether tomcat is normal      
                     for http in `seq 1 5`
                   do
                        tomcat_status=`curl -I ${i}:${port} -s|awk -F "[ ]" '{print $2}' |sed -n '1p'`
                    if  [[ "$tomcat_status" -ne 200 ]] || [[ "$tomcat_status" = "" ]];then
                        echo -e "\033[5;34m Please wait a moment, the service is starting........ \033[0m"
                              sleep 5
                      else
                        echo -e "\033[5;34m structure ${i}Environment released normally,Return value[${tomcat_status}] \033[0m"
                              break
                      fi
                  done

                      if [[ "${tomcat_status}" -ne 200 ]] || [[ "${tomcat_status}" = "" ]];then
                          if [[ "${tomcat_status}" = "" ]];then
                      echo -e "\033[5;34m structure ${i}Service start exception \033[0m"
                      exit 1
                        fi
                        echo -e "\033[5;34m structure ${i}Environment publishing exception,Return value[${tomcat_status}] \033[0m"
                    fi
        done
               echo -e "\033[5;34m This construction ${test_host}Host,This environment ${deploy} \033[0m"
   fi

### Rollback operation
elif [[ "${Status}" = "RollBack" ]];then

  ### Determine the rollback environment and host
            if [ "${deploy}" = "test" ];then
              for i in ${test_host}
              do
                 ssh ${i}  "[ -d ${war_bak}/${JOB_NAME}/${git} ]"
                      if [ $? -ne '0' ];then
                            echo -e "\033[5;34m  git commit Rollback directory does not exist, environment ${deploy} Error host ${i} \033[0m"
                            exit 3
                        else
                            echo -e "\033[5;34m  Prepare to rollback this rollback environment ${deploy} Rollback host ${i} \033[0m"
                            sleep 3
                      fi
                 ssh ${i}  "mkdir -p ${war_bak}/${JOB_NAME}/${git}_${Status}_rollback/"
                 ssh ${i}  "cp -r ${tomcat_deploy}/* ${war_bak}/${JOB_NAME}/${git}_${Status}_rollback/"
                 ssh ${i}  "rm -rf ${tomcat_deploy}/*"
                 ssh ${i} "cp -r ${war_bak}/${JOB_NAME}/${git}/*.war ${tomcat_deploy}/"
                 ssh ${i} /etc/init.d/tomcat  restart
                   ### Judge whether tomcat is normal      
              for http in `seq 1 5`
              do
                 tomcat_status=`curl -I ${i}:${port} -s|awk -F "[ ]" '{print $2}' |sed -n '1p'`
                 if  [[ "$tomcat_status" -ne 200 ]] || [[ "$tomcat_status" = "" ]];then
                        echo -e "\033[5;34m Please wait a moment, the service is starting........ \033[0m"
                        sleep 5
                 else
                        echo -e "\033[5;34m structure ${i}Environment released normally,Return value[${tomcat_status}] \033[0m"
                        break
                 fi
              done

                  if [[ "${tomcat_status}" -ne 200 ]] || [[ "${tomcat_status}" = "" ]];then
                    if [[ "${tomcat_status}" = "" ]];then
                      echo -e "\033[5;34m structure ${i}Service start exception \033[0m"
                      exit 1
                    fi
                      echo -e "\033[5;34m structure ${i}Environment publishing exception,Return value[${tomcat_status}] \033[0m"
                 fi
              done

            elif [ "${deploy}" = "stag" ];then
              for i in ${stag_host}
              do
                 ssh ${i}  "[ -d ${war_bak}/${JOB_NAME}/${git} ]"
                      if [ $? -ne '0' ];then
                            echo -e "\033[5;34m  git commit Rollback directory does not exist, environment ${deploy} Error host ${i} \033[0m"
                            exit 3
                        else
                            echo -e "\033[5;34m  Prepare to rollback this rollback environment ${deploy} Rollback host ${i} \033[0m"
                            sleep 3
                      fi
                 ssh ${i}  "mkdir -p ${war_bak}/${JOB_NAME}/${git}_${Status}_rollback/"
                 ssh ${i}  "cp -r ${tomcat_deploy}/* ${war_bak}/${JOB_NAME}/${git}_${Status}_rollback/"
                 ssh ${i}  "rm -rf ${tomcat_deploy}/*"
                 ssh ${i} "cp -r ${war_bak}/${JOB_NAME}/${git}/*.war ${tomcat_deploy}/"
                 ssh ${i} /etc/init.d/tomcat  restart
                   ### Judge whether tomcat is normal      
              for http in `seq 1 5`
              do
                 tomcat_status=`curl -I ${i}:${port} -s|awk -F "[ ]" '{print $2}' |sed -n '1p'`
                 if  [[ "$tomcat_status" -ne 200 ]] || [[ "$tomcat_status" = "" ]];then
                        echo -e "\033[5;34m Please wait a moment, the service is starting........ \033[0m"
                        sleep 5
                 else
                        echo -e "\033[5;34m structure ${i}Environment released normally,Return value[${tomcat_status}] \033[0m"
                        break
                 fi
              done

                  if [[ "${tomcat_status}" -ne 200 ]] || [[ "${tomcat_status}" = "" ]];then
                    if [[ "${tomcat_status}" = "" ]];then
                      echo -e "\033[5;34m structure ${i}Service start exception \033[0m"
                      exit 1
                    fi
                      echo -e "\033[5;34m structure ${i}Environment publishing exception,Return value[${tomcat_status}] \033[0m"
                 fi
              done
            ### Judge the end of test environment fi
            fi

fi

#### fi is to determine whether there is the end of git address
fi


11. To write the startup script of tomcat service, both servers need to be configured as follows
If you don't write Tomcat startup script, there are many changes in the above shell script, because the Tomcat startup script specified in the above script is / etc/init.d/tomcat
tomcat1 is configured as follows

[root@tomcat1 ~]# vim /etc/init.d/tomcat
#!/bin/bash
# description: Tomcat is a Java Servlet Container
TOMCAT_HOME=/usr/local/tomcat
start () {
TOMCAT_PID=`ps -ef |grep "$TOMCAT_HOME" |grep -v "grep" |awk '{print $2}'`
if [ -z $TOMCAT_PID ];then
      source   /etc/profile
      /bin/bash $TOMCAT_HOME/bin/startup.sh
else
    echo "$0 is  running"
fi
}
stop () {
TOMCAT_PID=`ps -ef |grep "$TOMCAT_HOME" |grep -v "grep" |awk '{print $2}'`
if [ -z $TOMCAT_PID ];then
        echo "$0 is not running"
else
        echo "shutting down $0"
        kill -9 "$TOMCAT_PID" && echo "PID $TOMCAT_PID killed."
fi
}
status () {
TOMCAT_PID=`ps -ef |grep "$TOMCAT_HOME" |grep -v "grep" |awk '{print $2}'`
if [ -z $TOMCAT_PID ];then
        echo "$0 is not running"
else
        echo "$0 is running PID is $TOMCAT_PID"
fi
}
case $1 in
start)
start
#tail -f $TOMCAT_HOME/logs/catalina.out
;;
stop)
stop
;;
status)
status
;;
restart)
stop
start
#tail -f $TOMCAT_HOME/logs/catalina.out
;;
*)
echo "Usage:$0  {start|stop|status|restart}."
;;
esac
[root@tomcat1 ~]# chmod +x /etc/init.d/tomcat             # Give execution permission
[root@tomcat1 ~]# /etc/init.d/tomcat restart      # Test whether the script can be used 

Note: tomcat2 configuration is the same
Note: tomcat2 configuration is the same
Note: tomcat2 configuration is the same
12. Deploy gitlab code to tomcat1 test server
First, you need to find the commit ID number of the test code in the web interface of gitlab, and then copy it, as follows:

Then go back to Jenkins' web interface and start to build it. Click here:

To view build information:



Now that you have successfully built the test server, visit the test server to see if the page has really changed
Visit test server tomcat01 (need to refresh the page, pay attention to the cache problem)

You can see the content of the build project
13. Deploy gitlab code to tomcat02 online server

Visit the online server to see if its page has changed, as follows (if the deployment fails, it is recommended to refer to the built console output information for troubleshooting):

14. Page upgrade of tomcat service
1) Prepare test code:

#Execute mvn command to generate code
[root@jenkins /]# mvn archetype:generate -DgroupId=cn.test.testweb -DartifactId=testweb -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
[root@jenkins /]# vim testweb/src/main/webapp/index.jsp 
<html>
<body>
<h2>Hello World! test2 web</h2>             # Change to test2
</body>
</html>
[root@jenkins /]# cd testweb/
[root@jenkins testweb]# ls
pom.xml  src
[root@jenkins testweb]# cp -r pom.xml src/ ~/test1/
[root@jenkins testweb]# cd ~/test1/
[root@jenkins test1]# git add *
[root@jenkins test1]# git commit -m "test2 web"
[root@jenkins test1]# git push origin master         # Push code to gitlab

Check the commit ID number of the code pushed from gitlab:

Upgrade the test server first:

Refresh the page of the test server to see if the update is successful:

Next, upgrade the online tomcat server:

Refresh the online tomcat server page, as shown below, indicating success:

15. Test version rollback
Perform version rollback for tomcat test server:


You can see that the page of the test server has been rolled back to the previous version, while the page of the online server is still the page of test02

Perform version rollback on the pages of the online server:

Posted by John Rowe on Tue, 05 May 2020 19:45:51 -0700