在Ubuntu 22.04上使用GitLab和Jenkins部署CI/CD的完整过程

详细介绍在Ubuntu 22.04上使用GitLab和Jenkins部署CI/CD的完整过程。

环境准备

1. 系统初始化

# 更新系统 sudo apt update && sudo apt upgrade -y # 安装必要工具 sudo apt install -y curl wget git vim

2. 安装Docker(推荐方式)

# 安装Docker sudo apt install -y docker.io docker-compose sudo systemctl enable docker sudo systemctl start docker # 将当前用户添加到docker组 sudo usermod -aG docker $USER

第一部分:GitLab安装与配置

1. 使用Docker安装GitLab

# 创建GitLab数据目录 sudo mkdir -p /srv/gitlab/{config,data,logs} # 创建docker-compose.yml cat > docker-compose-gitlab.yml << 'EOF' version: '3.6' services: gitlab: image: gitlab/gitlab-ce:latest container_name: gitlab restart: always hostname: 'gitlab.example.com' # 修改为您的域名或IP environment: GITLAB_OMNIBUS_CONFIG: | external_url 'http://192.168.1.100' # 修改为您的IP或域名 gitlab_rails['gitlab_shell_ssh_port'] = 2222 gitlab_rails['smtp_enable'] = false gitlab_rails['time_zone'] = 'Asia/Shanghai' ports: - "80:80" - "443:443" - "2222:22" volumes: - /srv/gitlab/config:/etc/gitlab - /srv/gitlab/logs:/var/log/gitlab - /srv/gitlab/data:/var/opt/gitlab networks: - gitlab-network shm_size: '256m' networks: gitlab-network: driver: bridge EOF # 启动GitLab docker-compose -f docker-compose-gitlab.yml up -d

2. 配置GitLab

# 获取初始root密码 sudo docker exec -it gitlab cat /etc/gitlab/initial_root_password # 登录GitLab (http://your-server-ip) # 用户名: root # 密码: 从上述命令获取

第二部分:Jenkins安装与配置

1. 使用Docker安装Jenkins

# 创建Jenkins数据目录 sudo mkdir -p /srv/jenkins_home # 设置目录权限 sudo chown -R 1000:1000 /srv/jenkins_home # 创建docker-compose.yml cat > docker-compose-jenkins.yml << 'EOF' version: '3.7' services: jenkins: image: jenkins/jenkins:lts-jdk17 container_name: jenkins restart: always user: "1000:1000" # 使用非root用户 ports: - "8080:8080" - "50000:50000" volumes: - /srv/jenkins_home:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock - /usr/bin/docker:/usr/bin/docker environment: - JAVA_OPTS=-Djenkins.install.runSetupWizard=false networks: - jenkins-network networks: jenkins-network: driver: bridge EOF # 启动Jenkins docker-compose -f docker-compose-jenkins.yml up -d # 查看初始管理员密码 sudo cat /srv/jenkins_home/secrets/initialAdminPassword

第三部分:案例实战 - Spring Boot应用CI/CD

1. 准备示例项目

