安装

1、由于 Jenkins 是基于 Java 的,首先需要确保你的系统中安装了 Java。推荐使用 OpenJDK 11。可以通过以下命令安装:

apt update
apt install openjdk-11-jdk

2、在安装 Jenkins 之前,你需要将其仓库添加到你的系统中。首先,导入 Jenkins 仓库的密钥:

wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -

3、然后,将 Jenkins 仓库添加到系统的软件源列表:

sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'

4、安装jenkins

apt update
apt-get install jenkins

5、配置清华源
image
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

6、安装中文插件
Localization: Chines
安装后需要重启
systemctl restart jenkins

配置jenkins

1、安装Git、Git client插件、Docker Pipeline、Pipeline、Blue Ocean、Pipeline: Stage View、user build vars
Pipeline: Stage View这个插件我很推荐,感觉比Blue好用
user build vars pipline调用内置变量,用户名和分支较为常用
2、生成公钥免密拉取代码

# 运行jenkins的用户执行
ssh-keygen -t rsa -b 4096 -C "baga@baga.com"
公钥添加到jenkins用户中
私钥添加到jenkins凭据中

3、测试jenkins

运行jenkins的用户执行
$ ssh -p 2222 git@192.168.31.20
PTY allocation request failed on channel 0
Welcome to GitLab, @jenkins!
# 到这里基本可以确定jenkins ssh gitlab没问题

4、添加凭据,选择ssh用户名和私钥
image

5、选择凭据登录git仓库
image

6、修改jenkins目录

# 启动脚本必须修改
vim /lib/systemd/system/jenkins.service
Environment="JENKINS_HOME=/data/jenkins"
WorkingDirectory=/data/jenkins
vim /etc/default/jenkins
JENKINS_HOME=/data/$NAME
# 拷贝文件
rsync -avzh /var/lib/jenkins/ /data/jenkins/
# 然后重启jenkins

jenkins DOCKERFILE

文件/data/Dockerfile-tmp,给容器一个基础的Dockerfile去构建镜像

FROM golang:1.19-alpine AS builder
WORKDIR /app
# 设置代理
ENV HTTP_PROXY http://192.168.31.115:1070
ENV HTTPS_PROXY http://192.168.31.115:1070
COPY . /app
# 只有当 go.mod 不存在时才初始化模块
RUN if [ ! -f go.mod ]; then go mod init yourmodule.com/m; fi
RUN go mod tidy
# 构建应用程序
RUN go build -o {{APP_NAME}}

# 使用 alpine 镜像作为运行环境
FROM alpine:latest

# 设置工作目录
WORKDIR /app

# 从构建器镜像中复制编译好的应用程序
COPY --from=builder /app/{{APP_NAME}} .

# 暴露端口
EXPOSE 8080

# 设置启动命令
CMD ["./{{APP_NAME}}"]

pipline测试

控制台可以看到构建人和分支
image

由于是jenkins用户运行的jenkins服务,所以需要用jenkins用户去docker login baga仓库,这样pipeline中就不需要再配置用户名密码了

pipeline {
    agent any  // 在任何可用的代理上运行

    environment {
        APP_NAME = "${env.JOB_NAME}"  // 应用名称设置为当前 Jenkins 作业的名称
        GIT_REPO = "ssh://git@192.168.31.20:2222/root/${APP_NAME}.git"  // Git 仓库地址
        STAGE_SUCCESS = "true"  // 跟踪整个 Pipeline 的成功状态
        IMAGE_TAG = "${APP_NAME}:${sh(returnStdout: true, script: 'date +%Y%m%d-%H%M').trim()}"  // 创建镜像标签,包含日期和时间
        SKIP_PUSH = "false"  // 动态控制是否推送镜像到仓库
        CONTAINER_PORT = "8080"  // 定义容器端口
        HOST_PORT = "8888"  // 定义宿主机映射端口
        PUSH_URL = "harbor.baga.live/base"  // 推送的仓库URL
    }

    stages {
        stage('Setup') {
            steps {
                script {
                    // 使用插件提供的变量设置构建描述
                    wrap([$class: 'BuildUser']) {
                        env.BUILD_USER_ID_SAFE = BUILD_USER_ID
                        currentBuild.displayName = "Build #${BUILD_NUMBER} by ${BUILD_USER_ID}"
                        currentBuild.description = "Initiated by ${BUILD_USER_ID} on branch ${BRANCH}"
                        echo "Build initiated by ${BUILD_USER_ID} on ${BRANCH}"
                    }
                }
            }
        }
        stage('Clean Workspace') {  // 清理工作区阶段
            steps {
                deleteDir()  // 删除工作目录中的所有文件
            }
            post {
                failure { script { env.STAGE_SUCCESS = "false" } }  // 如果失败,更新 STAGE_SUCCESS 环境变量
            }
        }
        stage('Prepare Environment') {  // 准备环境阶段
            steps {
                script { echo "IMAGE_TAG: ${env.IMAGE_TAG}" }  // 输出当前的镜像标签
            }
            post {
                failure { script { env.STAGE_SUCCESS = "false" } }  // 如果失败,更新 STAGE_SUCCESS 环境变量
            }
        }
        stage('拉取代码') {  // 拉取代码阶段
            steps {
                script {
                    checkout scm: [
                        $class: 'GitSCM',
                        branches: [[name: "${BRANCH}"]],
                        userRemoteConfigs: [[url: "${env.GIT_REPO}"]]
                    ]
                }
            }
            post {
                failure { script { env.STAGE_SUCCESS = "false" } }  // 如果失败,更新 STAGE_SUCCESS 环境变量
            }
        }
        stage('Prepare Dockerfile') {  // 准备 Dockerfile 阶段
            steps {
                sh "sed 's/{{APP_NAME}}/${APP_NAME}/g' /data/Dockerfile-tmp > Dockerfile"
            }
            post {
                failure { script { env.STAGE_SUCCESS = "false" } }  // 如果失败,更新 STAGE_SUCCESS 环境变量
            }
        }
        stage('构建镜像') {  // 构建镜像阶段
            steps {
                script { docker.build("${env.IMAGE_TAG}") }  // 使用 Docker 插件构建镜像
            }
            post {
                failure { script { env.STAGE_SUCCESS = "false" } }  // 如果失败,更新 STAGE_SUCCESS 环境变量
            }
        }
        stage('推送镜像') {
            when { expression { env.STAGE_SUCCESS == "true" && env.SKIP_PUSH == "false" } }
            steps {
                script {
                    sh "docker tag ${IMAGE_TAG} ${PUSH_URL}/${IMAGE_TAG}"
                    sh "docker push ${PUSH_URL}/${IMAGE_TAG}"
                }
            }
            post {
                success {
                    echo "Image pushed successfully to ${PUSH_URL}/${IMAGE_TAG}"
                }
                failure {
                    script { env.STAGE_SUCCESS = "false" }
                    echo "Failed to push the image to ${PUSH_URL}/${IMAGE_TAG}"
                }
            }
        }
        stage('部署测试') {  // 部署测试阶段
            steps {
                sh "docker run -d -p ${HOST_PORT}:${CONTAINER_PORT} --name ${APP_NAME} ${IMAGE_TAG}"
            }
        }
    }
    post {
        always {
            script {
                def buildStatus = (currentBuild.currentResult == 'SUCCESS') ? '成功' : '失败'
                sh "/bin/bash /data/ops/send_lark.sh 'Production' '${JOB_NAME}' '${BRANCH}' '${env.BUILD_USER_ID_SAFE}' '${buildStatus}' '${env.BUILD_URL}'"
            }
        }
    }
}