Jenkins+Docker+SpringCloud continuous integration process description

  1. Developers submit code to the Gitlab code repository every day
  2. Jenkins pulled the source code of the project from Gitlab, compiled and packed it into a JAR package, then built it into a Docker image, and uploaded the image to Harbor private warehouse
  3. Jenkins sent an SSH remote command to the production deployment server to Harbor private repository to pull the image locally and create the container
  4. Finally, the user can access the container

Source code overview of SpringCloud microservices

  • Project architecture: Front end separation

  • Backend technology stack: SpringBoot+SpringCloud+SpringDataJpa

  • Microservice project structure:

    • Tensquare_parent: Parent project, which stores basic configuration
    • Tensquare_common: General purpose project, which houses utility classes
    • Tensquare_eureka_server: Eureka registry for SpringCloud
    • Tensquare_zuul: Gateway service for SpringCloud
    • Tensquare_admin_service: Base authority authentication authority responsible for user authentication (using JWT authentication)
    • Tensquare_gathering: A simple business module, active microservices related logic
  • Database structure:

    • Tensquare_user: user authentication database, storing user account data. Corresponding to tensquare_admin_service microservice
    • Tensquare_gathering: Active microservices database. Corresponding to tensquare_gathering microservice
  • Microservice configuration analysis:

    • tensquare_eureka
    • tensquare_zuul
    • tensquare_admin_service
    • tensquare_gathering

Local deployment

Start microservices one by one

  1. Run the Eureka server Enter localhost:10086 in your browser

  2. Enable the gateway Zuul

  3. Enabling permission Center

  4. Enabling microservices

All started up successfully

SpringCloud microservices deployment

The first step is to import the plug-in to add in pom.xml

 <plugin>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-maven-plugin</artifactId>
 </plugin>
Copy the code
  1. SpringBoot microservice project packaging

    The generated JAR package is under TargetJar packages that run microservices locally

    java -jar xxx.jar

    We can run it using CMD

Make microservice image using Dockerfile

Install the docker

Yum install -y yum-utils yum install -y yum-utils yum install -y yum-utils yum install -y yum-utils yum install -y yum-utils http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo update yum yum package index makecache fast installation docker docker - ce community yum -y install docker-ce docker-ce-cli containerd. IO Start docker systemctl start docker Check the version of the docker versionCopy the code

Upload eureka jar package to the server

Mkdir /root/eureka mv tensquare_eureka_server-1.0-snapshot. jar /root/eureka/cd /root/eureka/
vim Dockerfile

FROM openjdk:8-jdk-alpine 
ARG JAR_FILE 
COPY ${JAR_FILE} app.jar 
EXPOSE 10086 
ENTRYPOINT ["java"."-jar"."/app.jar"] docker build --build-arg JAR_FILE= tensquare_eureka_server-1.0-snapshot. jar -t eureka:v1# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE eureka v1 255f6b6c7c53 4 seconds ago 150MB openjdk 8-jdk-alpine a3562aa0b991 2 Years ago 105MB Verifying whether the image is successful Docker run -di -p 10086:10086 Eureka :v1 Checking logs Docker logs -f Container IDCopy the code

Browser access

Harbor mirror warehouse installation and use

  • Harbor is an enterprise-class Registry server for storing and distributing Docker images.
  • In addition to Harbor, a private image repository, there is also Registry officially provided by Docker. Compared with Registry, Harbor has many advantages:
    1. Provide hierarchical transmission mechanism, optimize network transmission Docker image is hierarchical, and if each transfer uses the full file (so using FTP is not suitable), it is obviously not economical. A mechanism must be provided to identify the layered transport, identified by the UUID of the layer, to identify the object being transferred.
    2. Provide a WEB interface to optimize user experience. It is not convenient to upload and download images using only the image name. A user interface is required to support login and search functions, including distinguishing public and private images.
    3. Supports horizontal scaling of clusters

    If image uploading and downloading operations are centralized on a server, the corresponding access pressure must be resolved. 4. Good security Mechanism The development team in an enterprise has many different positions, and different permissions are assigned to different positions, which provides better security.

Harbor installation

We installed it on the Harbor server