# 在GitLab创建新项目 # 项目名称: spring-boot-demo # 可见性: Private # 本地准备Spring Boot项目 mkdir spring-boot-demo && cd spring-boot-demo # 创建项目结构 cat > pom.xml << 'EOF' <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>spring-boot-demo</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.0</version> <relativePath/> </parent> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> EOF # 创建Java源码 mkdir -p src/main/java/com/example/demo cat > src/main/java/com/example/demo/DemoApplication.java << 'EOF' package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class DemoApplication { @GetMapping("/") public String hello() { return "Hello from Spring Boot CI/CD Pipeline!"; } @GetMapping("/health") public String health() { return "Status: UP"; } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } EOF # 创建测试文件 mkdir -p src/test/java/com/example/demo cat > src/test/java/com/example/demo/DemoApplicationTest.java << 'EOF' package com.example.demo; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @SpringBootTest @AutoConfigureMockMvc class DemoApplicationTest { @Autowired private MockMvc mockMvc; @Test void testHelloEndpoint() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/")) .andExpect(status().isOk()) .andExpect(content().string("Hello from Spring Boot CI/CD Pipeline!")); } @Test void testHealthEndpoint() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/health")) .andExpect(status().isOk()) .andExpect(content().string("Status: UP")); } } EOF # 创建Dockerfile cat > Dockerfile << 'EOF' FROM openjdk:17-jdk-slim AS builder WORKDIR /app COPY . . RUN ./mvnw clean package -DskipTests FROM openjdk:17-jre-slim WORKDIR /app COPY --from=builder /app/target/*.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"] EOF # 创建部署脚本 cat > deploy.sh << 'EOF' #!/bin/bash # 部署脚本 set -e APP_NAME="spring-boot-demo" CONTAINER_NAME="spring-boot-app" VERSION=${BUILD_NUMBER:-latest} echo "开始部署版本: $VERSION" # 停止并删除旧容器 docker stop $CONTAINER_NAME || true docker rm $CONTAINER_NAME || true # 运行新容器 docker run -d \ --name $CONTAINER_NAME \ --restart always \ -p 8081:8080 \ -e SPRING_PROFILES_ACTIVE=prod \ $APP_NAME:$VERSION echo "部署完成!" docker ps | grep $CONTAINER_NAME EOF chmod +x deploy.sh # 创建.gitlab-ci.yml cat > .gitlab-ci.yml << 'EOF' stages: - build - test - package - deploy variables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" cache: paths: - .m2/repository/ - target/ build: stage: build image: maven:3.8.6-openjdk-17 script: - mvn clean compile artifacts: paths: - target/ test: stage: test image: maven:3.8.6-openjdk-17 script: - mvn test coverage: '/Total.*?([0-9]{1,3})%/' package: stage: package image: maven:3.8.6-openjdk-17 script: - mvn package -DskipTests artifacts: paths: - target/*.jar deploy: stage: deploy image: docker:latest services: - docker:dind variables: DOCKER_HOST: tcp://docker:2375 DOCKER_DRIVER: overlay2 script: - docker build -t spring-boot-demo:$CI_COMMIT_SHORT_SHA . - docker tag spring-boot-demo:$CI_COMMIT_SHORT_SHA spring-boot-demo:latest - docker run -d -p 8081:8080 --name spring-boot-app spring-boot-demo:latest only: - main environment: name: production url: http://your-server-ip:8081 EOF

2. Jenkins配置

安装必要插件
  1. 访问 Jenkins: http://your-server-ip:8080

  2. 安装插件:

    • GitLab Plugin

    • Pipeline

    • Maven Integration

    • Docker Pipeline

    • Blue Ocean

创建Pipeline任务
  1. 新建Item→ 选择Pipeline

  2. 配置:

    • Pipeline: Pipeline script from SCM

    • SCM: Git

    • Repository URL: http://gitlab-server/root/spring-boot-demo.git

    • Credentials: 添加GitLab凭据

    • Branch Specifier: */main

    • Script Path: Jenkinsfile

  3. 创建Jenkinsfile(在项目根目录)

groovy

