1. 安装

方式一:yum install

sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
yum install fontconfig java-17-openjdk
yum install jenkins

手动添加java环境变量

export JAVA_HOME=/etc/java/jdk-17.0.2
export PATH=$JAVA_HOME/bin:$PATH

输入命令jenkins进入8080端口,使用命令行里面的随机密码。

方式二:war包直接运行

  1. 下载 Jenkins.
  2. 打开终端进入到下载目录.
  3. 运行命令 java -jar jenkins.war --httpPort=8080.
  4. 打开浏览器进入链接 http://localhost:8080.
  5. 按照说明完成安装.

方式三:docker

值得注意的是,如果是在容器中运行的jenkins,想要调用宿主机的docker,就需要通过挂载卷的形式,将docker进程关联到jenkins容器内部。

docker run
-u root
-d -p 8080:8080 -p 50000:50000
-v /mnt/user/appdata/Jenkins:/var/jenkins_home
-v /var/run/docker.sock:/var/run/docker.sock
-v /usr/bin/docker:/usr/bin/docker
--name jenkins jenkins/jenkins

UNRAID中设置如下:

2. 基本设置

3. 执行一次成功的构建

新建一个项目,选择多分支流水线,填写git地址等信息后保存,jenkins会自动开始读取项目中的Jenkinsfile

image.png

这是jenkins官方的java jenkinsfile示例(需要Docker Pipeline插件),这个文件主要的行为就是构建了一个maven容器并输出版本号:

/*Jenkinsfile (Declarative Pipeline)*/
/* 适用于简单的 Pipeline,其中所有阶段都在同一个 Docker 容器中运行 */
pipeline {
    agent { docker 'maven:3.3.3' }
    stages {
        stage('build') {
            steps {
                sh 'mvn --version'
            }
        }
    }
}
/* Jenkinsfile (Scripted Pipeline) */
node('docker') {
    checkout scm
    stage('Build') {
        docker.image('maven:3.3.3').inside {
            sh 'mvn --version'
        }
    }
}

点击项目中的立即构建,此时应当不会有任何的权限问题。如果构建还是失败,显示fatal: not in a git directory,则进入容器执行以下命令。

git config --global --add safe.directory '*'

构建成功后,可以看到显示对应的控制台输出了。

+ mvn --version
Apache Maven 3.3.3 (7994120775791599e205a5524ec3e0dfe41d4a06; 2015-04-22T11:57:37+00:00)
Maven home: /usr/share/maven
Java version: 1.8.0_91, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-8-openjdk-amd64/jre
Default locale: en, platform encoding: UTF-8
OS name: "linux", version: "6.1.99-unraid", arch: "amd64", family: "unix"

4. 创建一个单分支持续构建

我们想要达成的目标,便是如同该笔记一样,搭建一套改动内容->触发编译->更新页面/镜像的自动化流程。
首先项目中编写一个Dockerfile,这样就不用把执行步骤都写到jenkinsfile的脚本里了。

# 基础镜像  
FROM openjdk:8  
# 复制主机jar包至镜像内,复制的目录需放置在 Dockerfile 文件同级目录下  
ADD target/xss-filt-0.0.1-SNAPSHOT.jar app.jar  
# 容器启动执行命令  
ENTRYPOINT ["java","-jar", "/app.jar" , "--spring.profiles.active=prod"]  
# 对外暴露的端口号  
EXPOSE 8080

接下来有两种选择,第一种在Jenkins服务器上直接执行构建,优点是流程较为简单,只要本机环境安装好有足够的资源就行,第二种是使用Jenkins指挥节点(agent)执行构建,优点是 分离编译环境和Jenkins主机,适用于需要隔离不同环境或资源的场景,缺点很显然,就是配置相对复杂。一般推荐后者,只创建一两个节点也还好,难的是统一各个节点的配置以及任务分配。这里我创建一个debian虚拟机作为子节点。

再写一个Jenkinsfile,如下,大概作用就是指定节点,执行编译打包然后构建docker镜像和容器:

pipeline {
    agent { label 'debiad' } // 在特定节点上运行
    stages {
        stage('Verify Tools') {
            steps {
                sh 'mvn --version'
                sh 'docker --version'
            }
        }
        stage('Build') {
            steps {
                sh 'cd /home/liyue/projects/xss-filt'
                sh 'mvn clean package'
            }
        }
        stage('Deploy') {
            steps {
                sh 'docker build -t xss-img:0.1-SNAPSHOT .'
                sh 'docker rm -f xss-app || true'
                sh 'docker run -d -p 8080:8080 --name xss-app xss-img:0.1-SNAPSHOT'
            }
        }
    }
}

新建一个单分支流水线项目,除了常规设置以外勾选触发远程构建,自定义的身份令牌最好复杂点。

3.1 持续集成构建Gitea上的代码

Jenkins + Gitea实现持续集成 | 阿栋的博客 | 翻身不粘锅 (nicholaskoji.github.io)
Gitea 与 Jenkins 的集成实践,打造你的专属 CI/CD 系统 - Gitea - 博客园 (cnblogs.com)
getea上代码提交后通过webhook触发jenkins进行构建_gitea webhook-CSDN博客

Jenkins额外配置

  • 安装Gitea插件,以前叫Gitea Plugin。
  • 开启匿名用户可读,不然配置Webhook会显示Server broke connection
  • 关闭CSRF(跨站请求伪造攻击)保护,不然配置Webhook会显示403 forbidden。高版本不能在选项中关闭,需要配置启动参数-Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true,docker部署配置变量-e JAVA_OPTS="-Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true"

Gitea设置Webhook

打开项目的钩子界面,url按照jenkins提示格式填写JENKINS_URL/job/xss/build?token=TOKEN_NAME请求方式选GET,触发条件一般就是推送,其他东西不太需要去动。

添加完毕后可以点击推送测试,转到jenkins界面就能够看到启动了新一轮构建。

添加消息推送

邮件

其他问题

1. 控制台输出乱码

如果是类似如下这种

[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.247 s - in

乱码其实是颜色标记,jenkins页面不显示颜色,因此变成了符号。

2. java.lang.ExceptionInInitializerError: Unable to make field private

maven使用的jdk版本不对。

3. 更换网络配置后无法启动

世界未解之谜,初步判断和docker network有关系。
破案了,更换为custom network之后-p端口映射就失效了,因为整个ip都归该容器所有了,原来是什么就是什么,因此要用8080访问。

更换网络配置为custom network之后部分访问不稳定

新的世界未解之谜。具体症状为从相同网络的容器去curl Jenkins:8080偶尔会收不到,gitea测试webhook报错context deadline exceeded (Client.Timeout exceeded while awaiting headers),web界面偶尔无法访问(内网穿透远程)