Install Docker and Compose

Yum install -y yum-utils yum install -y yum-utils yum install -y yum-utils yum install -y yum-utils yum install -y yum-utils http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo installation docker yum install docker - ce docker - ce - cli containerd.io systemctlenableDocker - now download and install compose the curl -l https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose licenses chmod +x /usr/local/bin/docker-compose View the docker-compose versionCopy the code

Install harbor download address

Upload the download to the server

Tar xf harbor-offline-installer-v1.9.2. TGZ -c /usr/local

cd /usr/localVim harbor. Yml hostname: 192.168.188.103 port 85 will not conflict with 80 port: 85 Run the./prepare installation./install.sh command to pull an image. After the installation is complete, you can access the browser using the local addressCopy the code

The user name is admin, and the default password is Harbor12345

Create users and projects in Harbor

Create a project

Harbor projects are public and private:

  • Public project: Accessible to all users, usually holding public images, with a Library public project by default.
  • Private projects: Accessible only to authorized users, usually holding a mirror of the project itself.

We can create a new project for the microservice project

Create a user Password Xiaotian123

Assign users to private projects

Upload the image to Harbor

  1. Label the image

    [root@jenkins eureka]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE eureka v1 255f6b6c7c53 32 minutes ago 150MB openjdk 8-jdk-alpine a3562aa0b991 2 Years line 105 MB docker tag eureka: v1 192.168.188.103:85 / tensquare/eureka: v1 [root @ Jenkins had]# docker imagesREPOSITORY TAG IMAGE ID CREATED the SIZE 192.168.188.103:85 / tensquare/eureka v1 255 f6b6c7c53 33 minutes line 150 MB had v1 255f6b6c7c53 33 minutes ago 150MB openjdk 8-jdk-alpine a3562aa0b991 2 years ago 105MBCopy the code
  2. Add Harbor address to Docker trust list

    vi /etc/docker/daemon.json
    
    {
    "registry-mirrors": ["https://zydiol88.mirror.aliyuncs.com"]."insecure-registries": ["192.168.188.103:85"} restart the dockerCopy the code
  3. Log in Harbor

    Docker login 192.168.188.103:85 -u maomao -p Xiaotian123Copy the code
  4. Push the mirror

    Docker push 192.168.188.103:85 / tensquare/eureka: v1Copy the code

There’s an uploaded image in the warehouse

Download the image from Harbor

Download the image file from server 192.168.188.102

vi /etc/docker/daemon.json

{
"registry-mirrors": ["https://zydiol88.mirror.aliyuncs.com"]."insecure-registries": ["192.168.188.103:85"]
}

systemctl daemon-reload 
systemctl restart docker
Copy the code

Log in first, then download the image from Harbor

[root@tomcat ~]# docker login 192.168.188.103:85 -u maomao -p Xiaotian123 
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-storeThe Login Succeeded pull mirror docker pull 192.168.188.103:85 / tensquare/eureka: v1 docker imagesCopy the code

Continuous microservice integration

The project code is uploaded to Gitlab

Upload background micro-service and front-end Web site code

First go to gitLab to create the project We have two new projects in this groupUpload code, through IDEA operation

Add adds to the local bufferSubmit code to the local code repository Create a new warehouse address

Push code to the repository

The project has been submitted successfullyFront-end code we upload through Git little turtleThe installation address

Right-click in the code directory and select Create Repository here

Right click Commit

Select Push to push the code to the remote repository

Setting warehouse Address Fill in the warehouse user and password

So far the code has been uploaded to the repository

Pull the project source code from Gitlab

We went into Jenkins to build back-end pipeline projectsAdd parameters

Select the SCM script to upload to the repository and configure the Git address to be pulled by SSHOpen IDEA and create a Jenkinsfile under the project root

Open pipelined syntaxHelp us generate the scriptWe can define variables

ID / / git certificate
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// Git url
def git_url = "[email protected]: maomao_group/tensquare_back. Git." "


node {
   stage('Pull code') {
      checkout([$class: 'GitSCM'.branches: [[name: "*/${branch}"]], extensions:[].userRemoteConfigs: [[credentialsId: "${git_auth}".url: "${git_url}"]]])}}Copy the code

Upload Jenkinsfile Start building the project == Notice == The script must pay attention to the format and syntax, because of the colon reason, I made three mistakes before correcting it

Submit to SonarQube code review

In the tensquare_back project, add two parameters the Choice ParameterAdd the name you want to select for review

The build can then choose which code to reviewNext configure the Sonarkube file

Created in the eureka_server root directorysonar-project.properties eureka_server

# must be unique in a given SonarQube instance
sonar.projectKey=tensquare_eureka_server
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=tensquare_eureka_server
sonar.projectVersion=1.0

# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. # This property is optional if sonar.modules is set. sonar.sources=. Sonar. Exclusions = / test / * *, * * * * / target / * * sonar in Java. The binaries =. Sonar. Java source = 1.8 sonar. Java. Target = 1.8 #sonar.java.libraries=**/target/classes/** # Encoding of the source code. Default is default system encoding sonar.sourceEncoding=UTF-8Copy the code

Then add different sonar-project.properties to the corresponding directory

zull

# must be unique in a given SonarQube instance
sonar.projectKey=tensquare_zuul
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=tensquare_zuul
sonar.projectVersion=1.0

# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. # This property is optional if sonar.modules is set. sonar.sources=. Sonar. Exclusions = / test / * *, * * * * / target / * * sonar in Java. The binaries =. Sonar. Java source = 1.8 sonar. Java. Target = 1.8 #sonar.java.libraries=**/target/classes/** # Encoding of the source code. Default is default system encoding sonar.sourceEncoding=UTF-8Copy the code

admin_service

# must be unique in a given SonarQube instance
sonar.projectKey=tensquare_admin_service
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=tensquare_admin_service
sonar.projectVersion=1.0

# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. # This property is optional if sonar.modules is set. sonar.sources=. Sonar. Exclusions = / test / * *, * * * * / target / * * sonar in Java. The binaries =. Sonar. Java source = 1.8 sonar. Java. Target = 1.8 #sonar.java.libraries=**/target/classes/** # Encoding of the source code. Default is default system encoding sonar.sourceEncoding=UTF-8Copy the code

gathering

# must be unique in a given SonarQube instance
sonar.projectKey=tensquare_gathering
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=tensquare_gathering
sonar.projectVersion=1.0

# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. # This property is optional if sonar.modules is set. sonar.sources=. Sonar. Exclusions = / test / * *, * * * * / target / * * sonar in Java. The binaries =. Sonar. Java source = 1.8 sonar. Java. Target = 1.8 #sonar.java.libraries=**/target/classes/** # Encoding of the source code. Default is default system encoding sonar.sourceEncoding=UTF-8Copy the code

Modify the Jenkinsfile script

ID / / git certificate
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// Git url
def git_url = "[email protected]: maomao_group/tensquare_back. Git." "


node {
   stage('Pull code') {
      checkout([$class: 'GitSCM'.branches: [[name: "*/${branch}"]], extensions:[].userRemoteConfigs: [[credentialsId: "${git_auth}".url: "${git_url}"]]])
   }
   stage('Code Review') {
        // The SonarQubeScanner tool environment that defines the current Jenkins is viewed in the global tools configuration
        def scannerHome = tool 'sonar-scanner'
        // Reference the current JenkinsSonarQube environment in the system configuration view
        withSonarQubeEnv('sonarqube') { 
             sh """ cd ${project_name} ${scannerHome}/bin/sonar-scanner """}}}Copy the code

Push the code into the repository and build the projectView console output

Start reviewing codeBuilding a successfulGo to sonarkube to see the results of the reviewThen we review the remaining three codes as well There is no problem

Package microservices as JAR packages

The first step is to compile and install a common subproject process

Add a step to Jenkinsfile

ID / / git certificate
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// Git url
def git_url = "[email protected]: maomao_group/tensquare_back. Git." "


node {
   stage('Pull code') {
      checkout([$class: 'GitSCM'.branches: [[name: "*/${branch}"]], extensions:[].userRemoteConfigs: [[credentialsId: "${git_auth}".url: "${git_url}"]]])
   }
   stage('Code Review') {
        // The SonarQubeScanner tool environment that defines the current Jenkins is viewed in the global tools configuration
        def scannerHome = tool 'sonar-scanner'
        // Reference the current JenkinsSonarQube environment in the system configuration view
        withSonarQubeEnv('sonarqube') {
             sh """ cd ${project_name} ${scannerHome}/bin/sonar-scanner """
        }
   }
   stage('Compile, install common subproject') {
        sh "mvn -f tensquare_common clean install"}}Copy the code

Upload the script to your Git repository and try another build packageBuilding a successful

If that fails, go into IDEA and remove the spring-boot-Maven plugin from the tensquare_parent project to the project that needs to be packaged

The tensquare_common subproject does not require this plug-in

Just add the plugin to tensquare_eureka_server, tensquare_admin_service, tensquare_gathering, tensquare_zuul

<build>
       <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
Copy the code

Once you’ve made the adjustments, continue writing Jenkinsfile, and it’s time to package other microservices

ID / / git certificate
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// Git url
def git_url = "[email protected]: maomao_group/tensquare_back. Git." "


node {
   stage('Pull code') {
      checkout([$class: 'GitSCM'.branches: [[name: "*/${branch}"]], extensions:[].userRemoteConfigs: [[credentialsId: "${git_auth}".url: "${git_url}"]]])
   }
   stage('Code Review') {
        // The SonarQubeScanner tool environment that defines the current Jenkins is viewed in the global tools configuration
        def scannerHome = tool 'sonar-scanner'
        // Reference the current JenkinsSonarQube environment in the system configuration view
        withSonarQubeEnv('sonarqube') {
             sh """ cd ${project_name} ${scannerHome}/bin/sonar-scanner """
        }
   }
   stage('Compile, install common subproject') {
        sh "mvn -f tensquare_common clean install"
   }
   // where project_name is the parameter selected for whom to package
   stage('Compile, install common subproject') {
           sh "mvn -f ${project_name} clean package"}}Copy the code

Package the Eureka service Tensquare_admin_service is not packaged tensquare_eureka_server is packaged and there are JAR packages in targetNext, the other three microservices are packaged in the same way but are being packagedtensquare_zuulAn error in theBecause the gateway depends on the parent project, but the parent project in the warehouse does not

Therefore, we need to manually upload the parent project pom.xml file to Jenkins server

Rebuild againThis time, the poM file of the parent project was found and packaged successfullyThe remaining two microservices are then packaged and builtEverything was successful except the second failure to package the gateway

Use Dockerfile to compile and generate images

Construct Docker image using dockerfile-maven-plugin

Add the dockerfile-maven-plugin to the ==pom.xml of each microservice project ==

We can add the dockerfile-maven-plugin to the spring-boot-maven-plugin

<build>
       <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <repository>${project.artifactId}</repository>
                    <buildArgs>
                        <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                    </buildArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>
Copy the code

Create a Dockerfile file for each microservice

#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10086
ENTRYPOINT ["java"."-jar"."/app.jar"]

Copy the code

Modify Jenkinsfile add dockerfile:build command

ID / / git certificate
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// Git url
def git_url = "[email protected]: maomao_group/tensquare_back. Git." "


node {
   stage('Pull code') {
      checkout([$class: 'GitSCM'.branches: [[name: "*/${branch}"]], extensions:[].userRemoteConfigs: [[credentialsId: "${git_auth}".url: "${git_url}"]]])
   }
   stage('Code Review') {
        // The SonarQubeScanner tool environment that defines the current Jenkins is viewed in the global tools configuration
        def scannerHome = tool 'sonar-scanner'
        // Reference the current JenkinsSonarQube environment in the system configuration view
        withSonarQubeEnv('sonarqube') {
             sh """ cd ${project_name} ${scannerHome}/bin/sonar-scanner """
        }
   }
   stage('Compile, install common subproject') {
        sh "mvn -f tensquare_common clean install"
   }
   stage('Compile, install common subproject') {
           sh "mvn -f ${project_name} clean package dockerfile:build"}}Copy the code

Then build eureka_serverMake a mirror imageExecute the steps written in DockerfileThe final successCheck that the image is created successfullyNext, build the other microservices into images, writing dockerfiles and adding plug-ins

tensquare_zuul

#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10020
ENTRYPOINT ["java"."-jar"."/app.jar"]
Copy the code

tensquare_admin_service

#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 9001
ENTRYPOINT ["java"."-jar"."/app.jar"]
Copy the code

tensquare_gathering

#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 9002
ENTRYPOINT ["java"."-jar"."/app.jar"]
Copy the code

Upload the code and build it

The images of the four microservices were built successfully

Upload to Harbor Mirror warehouse

Modify the Jenkinsfile build script

ID / / git certificate
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// Git url
def git_url = "[email protected]: maomao_group/tensquare_back. Git." "
// Version number of the mirror
def tag = "latest"
// Harbor url
def harbor_url = "192.168.188.103:85"
// Mirror library project name
def harbor_project = "tensquare"

node {
   stage('Pull code') {
      checkout([$class: 'GitSCM'.branches: [[name: "*/${branch}"]], extensions:[].userRemoteConfigs: [[credentialsId: "${git_auth}".url: "${git_url}"]]])
   }
   stage('Code Review') {
        // The SonarQubeScanner tool environment that defines the current Jenkins is viewed in the global tools configuration
        def scannerHome = tool 'sonar-scanner'
        // Reference the current JenkinsSonarQube environment in the system configuration view
        withSonarQubeEnv('sonarqube') {
             sh """ cd ${project_name} ${scannerHome}/bin/sonar-scanner """
        }
   }
   stage('Compile, install common subproject') {
        sh "mvn -f tensquare_common clean install"
   }
   stage('Compile, install common subproject, upload image') {
           sh "mvn -f ${project_name} clean package dockerfile:build"

           // Define the mirror name
           def imageName = "${project_name}:${tag}"

           // Label the image
           sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"}}Copy the code

Test whether the generated image can be labeled

Add a Harbor user credentialGo in again and copy the generated ID 4135b3f5-a3eb-436e-a6ef-fe096098bb4f

Pipelined syntax

Add variables to pipeline-generated syntax with minor changes

// git certificate ID
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// Git url
def git_url = "[email protected]: maomao_group/tensquare_back. Git." "
// Version number of the mirror
def tag = "latest"
// Harbor url
def harbor_url = "192.168.188.103:85"
// Mirror library project name
def harbor_project = "tensquare"
// Harbor's login credential ID
def harbor_auth = "4135b3f5-a3eb-436e-a6ef-fe096098bb4f"

node {
   stage('Pull code') {
      checkout([$class: 'GitSCM'.branches: [[name: "*/${branch}"]], extensions:[].userRemoteConfigs: [[credentialsId: "${git_auth}".url: "${git_url}"]]])
   }
   stage('Code Review') {
        // The SonarQubeScanner tool environment that defines the current Jenkins is viewed in the global tools configuration
        def scannerHome = tool 'sonar-scanner'
        // Reference the current JenkinsSonarQube environment in the system configuration view
        withSonarQubeEnv('sonarqube') {
             sh """ cd ${project_name} ${scannerHome}/bin/sonar-scanner """
        }
   }
   stage('Compile, install common subproject') {
        sh "mvn -f tensquare_common clean install"
   }
   stage('Compile, install common subproject, upload image') {

         sh "mvn -f ${project_name} clean package dockerfile:build"

         // Define the mirror name
         def imageName = "${project_name}:${tag}"

         // Label the image
         sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"

         // Push the image to Harbor
         withCredentials([usernamePassword(credentialsId: "${harbor_auth}".passwordVariable: 'password'.usernameVariable: 'username')]) {
             // Log in to Harbor
             sh "docker login -u ${username} -p ${password} ${harbor_url}"

             // Image upload
             sh "docker push ${harbor_url}/${harbor_project}/${imageName}"

             sh "Echo image uploaded successfully"}}}Copy the code

Image uploading succeeded

An error

I got two little details wrong on this step and it took me over an hour to figure it out

The docker tag command has too many parameters. The docker tag command has too many parametersAll kinds of checks, there are still Spaces, find the == option parameter == in the task configurationThe option is preceded by a space, causing the script to read parameters that also contain Spaces

The second error is because I wrote username as usrname

Pull images and publish applications

The installationPublish Over SSHThe plug-in can be used to send Shell commands remotely

Configure the remote deployment server

Copy the Jenkins server public key to the remote Tomcat server ssh-copy-id 192.168.188.107Copy the code

Go to System configuration in Jenkins and find Publish over SSH

Path to key Specifies the location where the private key is stored /root/.ssh/id_rsa

Click add Hostname to fill in the host IP address of the remote deployment projectTo write Jenkinsfile scripts, first go to pipelining syntax and find this script that will help us generate some remote connectionsSSH Server Selects the server with our precursors public keyLeave everything else blank for now. Click Generate Pipeline scriptThis is a copy of the script

sshPublisher(publishers: [sshPublisherDesc(configName: 'tomcat_server'.transfers: [sshTransfer(cleanRemote: false.excludes: ' '.execCommand: ' '.execTimeout: 120000.flatten: false.makeEmptyDirs: false.noDefaultExcludes: false.patternSeparator: '[and] +'.remoteDirectory: ' '.remoteDirectorySDF: false.removePrefix: ' '.sourceFiles: ' ')].usePromotionTimestamp: false.useWorkspaceInPromotion: false.verbose: false)])
Copy the code
  • ExecCommand is a command executed on a remote server, and we have it execute a shell script that will help us with deployment

  • Since the ports of our microservices are different, we need to add new port parameters in the pipeline task

Write remote script files

Accessing the Tomcat server [root@tomcat ~]# mkdir /opt/jenkins_shell
[root@tomcat ~]# cd /opt/jenkins_shell/
[root@tomcat jenkins_shell]# vim deploy.sh

#! /bin/bash
Accept external parameters
harbor_url=The $1
harbor_project=$2
project_name=$3
tag=$4
port=A $5

imageName=$harbor_url/$harbor_project/$project_name:$tag

echo "$imageName"

If the container exists, delete it
containerId=`docker ps -a | grep -w ${project_name}:${tag}  | awk '{print $1}'`
if [ "$containerId"! =""];then
    # Stop the container
    docker stop $containerId

    # delete container
    docker rm $containerId
	
	echo "Container deleted successfully"
fi

# Check whether the mirror exists and delete it
imageId=`docker images | grep -w $project_name  | awk '{print $3}'`

if [ "$imageId"! =""];then
      
    # delete mirror
    docker rmi -f $imageId
	
	echo "Mirror deleted successfully"
fi

# login Harbor
docker login -u maomao -p Xiaotian123 $harbor_url

# Download image
docker pull $imageName

# start container
docker run -di -p $port:$port $imageName

echo "Container started successfully"
Copy the code
Then add execute permission to the script chmod +x deploy.shCopy the code

Write Jenkinsfile

// git certificate ID
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// Git url
def git_url = "[email protected]: maomao_group/tensquare_back. Git." "
// Version number of the mirror
def tag = "latest"
// Harbor url
def harbor_url = "192.168.188.106:85"
// Mirror library project name
def harbor_project = "tensquare"
// Harbor's login credential ID
def harbor_auth = "c0e6642d-bab9-4978-be45-955e5130fae2"

node {
   stage('Pull code') {
      checkout([$class: 'GitSCM'.branches: [[name: "*/${branch}"]], extensions:[].userRemoteConfigs: [[credentialsId: "${git_auth}".url: "${git_url}"]]])
   }
   stage('Code Review') {
        // The SonarQubeScanner tool environment that defines the current Jenkins is viewed in the global tools configuration
        def scannerHome = tool 'sonar-scanner'
        // Reference the current JenkinsSonarQube environment in the system configuration view
        withSonarQubeEnv('sonarqube') {
             sh """ cd ${project_name} ${scannerHome}/bin/sonar-scanner """
        }
   }
   stage('Compile, install common subproject') {
        sh "mvn -f tensquare_common clean install"
   }
   stage('Compile, install common subproject, upload image') {

         sh "mvn -f ${project_name} clean package dockerfile:build"

         // Define the mirror name
         def imageName = "${project_name}:${tag}"

         // Label the image
         sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"

         // Push the image to Harbor
         withCredentials([usernamePassword(credentialsId: "${harbor_auth}".passwordVariable: 'password'.usernameVariable: 'username')]) {
             // Log in to Harbor
             sh "docker login -u ${username} -p ${password} ${harbor_url}"

             // Image upload
             sh "docker push ${harbor_url}/${harbor_project}/${imageName}"

             sh "Echo image uploaded successfully"
         }

         // Deploy the project
         sshPublisher(publishers: [sshPublisherDesc(configName: 'tomcat_server'.transfers: [sshTransfer(cleanRemote: false.excludes: ' '.execCommand: "/opt/jenkins_shell/deploy.sh $harbor_url $harbor_project $project_name $tag $port".execTimeout: 120000.flatten: false.makeEmptyDirs: false.noDefaultExcludes: false.patternSeparator: '[and] +'.remoteDirectory: ' '.remoteDirectorySDF: false.removePrefix: ' '.sourceFiles: ' ')].usePromotionTimestamp: false.useWorkspaceInPromotion: false.verbose: false)]}}Copy the code

Build the project after you upload the code The system starts to remotely log in to the server and execute the scriptView images and containers on the deployment server

Change the microservice Settings and prepare the test data

  • Eureka configuration

Change the IP address to the deployed server address

  • Zuul gateway

Also change the IP address of eruka

  • Admin_service Permission center

The database information needs to be modified here (we choose mysql on Sonarqube server as the back-end database, which is on Jenkins server).

  • So we need to go to mysql for authorization
Authorize the root account to log in to all clientsgrant all privileges on *.* to 'root'@The '%' identified by '123'; Refresh privileges flush PRIVILEGES;Copy the code

Use Navicat tests Modify the configuration

  • Gathering also modifies database and IP

Finally, all updated configurations are uploaded to the repositoryThen import mysql dataFinally, the remaining three microservices are also built into containers. The important thing here is to change the ports Check the containerViewing through a browser

Deploy a front-end static Web site

Do this on the Tomcat server

Yum install -y epel-release yum -y install nginx Vim /etc/nginx/nginx.conf server {listen 9090 default_server; listen [::]:9090 default_server; server_name _; root /usr/share/nginx/html; Start the nginx systemctlenable nginx --now
Copy the code

Install the NodeJS plug-inJenkins configured the Nginx server in the global tools configuration

Go to NodeJS and select a version to save

Create a front-end pipeline projectFirst add the branch parameter

Write pipelined scripts

/ / gitlab credentials
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
 node { stage('Pull code') {
	checkout([$class: 'GitSCM'.branches: [[name: '*/${branch}']],
	doGenerateSubmoduleConfigurations: false.extensions:[].submoduleCfg:[].userRemoteConfigs: [[credentialsId: "${git_auth}".url:
	'[email protected]: maomao_group/tensquare_front. Git']]]) 
	   }
	   stage('Package, deploy the site') {
	   // Use NodeJS NPM for packaging
	   nodejs('nodejs12'){
			sh ''' npm install npm run build ''' 
		}
		
		//===== The following is a remote call for project deployment ========
		sshPublisher(publishers: [sshPublisherDesc(configName: 'tomcat_server'.transfers: [sshTransfer(cleanRemote: false.excludes: ' '.execCommand: ' '.execTimeout: 120000.flatten: false.makeEmptyDirs: false.noDefaultExcludes:
		false.patternSeparator: '[and] +'.remoteDirectory: '/usr/share/nginx/html'.remoteDirectorySDF: false.removePrefix: 'dist'.sourceFiles: 'dist/**')].usePromotionTimestamp: false.useWorkspaceInPromotion: false.verbose: false)]}}Copy the code

Note that the git_auth credential ID needs to be found in Jenkins Building a successfulUse a browser to log in to port +9090The loginThe database information was queried, so it proves that the front-end page and back-end connection is successful

At this point, our ==Jenkins+Docker+SpringCloud microservice continuous integration == has been built, and the rest is to optimize it