pipeline { agent any tools { maven 'Maven-3.8' jdk 'JDK-17' } stages { stage('Checkout') { steps { git branch: 'main', url: 'http://gitlab-server/root/spring-boot-demo.git', credentialsId: 'gitlab-credentials' } } stage('Build') { steps { sh 'mvn clean compile' } } stage('Unit Test') { steps { sh 'mvn test' } post { always { junit 'target/surefire-reports/*.xml' } } } stage('Code Analysis') { steps { sh 'mvn checkstyle:checkstyle pmd:pmd' } } stage('Package') { steps { sh 'mvn package -DskipTests' } post { success { archiveArtifacts 'target/*.jar' } } } stage('Build Docker Image') { steps { script { docker.build("spring-boot-demo:${env.BUILD_ID}") } } } stage('Deploy to Test') { steps { sh ''' docker stop spring-boot-test || true docker rm spring-boot-test || true docker run -d --name spring-boot-test -p 8082:8080 spring-boot-demo:${BUILD_ID} ''' } } stage('Integration Test') { steps { sh ''' sleep 10 # 等待应用启动 curl -f http://localhost:8082/health || exit 1 ''' } } stage('Deploy to Production') { when { branch 'main' } steps { sh ''' docker tag spring-boot-demo:${BUILD_ID} spring-boot-demo:latest docker stop spring-boot-prod || true docker rm spring-boot-prod || true docker run -d --name spring-boot-prod -p 8081:8080 --restart always spring-boot-demo:latest ''' } } } post { success { emailext ( subject: "构建成功: ${env.JOB_NAME} - ${env.BUILD_NUMBER}", body: "项目构建成功,请访问: http://your-server-ip:8081", to: 'admin@example.com' ) } failure { emailext ( subject: "构建失败: ${env.JOB_NAME} - ${env.BUILD_NUMBER}", body: "项目构建失败,请检查日志", to: 'admin@example.com' ) } } }

3. GitLab Webhook配置

  1. 在GitLab项目中

    • Settings → Webhooks

    • URL: http://jenkins-server:8080/project/spring-boot-demo

    • Secret Token: (生成并复制)

  2. 在Jenkins中

    • 项目配置 → Build Triggers

    • 勾选 "Build when a change is pushed to GitLab"

    • 添加Secret Token (与GitLab中相同)

第四部分:CI/CD流程测试

1. 推送代码触发构建

# 初始化Git仓库 git init git add . git commit -m "Initial commit" git remote add origin http://gitlab-server/root/spring-boot-demo.git git push -u origin main

2. 监控流程

# 查看Jenkins构建日志 docker logs -f jenkins # 查看应用运行状态 docker ps # 测试应用 curl http://localhost:8081 curl http://localhost:8081/health

第五部分:高级配置

1. 配置Slack通知

# Jenkins安装Slack Notification插件 # Jenkinsfile中添加 post { success { slackSend( color: 'good', message: "构建成功: ${env.JOB_NAME} - ${env.BUILD_NUMBER}" ) } failure { slackSend( color: 'danger', message: "构建失败: ${env.JOB_NAME} - ${env.BUILD_NUMBER}" ) } }

2. 配置SonarQube代码质量检查

groovy

stage('SonarQube Analysis') { steps { withSonarQubeEnv('sonarqube-server') { sh 'mvn sonar:sonar' } } }

3. 使用Kubernetes部署

yaml

# 创建k8s部署文件 deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: spring-boot-app spec: replicas: 3 selector: matchLabels: app: spring-boot-app template: metadata: labels: app: spring-boot-app spec: containers: - name: spring-boot-app image: spring-boot-demo:latest ports: - containerPort: 8080

故障排除

常见问题解决

# 1. Jenkins无法连接GitLab # 检查网络连通性 docker network ls docker network connect gitlab-network jenkins # 2. Maven构建缓慢 # 配置阿里云镜像 mkdir -p ~/.m2 cat > ~/.m2/settings.xml << 'EOF' <settings> <mirrors> <mirror> <id>aliyun</id> <name>Aliyun Maven Mirror</name> <url>https://maven.aliyun.com/repository/public</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors> </settings> EOF # 3. Docker权限问题 sudo chmod 666 /var/run/docker.sock # 4. 查看日志 docker logs gitlab docker logs jenkins journalctl -u docker --follow

这个完整的CI/CD案例包含了从环境搭建到自动化部署的全过程,可以根据实际需求进行调整和扩展。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1164603.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷歌云与国内云,我用亲身踩坑经历告诉你到底该怎么选

作为一名在云计算行业摸爬滚打了近十年的老运维&#xff0c;我几乎把所有主流的云服务商都用了个遍。从最早的自己攒服务器托管到IDC机房&#xff0c;再到后来全面上云&#xff0c;我可以说是一路踩着坑过来的。特别是最近几年&#xff0c;团队业务开始走向全球化&#xff0c;我…

