GitLab CI-CD 学习笔记
概述
1. CI/CD
CI(持续集成)指开发人员一天内进行多次合并和提交代码操作,并通过自动化测试,完成构建
CD(持续部署)指每次代码更改都会自动部署到对应环境
CI/CD 结合在一起,可以加快开发团队交付成果的效率,减少时间成本
2. Gitlab-CI/CD
gitlab-ci 是 gitlab8.0 之后自带的一个持续集成系统,中心思想是每一次 push 到 gitlab 就会触发一次脚本执行,脚本内容包括测试、编译、部署等一系列内容
gitlab-ci 的脚本需要 gitlab-runner 来执行,代码 push 之后,webhook 检查到代码变化,就会触发 gitlab-ci,分配到各个 Runner 来运行相应的脚本
gitlab-ce
1. 安装 gitlab-ce
gitlab 有 ce 和 ee 两个版本,ce 是社区版,开源免费,ee 是企业版,需要付费
下面以 Ubuntu18.04.6 为例,安装 gitlab-ce
安装依赖软件
sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates tzdata perl
添加 gitlab 软件源镜像
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
安装 gitlab-ce
sudo apt-get install gitlab-ce
如果命令行能看到 Gitlab 的 Logo 打印,就说明安装成功了
打开 gitlab 配置文件
vim /etc/gitlab/gitlab.rb
为了能在浏览器访问 gitlab,还需要配置 gitlab 的访问地址和端口
# ip:port 改成自己的,也可以用域名
external_url 'http://192.168.66.100:82'
重载配置并重启
gitlab-ctl recofigure
gitlab-ctl restart
在浏览器输入 http://192.168.66.100:82 即可访问 gitlab,当然了,前提是你的端口要放开

初始用户名为 root,初始密码记录在 /etc/gitlab/initial_root_password 文件,密码有效期为 24 小时,建议登录后尽快修改密码
登录以后,就可以创建项目了,其余的基本的 git 操作这里就不赘述了
2. 其他问题
gitlab-ctl recofigure 过程,有可能出现卡在 ruby_block[wait for logrotate service socket] action run 的情况,解决办法如下:
-
ctrl + c 强行结束
-
运行
systemctl restart gitlab-runsvdir -
再次运行
gitlab-ctl recofigure
安装结束以后,访问 web 端报 502,最可能的原因是端口被占用了,需要修改端口
vim /etc/gitlab/gitlab.rb
# 修改为没有被使用的端口即可
puma['port'] = 9091
gitlab-runner
1. 安装 gitlab-runner
下面以 Ubuntu18.04.6 为例,安装 gitlab-runner
添加 gitlab 软件源镜像
curl https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
安装 gitlab-runner
sudo apt-get install gitlab-runner
2. gitlab-runner 注册
首先获取 gitlab-ci 的 token:项目主页->Setting->CI/CD->Runners Expand

使用命令注册 gitlab-runner
gitlab-runner register
按照步骤输入:
- GitLab instance URL:如上图所示 URL
- registration token:如上图所示 Token
- description:关于该 Runner 的描述
- tags:用于标记该 Runner,后续需要使用这个 tag 来指定 gitlab-runner
- optional maintenance note:没搞懂有啥用,随意写
- Enter an executor:选择执行器,gitlab-runner 提供了许多执行器,可用在不同场景中运行构建,这里选择 shell
完成以后,刷新页面,即可在 Runners Expand 看到新增了一个 Runner

3. 简单示例
下面我们简单测试一下 Runner 是否能正常运行,随意新建一个 SpringBoot 项目

在根目录下创建一个 .gitlab-ci.yml 文件,这里只是简单输出一段语句
stages:- deploydeploy-job:tags:- prodstage: deployscript:- echo "hello world!!!"
push 到 gitlab 后,会发现脚本已经自动执行了,绿勾代表执行成功

点击绿勾,在下方 Pipeline 点击 deploy-job 可以查看执行过程


