# jenkins安装

# centos7.6互联网环境下rpm(yum)安装

  • 通过yum方式安装,需要提前安装jdk环境。使用Jdk8。 最新的jenkins需要jdk17以上,所以只能用固定版本的jdk
wget https://repo.huaweicloud.com/jenkins/redhat-stable/jenkins-2.346.1-1.1.noarch.rpm
rpm -ivh jenkins-2.346.1-1.1.noarch.rpm

#这一步是为了配置java环境,jenkins会用绝对地址的命令
ln -s /usr/local/java/jdk1.8.0_161/bin/java /usr/bin/java

#新增执行时间,不然首次执行会超时(偶尔出现,不一定会复现)
vim /usr/lib/systemd/system/jenkins.service
[Service]
TimeoutStartSec=300
TimeoutStopSec=300
TimeoutSec=300

#在内容中追加该参数,否则安装不了插件,参考地址 https://blog.csdn.net/weixin_50902636/article/details/143508066
# 注意,后方的内存大小,根据实际情况设置,不设置对于内存比较大的机器来说,有点浪费
JAVA_OPTS=-Dhudson.model.DownloadService.noSignatureCheck=true JAVA_ARGS=-Xms2048m -Xmx2048m

#这个可以设置上下文,用于代理环境(可选)
Environment="JENKINS_PREFIX=/jenkins"

systemctl daemon-reload

systemctl start jenkins
# install过程,不要安装插件,这个时候插件安装都会失败,免得浪费时间
# 点击 manage jenkins -> manage plugins -> available,点击check now,这时候会更新插件列表,然后安装插件

#更新插件中心的地址
vim /var/lib/jenkins/hudson.model.UpdateCenter.xml
-> <url>https://mirrors.aliyun.com/jenkins/updates/dynamic-2.346/update-center.json</url>

systemctl stop jenkins

systemctl start jenkins

# 镜像失效备注20250403

  • 国内的阿里源与清华源均已失效,互联网老版本不好找;

  • 对于 插件 2.1x, 2.2x可在github地址进行配置,https://github.com/jenkins-zh/update-center-mirror

  • 目前发现华为云镜像还存在https://mirrors.huaweicloud.com/jenkins/updates/

  • 为了保险起见,已经进行了本地备份: https://gitee.com/automannn/update-center-mirror.git

  • 插件认证报错(特别特别坑)配置 vim /usr/lib/systemd/system/jenkins.service

#在内容中追加该参数,参考地址 https://blog.csdn.net/weixin_50902636/article/details/143508066
JAVA_OPTS=-Dhudson.model.DownloadService.noSignatureCheck=true

systemctl daemon reload
systemctl stop jenkins
systemctl start jenkins

这是因为修改了默认的updater-center.json的内容, Jenkins会对其进行校验,校验逻辑在源码core/src/main/java/hudson/PluginManager.javacheckUpdateServer方法中可以看到

  • jenkins默认密码
cat /var/lib/jenkins/secrets/initialAdminPassword
  • 修改执行用户(ssh命令具有最高权限) vim /etc/sysconfig/jenkins
JENKINS_USER="root"
  • 修改Jenkins端口号、user、group vim /usr/lib/systemd/system/jenkins.service
User=root
Group=root
#默认8080端口,因为本人8080端口已使用,故改为8083。
Environment="JENKINS_PORT=8083" 

# jenkins常用插件

  • Publish Over SSH: 远程发布
  • NodeJS Plugin: nodejs的使用
  • Pipline: 流水线构建
  • Pipeline Stage View: 流水线任务预览
  • Blue Ocean: 流水线可视化
  • SSH Plugin: ssh远程执行命令
  • SSH server: ssh服务端配置

# jenkins使用

# 配置git

  • git安装
yum install git
git --version
  • 在jenkins的manage jenkins -> manage credentials -> 配置username,pass,id;
pipeline {
    agent any

    stages {
        stage('clone code') {
          steps {
            git(url: 'https://gitee.com/xxx/xxx.git', credentialsId: 'gitee', changelog: true, poll: false)
          }
        }
    }
}
  • git()是groovy的内置方法调用,常见的groovy内置方法调用有:
    • git: 拉取代码
    • sh: 执行shell命令
    • bat: 执行windows的批处理命令
    • withCredentials: 在步骤中使用凭据
    • archiveArtifacts: 用于归档构建产物
    • stash 和 unstash: 用于不同阶段之间共享文件
    • dir: 切换工作目录
    • timeout: 设置超时时间
    • container: 在docker容器中运行步骤