领航技术股份-干接点水浸传感器

领航技术股份-干接点水浸传感器是工业与安防场景中最常用的漏液监测设备&#xff0c;核心特点是通过 干接点&#xff08;无源开关&#xff09;信号 输出报警状态&#xff0c;无需额外供电即可传输信号&#xff0c;适配各类 PLC、安防主机、动环监控系统&#xff0c;兼容性极强。…

什么是粗排和精排

在 RAG、推荐系统、搜索引擎等场景中&#xff0c;粗排&#xff08;Coarse-grained Ranking&#xff09; 和 精排&#xff08;Fine-grained Ranking&#xff09; 是一套 **“先海选、再精选”** 的两级检索排序策略&#xff0c;核心目的是在保证检索效率的前提下&#xff0c;大幅…

Google Ads花钱没单?9大常见设置错误与修复指南

在数字广告投放中&#xff0c;Google Ads 一直是流量变现和品牌推广的重要渠道。但对于许多广告主和运营人员来说&#xff0c;账户的设置问题往往比创意和预算更致命。一个看似小小的参数配置错误&#xff0c;就可能导致广告无法触达目标人群、预算被快速消耗&#xff0c;甚至账…

全国冠军代言资源平台排名

【标题】&#xff1a;体育冠军代言哪家好&#xff1a;专业深度测评&#xff0c;排名前五揭晓【开篇】&#xff1a;随着体育产业的蓬勃发展&#xff0c;体育冠军代言成为品牌宣传的重要手段。为了帮助消费者更好地了解市场上的冠军代言资源平台&#xff0c;我们特此进行了深度测…

EasyGBS算法算力平台在智慧安防视频监控中的应用实践

在数字化、智能化浪潮席卷全球的今天&#xff0c;传统安防体系正经历着深刻的变革。随着GB28181国家标准的全面推广和实施&#xff0c;视频监控系统的标准化、网络化、智能化已成为智慧安防建设的必然要求。EasyGBS作为GB28181的算法算力平台&#xff0c;不仅解决了海量视频资源…

大模型强化学习训练全攻略:从RLHF到RLVR,算法、框架与性能优化详解

文章解析了大模型从预训练到后训练的转变&#xff0c;重点介绍强化学习(RL)在大模型中的应用。详细阐述了SFT、RLHF和RLVR三大训练阶段&#xff0c;PPO和GRPO等核心算法&#xff0c;以及RL训练面临的基础设施挑战&#xff0c;特别是混合负载问题。同时介绍了字节跳动的verl框架…

领航技术股份-水浸传感器哪家好

领航技术股份-选水浸传感器&#xff0c;家用看智能联动与性价比&#xff0c;工业级看稳定性、干接点 / 通讯适配及场景防护&#xff0c;以下是分场景的优质品牌与选型建议&#xff0c;兼顾国产与进口&#xff0c;覆盖主流需求。领航技术股份一、家用 / 智能家居场景&#xff08…

EasyGBS智能化视频监控助力企业安全运营

在商业快速扩张的背景下&#xff0c;连锁店门店数量激增&#xff0c;分布范围广。但传统人工巡检等管理方式效率低下&#xff0c;存在信息滞后、管理盲区&#xff0c;难以掌握店铺运营情况&#xff0c;影响企业效率与安全。作为一体化智能视频监控的国标GB28181算法算力平台Eas…

靠谱的厌氧池清淤哪家妙

《厌氧池清淤哪家好&#xff1a;专业深度测评排名前五》开篇&#xff1a;定下基调随着环保要求的不断提高和污水处理设施的持续建设&#xff0c;厌氧池清淤作为污水处理过程中的关键环节&#xff0c;其专业性和高效性日益受到重视。本次测评旨在为广大企业和环保单位提供一份客…

WHAT - Vercel react-best-practices 系列(一)

文章目录 前言 Guidelines Critical Patterns 1. Eliminate Waterfalls(消灭瀑布流) Defer await until needed 核心问题 反例:无论是否需要,先 await 推荐:await 放进条件分支 典型业务场景 本质总结 Use Promise.all for independent async operations 核心问题 反例:人…

