1、安装jenkins
1.1 安装jdk
要求:11及以上版本
yum install yum install java-11-openjdk 
1.2 安装jenkins
导入镜像
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
 
出现以下错误

执行以下命令
sudo yum install -y ca-certificates
 
导入key
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key 
安装jenkins
 yum install jenkins 
2 配置jenkins
2.1 配置服务端口
 vim /usr/lib/systemd/system/jenkins.service 
修改Environment="JENKINS_PORT=9080"

2.2 配置 jenkins 用户组
Jenkins 安装好后,会自动创建一个 jenkins 用户。jenkins 在构建工程时,默认的权限是不够写入文件的。这时就需要把它的权限提升为root。
将 jenkins 账号加入到 root 组中。
gpasswd -a jenkins root 
修改vim /usr/lib/systemd/system/jenkins.service文件,修改如下配置。

重启服务
systemctl daemon-reload
systemctl restart jenkins 
2.3 配置jenkins镜像加速
配置jenkins镜像加速
vim /var/lib/jenkins hudson.model.UpdateCenter.xml 
原配置
<?xml version='1.1' encoding='UTF-8'?>
<sites>
  <site>
    <id>default</id>
    <url>https://updates.jenkins.io/update-center.json</url>
  </site>
</sites> 
修改为以下配置
<?xml version='1.1' encoding='UTF-8'?>
<sites>
  <site>
    <id>default</id>
    <url>https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json</url>
  </site>
</sites> 
也可在登录Jenkins后在插件的高级设置里配置镜像加速,如下图所示

3 初始化配置jenkins
访问web页面(http://IP:端口)
3.1 获取初始密码登录
cat /var/lib/jenkins/secrets/initialAdminPassword 
输入初始密码

3.2 安装插件,推荐的即可

3.3 创建用户 并登录

3.4 安装插件
1、安装maven插件


3、安装Pipeline Utility Steps

4、安装Nodejs

5、安装Blue Ocean

4 全局工具配置
4.1、maven 配置

4.2、nodejs 配置

4.2 maven配置修改
vim /var/lib/jenkins/tools/hudson.tasks.Maven_MavenInstallation/maven-3.9.4/conf/settings.xml 
 
5 创建多分支流水线
1、打开Blue Ocean

2、创建新的流水线

配置仓库和凭证信息
 
退出Blue Ocean,打开流水线项目
3、扫描多分支流水线

6、docker 镜像推送到Habour及部署到远程服务器
项目的Jenkinsfile
pipeline {
    environment {
        product = "test-project-back"
        //镜像仓库地址
        repository_host = "192.168.1.5:5050"
        env_profile = ""
        deploy_port = ""
    }
    agent any
    tools {
        maven 'maven-3.9.4'
    }
    triggers {
        GenericTrigger(
            genericVariables: [
                [key: 'ref', value: '$.ref']
            ],
            causeString: 'Triggered on $ref',
            token: 'test-project-bac',
            printContributedVariables: true,
            printPostContent: false,
            silentResponse: false,
            shouldNotFlatten: false,
            regexpFilterText: '$ref',
            regexpFilterExpression: 'refs/heads/' + BRANCH_NAME
        )
    }
    // 存放所有任务的合集
    stages {
        stage("prepare") {
            when {
                anyOf {
                    branch "?.?.?/dev"
                    branch "?.?.?/qa"
                    branch "?.?.?/release"
                }
            }
            steps {
                echo "当前jenkins的工作目录:${env.WORKSPACE}"
                deleteDir()
                checkout scm
                script {
                    prepare()
                }
            }
        }
        stage('maven build') {
            when {
                anyOf {
                    branch "?.?.?/dev"
                    branch "?.?.?/qa"
                    branch "?.?.?/release"
                }
            }
            steps {
                sh """
                    mvn -B -DskipTests clean package
                    cp ./target/test-api.jar ./docker/test-project-bac/jar/
                """
            }
        }
        stage('docker build image') {
            when {
                anyOf {
                    branch "?.?.?/dev"
                    branch "?.?.?/qa"
                    branch "?.?.?/release"
                }
            }
            steps {
                sh """
                    cd ./docker/test-project-bac
                    docker build -f ./dockerfile -t ${product}-${env_profile}-${tag_version} --build-arg env_profile="${env_profile}" --build-arg tag_version="${tag_version}" .
                """
            }
        }
        stage('docker push') {
            when {
                anyOf {
                    branch "?.?.?/dev"
                    branch "?.?.?/qa"
                    branch "?.?.?/release"
                }
            }
            steps {
                sh """
                    docker login -u admin -p 123456 ${repository_host}
                    docker tag ${product}-${env_profile}-${tag_version}  ${repository_host}/repository/${product}-${env_profile}-${tag_version}
                    docker push ${repository_host}/repository/${product}-${env_profile}-${tag_version}
                    docker rmi \$(docker images --format "{{.Repository}}:{{.Tag}}" | grep ${product}-${env_profile}-${tag_version}) || true
                """
            }
        }
        stage('docker deploy') {
            when {
                anyOf {
                    branch "?.?.?/dev"
                    branch "?.?.?/qa"
                    branch "?.?.?/release"
                }
            }
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: 'test-Server', transfers: [sshTransfer(cleanRemote: false, excludes: '',
                execCommand: """
                   docker stop \$(docker ps -a --format "{{.Names}}" | grep ${product}-${env_profile}-${tag_version}) || true
                   docker rm \$(docker ps -a --format "{{.Names}}" | grep ${product}-${env_profile}-${tag_version}) || true
                   docker rmi \$(docker images --format "{{.Repository}}:{{.Tag}}" | grep ${repository_host}/repository/${product}-${env_profile}-${tag_version}) || true
                   docker pull ${repository_host}/repository/${product}-${env_profile}-${tag_version}
                   docker run -e TZ=Asia/Shanghai -e 'spring.profiles.active'=${env_profile} \
                              -e tag_version=${tag_version} -d -p ${deploy_port}:${deploy_port} --restart=always \
                              --name ${product}-${env_profile}-${tag_version}-${build_version} ${repository_host}/repository/${product}-${env_profile}-${tag_version}
                """,
                execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+',
                remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false,
                useWorkspaceInPromotion: false, verbose: true)])
            }
        }
    }
}
def prepare() {
    def pom = readMavenPom file: 'pom.xml'
    echo "groupId:${pom.groupId}\nartifactId:${pom.artifactId}\npackaging:${pom.packaging}\nversion:${pom.version}"
    build_version = sh(script: "echo `date '+%Y%m%d%H%M%S'`", returnStdout: true).trim()
    tag_version = env.BRANCH_NAME.split("/")[0]
    branch_env = env.BRANCH_NAME.split("/")[1]
    pom_version = pom.version
    image_tag = branch_env + "-" +  pom.version
    switch (branch_env) {
        case "dev":
            deploy_port = "8081"
            env_profile = "dev"
            break
        case "qa":
            deploy_port = "28081"
            env_profile = "test"
            break
        case "release":
            deploy_port = "38081"
            env_profile = "prod"
            break
    }
}
 
7、webhook触发自动化构建部署
环境:Gogs
1、创建钩子

2、配置推送地址

3、测试验证

4、推送失败问题

如果提示
Did not find any jobs with GenericTrigger configured!\nA token was supplied.\n
是因为创建多分支流水线后,jenkins没有重启,gogs推送过去jenkins说找不到token对应的job,重启下jenkins服务即可。这算jenkins的一个bug吧!