# 配置maven

  • 安装maven环境
# 遇到提示Not Found,就是安装的maven版本号更新了,可以官网(https://dlcdn.apache.org/maven/),查看对应的版本号,只更改数字即可
wget https://dlcdn.apache.org/maven/maven-3/3.8.8/binaries/apache-maven-3.8.8-bin.tar.gz
tar -zxvf apache-maven-3.8.8-bin.tar.gz -C /usr/local
ln -s /usr/local/apache-maven-3.8.8/bin/mvn /usr/bin/mvn
mvn -version
  • 配置jenkins
#更新settings配置文件及默认仓库地址,并追加内容
vim /usr/local/apache-maven-3.8.8/conf/settings.xml
>>> <servers>
    <server>
        <id>rdc-releases</id>
        <username>63bfbed4b7bea95c5370baf3</username>
        <password>E_BG7Vs0gKDy</password>
    </server>
    <server>
        <id>rdc-snapshots</id>
        <username>63bfbed4b7bea95c5370baf3</username>
        <password>E_BG7Vs0gKDy</password>
    </server>
</servers>
<mirrors>
    <mirror>
        <id>aliyunmaven</id>
        <name>阿里云公共仓库</name>
        <url>https://maven.aliyun.com/repository/public</url>
        <mirrorOf>central</mirrorOf>
    </mirror>
</mirrors>
pipeline {
    agent any

    stages {
        stage('clone code') {
          steps {
            git(url: 'https://gitee.com/automannn/natm-generator.git', credentialsId: 'gitee', changelog: true, poll: false)
          }
        }
        
        stage('build') {
          agent none
          steps {
            sh 'mvn  -Dmaven.test.skip=true clean package'
            sh 'ls'
          }
          
          post {
                success {
                    archiveArtifacts 'generator-starter/target/*.jar'
                }
          }
        }
    }
}