数据合规律师必考七大证书:全面提升职场竞争力

在企业的数字化转型浪潮中&#xff0c;数据合规已成为法律人不可忽视的业务蓝海。随着《数据安全法》《个人信息保护法》等法规的深入实施&#xff0c;数据合规人才需求爆发性增长&#xff0c;具备专业资质的法律人才薪资平均比普通法务高出400%。一、CISP&#xff08;注册信息…

AI大模型全景指南,从小白到程序员的完全学习手册

AI大模型作为新一代人工智能核心驱动力&#xff0c;已进入应用与智能体时代。产业链分为基础层&#xff08;算力、数据、算法、云服务&#xff09;、模型层&#xff08;通用/行业大模型、MaaS&#xff09;和应用层&#xff08;To B/C场景&#xff09;&#xff0c;配以支撑服务提…

救命!挖到就业黄金赛道!2025 网安缺口 327 万,零基础入门到精通,收藏即通关!

《信息安全毕业主推的6大岗位&#xff08;2025真实版&#xff09;》 **关于我&#xff1a;资深IT专家&#xff0c;AI布道者&#xff0c;15年实战老兵多本专业图书作者大厂技术面试官。 ** 根据2024年官方公布的数据显示,到2027年我国网络安全人员缺口将达327万。 尽管全国已有6…

携手订单日记,圣力树开启智能升级之路

一、客户背景 惠州圣力树工艺品有限公司&#xff0c;成立于2016年&#xff0c;位于广东省惠州市惠阳区&#xff0c;是一家以从事销售圣诞制品、工艺品等产品为主的企业。 在业务不断壮大的过程中&#xff0c;面临生产效率低、统计数据麻烦等问题&#xff0c;需要一种既能提升运…

国家战略急需!网安工程师年薪真能过百万?好不好入行一篇说透!

针对时下大火的“网络安全工程师”,网络出现不少相关报导和信息: 下面就来跟大家分享一下网络安全工程师工资待遇&#xff0c;给大家作为一个参考。 不同工作经验的待遇水平 其中应届生工资&#xffe5;6070&#xff0c;1-3年工资&#xffe5;8820&#xff0c;3-5年工资&…

基于社区宠物管理

基于社区的宠物管理系统设计与实现 第一章 系统整体架构设计 基于社区的宠物管理系统以“规范饲养、安全保障、邻里和谐”为核心目标&#xff0c;采用“前端交互-后端服务-数据管理”三层架构。系统核心包含五大功能模块&#xff1a;宠物档案管理模块、免疫接种模块、社区活动模…

8个降AI率工具推荐!研究生高效降AIGC神器合集

8个降AI率工具推荐&#xff01;研究生高效降AIGC神器合集 AI降重工具&#xff1a;论文优化的高效助手 在当今学术研究日益依赖人工智能辅助写作的背景下&#xff0c;如何有效降低AIGC率、去除AI痕迹并保持论文的原创性&#xff0c;成为研究生们必须面对的挑战。随着各大高校对A…

基于ASP.NET及HTML的高校官网设计

基于ASP.NET及HTML的高校官网设计 第一章 系统整体架构设计 基于ASP.NET及HTML的高校官网以“信息公开、服务师生、塑造形象”为核心目标&#xff0c;采用“表现层-业务逻辑层-数据访问层”三层架构。系统核心包含六大功能模块&#xff1a;首页展示模块、学校概况模块、教学科研…

网安冰火两重天:480 万缺口下,裁员潮 + 一线饱和 + 二三线降薪 30%,核心缺高端实战人才!

上海网络安全人才的就业格局&#xff1a;高端人才争夺激烈但门槛高&#xff0c;基础岗位门槛降低且同质化加剧&#xff0c;安全威胁复杂化与合规压力同步攀升。 2025年上海网络安全岗位招聘量为1853个&#xff0c;较2023年增长8%。行业集中于互联网&#xff08;31%&#xff09;…