pipeline 语法
1. job & script
.gitlab-ci.yml 文件中可以定义一个或多个作业(job),每个作业独立执行,必须有唯一的名称(不能使用关键字)以及包含一个 script,这里定义了三个作业 build、test、deploy,script 可以是 shell 命令
build:script: - echo "build"
test:script: - echo "test"
deploy:script: - echo "deploy"- echo "finish"
2. before_script & after_script
before_script 用于定义一个命令,在每个作业运行之前运行,before_script 失败将导致整个作业失败,其他作业不再执行,如果在作业中定义了 before_script,则该作业不会运行全局的 before_script
after_script 用于定义一个命令,在每个作业运行之后运行,作业失败不影响 after_script 的运行,如果在作业中定义了 after_script,则该作业不会运行全局的 after_script
before_script:- echo "before script"
build:before_script: - echo "before script in buildjob"script: - echo "build"after_script:- echo "before script in buildjob"
test:script: - echo "test"
deploy:script: - echo "deploy"- echo "finish"after_script:- echo "after script"
3. stages & stage
用于定义作业可以使用的阶段,并且是全局定义的,同一阶段的作业并行运行,不同阶段按顺序执行
before_script:- echo "before script"stages:- build- test- deploybuild:before_script: - echo "before script in buildjob"stage: buildscript: - echo "build"after_script:- echo "before script in buildjob"
test:stage: testscript: - echo "test"deploy:stage: deployscript: - echo "deploy"- sleep 5after_script:- echo "after script"
4. .pre & .post
.pre 始终是整个 pipeline 的第一个运行阶段,.post 始终是整个 pipeline 的最后一个运行阶段,无法修改,用户自定义的 stage 则在这两者之间,如果一个 pipeline 仅包含 .pre 和 .post,则不会创建 pipeline
before_script:- echo "before script"stages:- build- test- deploycodescan:stage: .prescript: - echo "codescan"build:before_script: - echo "before script in buildjob"stage: buildscript: - echo "build"after_script:- echo "before script in buildjob"
test:stage: testscript: - echo "test"deploy:stage: deployscript: - echo "deploy"- sleep 5after_script:- echo "after script"
5. variables
定义变量,可以定义 pipeline 变量、job 变量,job 变量优先级最高
before_script:- echo "before script"variables:DOMAIN: example.comstages:- build- test- deploycodescan:stage: .prescript: - echo "codescan"build:before_script: - echo "before script in buildjob"stage: buildscript: - echo "build"- echo "$DOMAIN"after_script:- echo "before script in buildjob"
test:stage: testscript: - echo "test"deploy:stage: deployscript: - echo "deploy"- sleep 5after_script:- echo "after script"
6. tags
用于指定特定的 job 在特定的 runner 运行,如果 job 不指定 tags,则默认在共享的 runner 运行
windows_job:stages: - buildtags:-windowsscript:- echo "windows job"linux_job:stages: - buildtags:-linuxscript:- echo "linux job"
7. allow_failure
allow_failure 表示是否允许作业失败,默认值 false 不允许失败,改为 true 后,如果该作业失败也不会被阻塞
job1:stage: testscript: - "..."allow_failure: true
8. when
when 用于控制作业运行:
- on_success:前面阶段的所有作业成功才执行该作业,默认 on_success
- on_failure:前面阶段出现失败时执行
- always:总是执行作业
- manual:手动执行作业
- delayed:延迟执行作业
job1:stage: testscript: - "..."when: delayed # 表示延迟30s执行start_in: "30"
9. retry
配置作业失败后重试作业的次数
job1:stage: testscript: - "..."retry: 2
也可以精确匹配到某一错误,即出现某一错误时才重试
job1:stage: testscript: - "..."retry: max: 2when: - script_failure # 脚本失败时重试
10. timeout
作业级别的超时可以超过项目级别的超时,但不能超过 Runner 特定的超时
job1:stage: testscript: - "..."timeout: 3h
11. parallel
配置要并行运行的作业的实例数,此值必须大于等于 2 并小于等于 50,这将创建 N 个并行运行的同一作业实例
job1:stage: testscript: - "..."parallel: 5
12. rules
rules 允许按顺序评估单个规则,直到匹配为止:
-
if:如果条件匹配,多条件匹配可以使用 && ||
variables:DOMAIN: example.comjob1:stage: testscript: - "..."rules: # DOMAIN值匹配,则手动运行,否则- if: '$DOMAIN == "example.com"'when: manual- if: '$DOMAIN == "example2.com"'when: delayedstart_in: '5'- when: on_success -
changes:指定文件发生变化
job1:stage: testscript: - "..."rules:- changes: - fimeName # 文件名when: manual- when: on_success -
exists:指定文件存在
job1:stage: testscript: - "..."rules:- exists: - fimeName # 文件名when: manual- when: on_success
13. workflow-rules
workfolw 关键字适用于整个管道,并确定是否创建管道
variables:DOMAIN: example.comworkflow:rules:- if: '$DOMAIN == "example.com"'when: always # 默认always,可以设置never- when: never
14. cache
存储编译项目时所需的运行时依赖项,指定项目工作空间中需要在 job 之间缓存的文件或目录
全局 cache 定义在 job 之外,针对所有 job 生效,job 中的 cache 优于全局
cache:paths: # 在全局定义缓存- my/filesjob:script: "..."cache:key: job # 为缓存设置唯一key,会为该job分配一个独立的cachepaths: # 在job中定义缓存,缓存target目录下的所有.jar文件,该缓存将覆盖全局缓存- target/*.jar# policy: pull # pull:不下载缓存,push不上传缓存,默认会在job执行之前下载缓存,并在结束之后上传缓存
15. artifacts
用于指定作业成功或失败时应附加到作业的文件或目录的列表,可在 Gitlab UI 中下载
build:script:- mvn packageartifacts:name: "$ARTIFACTS_NAME" # 指定所创建的制品名称,默认为artifacts,下载为artifacts.zippaths:- target/*.jarwhen: always # 制品创建条件,on_success:作业成功时创造制品,on_failure:作业失败时创建制品,always:总是创建制品expire_in: 1 week # 制品有效期,从存储到gitlab开始算起,默认30天
16. dependencies
获取当前阶段之前的制品
build:stage: buildscript:- mvn packageartifacts:name "$ARTIFACTS_NAME"paths: - target/*.jardeploy:dependencies:- buildstage: deployscript: - ... # 部署制品
17. needs
可以让作业无需按照阶段顺序运行,下述的例子表示:deploy-a 在 build-a 完成之后就可以执行,deploy-b 在 build-b 完成之后就可以执行
stages:- build- deploybuild-a:stage: buildscript: - ...build-b:stage: buildscript: - ...deploy-a:stage: deployscript:- ...needs: ["build-a"]deploy-b:stage: deployscript:- ...needs: ["build-b"]
18. include
可以引入外部 yaml 文件,使用合并功能可以自定义和覆盖本地定义的 CI/CD 配置
local
引入同一存储库的文件,使用相对于根目录的完整路径进行引用,必须保证走到同一分支
假设有 ci/localci.yml 文件
stages:- deploydeploy-job:stage: deployscript: ...
在 .gitlab-ci.yml 引入 ci/localci.yml 文件,如果存在相同名称的作业,它们的配置会进行合并,并且原文件 .gitlab-ci.yml 的配置优先生效
include:local: "ci/localci.yaml"stages:- build- test- deploybuild-job:stage: buildscript: ...test-job:stage: testscript: ...
file
引入其他项目的 yaml 配置
include:project: demo/demo-java-serviceref: masterfile: .gitlab-ci.yml
template
引入官方提供的模板,可以访问 https://gitlab.com/gitlab-org/gitlab/tree/master/lib/gitlab/ci/templates 查看有哪些模板
include:template: Auto-DevOps.gitlab-ci.yml
remote
引入远程文件
include:remote: "https://gitlab.com/awesome-project/raw/master/.gitlab-ci-template.yml"
19. extends
继承作业配置,相同配置覆盖,不同则继承
.tests:script: mvn teststage: testonly:refs:- tagstest-job:extends: .testsscript: mvn clean testonly:variables:- $RSPEC
最终得到的作业配置如下
test-job:stage: testscript: mvn clean testonly:variables:- $RSPECrefs:- tags
20. trigger
当 gitlab 从 trigger 定义创建的作业启动时,将创建一个下游管道,允许创建多项目管道和子管道:
-
多项目管道:跨多个项目设置流水线,以便一个项目的管道可以触发另一个项目的管道
stagging:variables:ENVIROMENT: stagging # 该变量会传递给下游管道,如果上下游定义了相同名称的变量,上游变量将优先stage: deploytrigger:project: demo/demo-java-service # 指定下游项目的完整路径branch: master # 指定项目的分支名称strategy: depend # 将自身状态从触发的管道合并到源作业 -
父子管道:同一项目的管道可以触发一组同时运行的子管道
子管道 ci/child.yml
stages:- buildchild-build-job:stage: buildscript: ...父管道
stages:- deploystagging:stage: deploytrigger:include: ci/child.ymlstrategy: depend21
21. image
首先注册一个工作类型为 docker 的 runner,只要使用该类型的 runner,所有运行操作都会在容器中运行
gitlab-runner register \--non-interactive \--executor "docker" \--docker-image alpine:latest \ # 默认使用该镜像--url "http://192.168.1.200:30088/" \--registration-token "JRzzw2j1Ji6aBjwvkxAv" \--description "docker-runner" \--tag-list "docker" \--run-untagged="true" \--locked="false" \--access-level="not_protected"
默认注册 runner 会指定一个基础镜像,如果全局指定 image 则所有作业使用该镜像创建容器并运行,如果全局未指定 image,则查看 job 中是否有指定,有则按照 job 指定的镜像创建容器并运行,否则使用默认镜像
image: maven:3.6.3-jdk-8 # 全局定义...deploy-job:stage: deploytags:- dockerscript: ...image: maven:3.6.3-jdk-8 # 局部定义
22. services
工作期间运行的另一个 Docker 服务镜像,将其 link 到 image 定义的 Docker 镜像,这样可以在构建期间访问该服务镜像
...services:- name: mysql:latestalias: mysqlbuild-job:stage: buildtags:- dockerscript: ...image: maven:3.6.3-jdk-8 # 局部定义
23. environment
可用于在 gitlab ui 追踪作业运行情况,
deploy-job:stage: deploytags:- dockerscript: ...environment:name: production # 应用名称url: http://www.baidu.com # 应用地址
相关文章:
GitLab CI-CD 学习笔记
概述 1. CI/CD CI(持续集成)指开发人员一天内进行多次合并和提交代码操作,并通过自动化测试,完成构建 CD(持续部署)指每次代码更改都会自动部署到对应环境 CI/CD 结合在一起,可以加快开发团…...
K8S安装
1.创建三台centos虚拟机 使用的官方最小镜像安装 CentOS-7-x86_64-Minimal-1804.iso 建议最小硬件配置:2核CPU、2G内存、20G硬盘 master配置详情 node1和node2配置详情 三台虚拟机在安装centos的时候在网络IPV4指定DHCP,配置IPV4固定地址,保证可以访问…...
【C++】模板初阶STL简介
今天,你内卷了吗? 文章目录一、泛型编程二、函数模板(显示实例化和隐式实例化)1.函数模板格式2.单参数模板3.多参数模板4.模板参数的匹配原则三、类模板(没有推演的时机,统一显示实例化)1.类模…...
备战蓝桥杯第一天【二分查找无bug版】
🌹作者:云小逸 📝个人主页:云小逸的主页 📝Github:云小逸的Github 🤟motto:要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前…...
Java集合中的Map
MapMap接口键 值 对存储键不能重复,值可以重复Map三个实现类的存储结构HashMap:Hash表链表红黑树结构 线程不安全TreeMap: 底层红黑树实现HashTable:hash表链表红黑树 线程安全HashMapHashMap常用方法HashMap<String,String>…...
【java】springboot项目启动数据加载内存中的三种方法
文章目录一、前言二、加载方式2.1、 第一种:使用PostConstruct注解(properties/yaml文件)。2.2、 第二种:使用Order注解和CommandLineRunner接口。2.3、 第三种:使用Order注解和ApplicationRunner接口。三、代码示例3.…...
【GO】29.go-gin支持ssl/tls,即https示例
本文为演示采用自签名证书一.生成证书通过openssl工具生成证书1.1 安装opensslmacos通过brew安装brew install openssl1.2 生成跟证书私钥openssl genrsa -out ca.key 40961.3 准备配置文件vim ca.conf内容如下[ req ] default_bits 4096 distinguished_name req_disti…...
逻辑仿真工具VCS的使用-Makefile
Gvim写RTL code,VCS仿真,Verdi看波形,DC做综合下约束,Primetime做STA,Spyglass做异步时序分析。 VCS全称Verilog Computer Simulation ,VCS是逻辑仿真EDA工具的编译源代码的命令。要用VCS做编译仿…...
信息系统安全技术
一、信息安全的有关概念 1. 属性2. 四个安全层次※3. 信息安全保护等级※4. 安全保护能力的等级※ 二、信息加密、解密与常用算法 1. 对称加密2. 非对称加密3. Hash函数4. 数字签名5. 认证 三、信息系统安全 1. 计算机设备安全2. 网络安全3. 操作系统安全4. 数据库安全5. 应用系…...
【数据结构】最小生成树(Prim算法,普里姆算法,普利姆)、最短路径(Dijkstra算法,迪杰斯特拉算法,单源最短路径)
文章目录前置问题问题解答一、基础概念:最小生成树的定义和性质(1)最小生成树(Minimal Spanning Tree)的定义(2)最小生成树(MST)的性质二、如何利用MST性质寻找最小生成树…...
Session与Cookie的区别(一)
从我刚开始学程序时这一题就常出现在面试考题里,一直到现在都还是能看见这个问题。 这个问题重要吗?我觉得蛮重要的。因为 Session 所代表的是「状态」,如果没有了状态,一大堆功能都会失效。 对于工程师来说必须去理解什么是 Sess…...
【Java】重载和重写的区别
重载(Overload) 在同一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同…...
AcWing 第 90 场周赛
目录A、首字母大写B、找数字C、构造字符串A、首字母大写 原题链接:AcWing 4806. 首字母大写 签到题。 #include <bits/stdc.h>using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(nullptr);string s;cin >> s;s[0] toupper(s[0]);…...
刚刚,体验了一把Bing chat很爽
文章目录刚刚,体验了一把Bing chat很爽你能做啥?与chatgpt有什么不同?以下是Bingchat的 10个新功能1⃣️在网上搜索结果2⃣️摘要链接3⃣️对话助手4⃣️向您发送实际信息,正确的链接5⃣️在单个查询中执行多个搜索6⃣️玩冒险游戏…...
牛客网Python篇数据分析习题(二)
1.现有一个Nowcoder.csv文件,它记录了牛客网的部分用户数据,包含如下字段(字段与字段之间以逗号间隔): Nowcoder_ID:用户ID Level:等级 Achievement_value:成就值 Num_of_exercise&a…...
如何用Python打包好exe文件,并替换图标
前言 Python打包?打包exe文件?怎么操作? ok,今天我来分享分享,教你们如何打包号文件,顺便还来展示一下,如何替换好图标 首先把你的代码准备好,尽量不要中文路径,容易报…...
NFC概述摘要
同学,别退出呀,我可是全网最牛逼的 WIFI/BT/GPS/NFC分析博主,我写了上百篇文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦。 原理来说,NFC和Wi-Fi类似,利用无线射频技术来实现设备间通信。NFC的工作频率为13.5…...
Python-项目实战--贪吃蛇小游戏(1)
1.贪吃蛇游戏规则贪吃蛇游戏规则如下:1.1开始和结束贪吃蛇初始出现在游戏窗口的左上角位置,体长共有3节游戏过程中,一旦蛇头撞到了窗口的边缘或者身体的其他部位,游戏结束游戏过程中,点击游戏窗口的关闭按钮,或者按下ESC键可以直接退出游戏一…...
vscode sftp从linux服务器下载文件至本地:No such file or dictionary【已解决】
在服务器跑完程序需要下载数据的时候报错: [warn] ENOENT: no such file or directory, open /home/LIST_2080Ti/.ssh/config load /home/LIST_2080Ti/.ssh/config failed 完整报错内容如下: [02-10 08:38:47] [info] config at /home/LIST_2080Ti {&q…...
详解指针(2)(初阶版)
前言:内容包括:指针运算,指针和数组,二级指针,指针数组 详解指针(1)(点击即跳转) part 1:指针运算 1 指针-整数 以如下代码为例:初始化数组内容…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