# 配置nodejs

  • 安装nodejs环境18以上准备环境(nojs18版本开始都需要安装glibc2.27支持)
  • 注意安装后一定要安装locale文件: make localedata/install-locales,
    • 切记切记(参考地址: https://www.cnblogs.com/owlowl/p/18286098,https://jacklee.life/%E6%93%8D%E4%BD%9C%E8%AE%B0%E5%BD%95/2020-08-13-%E5%8D%87%E7%BA%A7glibc%20%E5%AF%BC%E8%87%B4%E7%9A%84locale%20%E9%97%AE%E9%A2%98.html 耗时在10分钟左右)
# 升级GCC 和 make, 参考文档 https://blog.csdn.net/xinvictory/article/details/142693381,需要使用gcc8
vim /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo
>>> [centos-sclo-rh]
name=CentOS-7 - SCLo rh
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/rh/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo

yum install -y devtoolset-8
echo "source /opt/rh/devtoolset-8/enable" >> ~/.bashrc
source ~/.bashrc

# 参考地址 https://www.cnblogs.com/gongjiang79/p/18191590,https://www.cnblogs.com/dingshaohua/p/17103654.html, https://www.cnblogs.com/astonc/p/16660685.html
wget http://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.gz
tar xf glibc-2.28.tar.gz 

#参考地址: https://blog.csdn.net/freflying1119/article/details/141937402?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7Ebaidujs_baidulandingword%7ECtr-6-141937402-blog-137056771.235%5Ev43%5Epc_blog_bottom_relevance_base5&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7Ebaidujs_baidulandingword%7ECtr-6-141937402-blog-137056771.235%5Ev43%5Epc_blog_bottom_relevance_base5&utm_relevant_index=13
# bug描述参考地址: sourceware.org/bugzilla/attachment.cgi?id=11157
#修改glibc-2.28/scripts/test-installation.pl, 将第128行:&& $name ne “nss_test1” && $name ne “libgcc_s”) {
#改为:  && $name ne "nss_test1" && $name ne "nss_test2" && $name ne "nss_nis" && $name ne "nss_nisplus" && $name ne "libgcc_s") {

# 解决完上方的bug后在做下方的动作,切记切记
cd glibc-2.28/ && mkdir build  && cd build
../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
# 使用gcc8时,不会报错,使用gcc9会报错。  不带j4 编译耗时在7到8分钟
make -j4 #耗时3分钟左右
make install

#需要root
wget http://ftp.de.debian.org/debian/pool/main/g/gcc-8/libstdc++6_8.3.0-6_amd64.deb
ar -x libstdc++6_8.3.0-6_amd64.deb
tar -xvf data.tar.xz
cp usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 /usr/lib64/
find / -name "libstdc++*"
mv  /usr/lib64/libstdc++.so.6 /usr/lib64/libstdc++.so.6.bak
ll /usr/lib64/libstd*
ln -s /usr/lib64/libstdc++.so.6.0.25 /usr/lib64/libstdc++.so.6


# 参考地址: https://blog.csdn.net/ht3hyc/article/details/137056771(通过源码编译方式安装gcc和make,与上方效果一致,未采用该方案。用作参考)

  • 安装nodejs
# 解决githubusercontent有时无法访问的问题,使用 https://www.ipaddress.com/ 获取实际的ip地址
vim /etc/hosts
>>> 20.205.243.166 github.com
185.199.109.133 raw.githubusercontent.com

# 全局安装 nvm (Node 版本管理器)
mkdir -p /usr/local/nvm
export NVM_DIR="/usr/local/nvm"
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
# 登录方式下全局生效,主要是给其他用户使用,但是jenkins还是不行
echo 'export NVM_DIR="/usr/local/nvm"' >> /etc/profile
echo '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"' >> /etc/profile
echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> /etc/profile
source /etc/profile

#配置命令全局生效(正常来说,上方的操作已经可以生效了,如果不生效,则使用软连接)
ln -s /usr/local/nvm/versions/node/v20.18.0/bin/node /usr/bin/node
ln -s /usr/local/nvm/versions/node/v20.18.0/bin/npm /usr/bin/npm

# 下载并安装 Node.js(可能需要重启终端,如果执行了source还不能识别node命令,就新开终端)
nvm install 20
source ~/.bashrc
# 验证环境中是否存在正确的 Node.js 版本
node -v # 应该打印 `v20.18.0`
# 验证环境中是否存在正确的 npm 版本
npm -v # 应该打印 `10.8.2`

#配置生效
ln -s /usr/local/nvm/versions/node/v20.18.0/bin/node /usr/bin/node
ln -s /usr/local/nvm/versions/node/v20.18.0/bin/npm /usr/bin/npm
  • 配置sshPublisher,用于后续发布

    • manage jenkins -> manage plugins -> avaliable -> search for "Publish over SSH"
    • manage jenkins -> configure system -> Publish over SSH ->SSH Servers -> add server. 参考地址:https://developer.aliyun.com/article/1584152
    • 注意,这里配置的路径,将作为上传文件的起始路径,与 工作流中的remoteDirectory拼接起来,就是最终的文件上传路径; 这里的路径最好配置/,否则留空会使用/root,会导致幻觉.
  • 配置jenkins流水线及发布

pipeline {
    agent any

    stages {
        stage('Clone repository') {
          agent none
          steps {
            git(url: 'https://gitee.com/automannn/blog.git', credentialsId: 'gitee', changelog: true, poll: false)
          }
        }
        stage('Change Registry') {
          steps {
            
              sh '''npm config get registry
    
                npm config set registry https://repo.huaweicloud.com/repository/npm/
                
                npm config get registry
                
                npm set strict-ssl=false'''
          }
        }
        
        stage('Run npm install') {
          agent none
          steps {
            
            sh '''npm config get registry
    
                npm install'''
            
    
          }
        }
        
        stage('Run build') {
          agent none
          steps {
            sh 'npm run docs:build'
          }
        }
        
        stage('Archive artifacts and Deploy') {
          agent none
          steps {
            
            sh 'zip -r dist.zip dist/'
            
            sshPublisher(publishers: [sshPublisherDesc(configName: "Local", transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand:
            """
            cd /usr/share/nginx/html
            rm -rf blog
            unzip dist.zip
            mv dist blog
            rm -f dist.zip
            nginx -s reload
            """, execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: "/usr/share/nginx/html", remoteDirectorySDF: false, removePrefix: "", sourceFiles: "dist.zip")], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
            
          }
          
          post {
                success {
                    archiveArtifacts 'dist.zip'
                }
          }
        }
    }
}

# jenkins流水线命令执行测试

cp /etc/passwd /etc/passwd.bak 
vim /etc/passwd
# 将 jenkins:x:994:991:Jenkins Automation Server:/var/lib/jenkins:/bin/false 改为 jenkins:x:994:991:Jenkins Automation Server:/var/lib/jenkins:/bin/bash
su - jenkins
echo $PATH
# 执行完后,改回原来的配置

# 配置python+Poetry

  • 安装所需python版本python3.6+,python2.7和python3.5由于不在维护,所以尽量不要安装
  • 由于用于实验的项目,依赖python310,因此使用该版本
#这个必须要执行,参考资料: https://blog.csdn.net/weixin_45858439/article/details/141788483
yum install -y openssl-devel openssl11 openssl11-devel
export CFLAGS=$(pkg-config --cflags openssl11)
export LDFLAGS=$(pkg-config --libs openssl11)

#参考地址: https://blog.csdn.net/Joker_ZJN/article/details/142517558
yum install zlib-devel bzip2-devel opssl-devel ncurses-devel sqlite-devel readline-devel tk-devel libffi-devel
# 速度慢的话,就本地下载好上传
wget https://www.python.org/ftp/python/3.10.14/Python-3.10.14.tgz
tar -xvf Python-3.10.14.tgz
cd Python-3.10.14 && mkdir build && cd build
../configure

# 耗时在3分钟左右
make -j4
make altinstall

mv /usr/bin/python /usr/bin/python.bak
mv /usr/bin/python3 /usr/bin/python3.bak
mv /usr/bin/pip3 /usr/bin/pip3.bak
ln -sf /usr/local/bin/python3.10 /usr/bin/python3
ln -sf /usr/local/bin/python3.10 /usr/bin/python
ln -sf /usr/local/bin/pip3.10 /usr/bin/pip3
ln -sf /usr/local/bin/pip3.10 /usr/bin/pip
  • 安装poetry
# 参考资料: https://www.automannn.cn/blog/language/python.html#windows%E5%AE%89%E8%A3%85poetry
pip install pipx

export PIPX_HOME=/usr/local/pipx
export PIPX_BIN_DIR=/usr/local/bin
pipx install poetry

#之前已经是全局安装了,所有用户都能使用  由于jenkins是非登录使用,因此配置etc/profile,.bashrc等都不行, 必须链接到/usr/bin目录,并且源路径不能有权限限制。 通常放在/usr/local/bin目录下
# jenkins会在 /bin目录下,链接/usr/bin下的所有命令 
ln -sf /usr/local/bin/poetry /usr/bin/poetry
  • 配置gcc8的环境,dify的pyarray需要这个环境(巨坑)
ln -s /bin/gcc /opt/rh/devtoolset-8/root/usr/bin/gcc
#开发工具里面,默认没有包含gcc的lib库,需要去centos8的系统里面搞个过来。centos8的gcc在`/usr/lib64/libgcc_s.so.1`,复制这个链接指向的库文件
# 网上不好找这个库文件,最好不要自己编译耗时太多(2小时以上),不可控因素很多
#注意,上传的库文件必须放到lib64目录下,其他目录链接不过去
mv /usr/lib64/libgcc_s.so.1 /usr/lib64/libgcc_s.so.1.bak
ln -s 上传的库文件 /usr/lib64/libgcc_s.so.1
pipeline {
    agent any

    stages {
        stage('Clone repository') {
          agent none
          steps {
            git(url: 'https://gitee.com/automannn/dify.git', credentialsId: 'gitee',branch: 'main', changelog: true, poll: false)
          }
        }
        stage('poetry install') {
          steps {
            
              sh '''cd api

                cp .env.example .env

                poetry install
    
                '''
          }
        }

        stage('flask stop') {
          steps {
            
              sshPublisher(publishers: [sshPublisherDesc(configName: "Local", transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand:
            """
            cd /var/lib/jenkins/workspace/${JOB_NAME}/api

            sh ./stopflask.sh
            
            """, execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: "/usr/share/nginx/html", remoteDirectorySDF: false, removePrefix: "", sourceFiles: "")], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
 
          }
        }

        stage('flask rerun ') {
          steps {
            
              sshPublisher(publishers: [sshPublisherDesc(configName: "Local", transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand:
            """
            cd /var/lib/jenkins/workspace/${env.JOB_NAME}/api

            nohup poetry run python -m flask run --host 0.0.0.0 --port=5001 --debug >pythonout.log &
            
            """, execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: "/usr/share/nginx/html", remoteDirectorySDF: false, removePrefix: "", sourceFiles: "")], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
 
          }
        }
        
        //不启用外置知识库功能
        // stage('python-tasks') {
        //   agent none
        //   steps {
            
        //     sh '''
        //         cd api
    
        //         poetry run python -m celery -A app.celery worker -P gevent -c 1 --loglevel INFO -Q dataset,generation,mail,ops_trace,app_deletion
        //         '''
            
    
        //   }
        // } 
    }
}