gitlab CI教学
GitLab CI/CD 环境搭建指南 本文详细介绍了在腾讯云CVM上搭建GitLab CI/CD环境的完整流程。主要内容包括: 环境准备:配置3台Ubuntu服务器(GitLab、Harbor、Runner),安装Docker和Docker Compose,设置镜像加速 GitLab部署:通过Docker Compose安装GitLab CE 16.11.1,配置外部URL,创建代码仓库和Git
gitlab CI教学
一、环境准备
-
腾讯云账号
-
上面购买三个CVM,两个4C8G,一个2C4G,系统都用Ubuntu 22.04
- GITLAB_IP:GitLab 所在 CVM 的内网 IP,例如 192.168.1.2
- HARBOR_IP:Harbor 所在 CVM 的内网 IP,例如 192.168.1.3
- RUNNER_IP:Runner 所在 CVM 的内网 IP,例如 192.168.1.4
-
三个公网弹性公网ip,绑定给这3个机器。目的不是让他们通过公网互通,只是方便从官网拉镜像装包。在严格网络环境下,可以全部采用内网互通,不带公网,相关的镜像文件等东西,用一个能连上公网的机器下载下来,分别传给内网机器即可。这里从实验的角度来说,各配置一个弹性公网ip方便一点。
-
腾讯云镜像仓库地址:https://mirror.ccs.tencentyun.com
-
镜像文件:
- docker:24 # 这个镜像要放到gitlab-runner的机器上
- gitlab/gitlab-runner:alpine # 这个镜像要放到gitlab-runner的机器上
- gitlab-ce-16.11.1.tar # 这个镜像要放到gitlab的机器上
- gitlab/gitlab-runner-helper:x86_64-v18.9.0 # 这个镜像要docker pull到 gitlab-runner的机器上,因为跑CI job的时候要用,没有这个的话,跑pipeline job会报错,拉不到这个镜像,如图9.png

-
apt安装包:
- docker.io
- docker-compose
-
单独下载:
- harbor-online-installer-v2.10.0.tgz # 是wget下载的压缩包,给harbor机器用
(见第三节wget方式)
- harbor-online-installer-v2.10.0.tgz # 是wget下载的压缩包,给harbor机器用
-
在三台机器上分别装docker 和 docker-compose(如果用的centos和rocky linux,高版本的rpm docker我记得一般是默认自带docker-compose的,但是Ubuntu得再装一下)
apt install -y docker.io docker-compose
-
三台机器上都配置上腾讯云镜像仓库加速器
root@VM-1-2-ubuntu:/srv/gitlab# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}
root@VM-1-2-ubuntu:/srv/gitlab#
修改 daemon.json 后,三台机器都要执行 systemctl restart docker,否则配置不生效
- 部署方式

二、部署gitlab服务
- 在gitlab的cvm上,创建gitlab工作目录
mkdir -p /srv/gitlab && cd /srv/gitlab
- 写docker-compose.yml
root@VM-1-2-ubuntu:/srv/gitlab# cat docker-compose.yml
version: "3.8"
services:
gitlab:
image: gitlab/gitlab-ce:16.11.1-ce.0
container_name: gitlab
restart: always
hostname: 192.168.1.2
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://192.168.1.2'
# 要从公网访问gitlab UI,在上面创建runner时,会跳转为404,这时把这个ip改成gitlab机器的公网ip,等复制完创建runner时跳出的提示的,runner如何在gitlab注册的命令后,将ip再改回为内网ip,
# 提示命令比如:docker exec -it gitlab-runner gitlab-runner register --url http://123.xxx.xx.xxx --token glrt-xxvUZuNYexxx
ports:
- "80:80"
volumes:
- ./config:/etc/gitlab
- ./logs:/var/log/gitlab
- ./data:/var/opt/gitlab
root@VM-1-2-ubuntu:/srv/gitlab#
- 用docker-compose启动gitlab服务,启动过程需要几分钟,大概3-5分钟。
docker-compose up -d
- 过3分钟,检查gitlab是否部署成功
-
docker ps -a | grep gitlab
- 用自己电脑浏览器访问gitlab机器的公网ip,应该要看到gitlab的登录界面
- 默认登录用户root
- 初始密码,在gitlab机器上执行如下命令
-
docker exec -it gitlab grep ‘Password:’ /etc/gitlab/initial_root_password
-
- 登录gitlab之后,修改root密码
- 在gitlab里面创建两个空项目
- 代码仓库: demo-app,用来放java源码和.gitlab-ci.yml、Dockerfile、pom.xml
- gitops仓库: demo-gitops,用来CD的时候弄argocd,放deployment.yaml
三、部署harbor
-
下载安装包
wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-online-installer-v2.10.0.tgz
-
解压安装包
tar xvf harbor-online-installer-v2.10.0.tgz
cd harbor
-
复制示例配置
cp harbor.yml.tmpl harbor.yml
-
修改配置:
vim harbor.yml
关键修改:- hostname: HARBOR_IP,这里用192.168.1.3
- 使用 http:
- port: 80
- https: 块保持注释或 disabled,这里进行注释
- 设定 admin 密码:harbor_admin_password: 你自定义
-
安装harbor
./install.sh
-
登录harbor
- 默认用户: admin
- 初始化密码: 在harbor.yml中自己自定义的
- 在harbor UI创建项目:demo
- 在harbor UI创建一个普通用户,要记录下这个用户的用户名和密码,作为HARBOR_USER和HARBOR_PASSWORD的值
- 在harbor UI点进项目demo里面,点击成员,添加刚才创建的普通用户,这个用户的角色定义为开发者
四、 部署gitlab-runner
- 在CVM机器上,对docker的配置,将harbor机器的内网ip设置成对于gitlab-runner机器来说是不安全的仓库
ubuntu@cvm-runner:~$ cat /etc/docker/daemon.json
{
"insecure-registries": ["192.168.1.3:80"],
"registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}
ubuntu@cvm-runner:~$
-
重启docker
systemctl restart docker
-
拉取gitlab-runner的镜像
docker pull gitlab/gitlab-runner:alpine
-
启动runner容器(挂载 docker.sock)
mkdir -p /srv/gitlab-runner/config
docker run -d --name gitlab-runner --restart always -v /srv/gitlab-runner/config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:alpine -
检查容器启动成功没
docker ps
-
编辑 runner 配置(必须,否则 job 里 docker build 会失败) 「若当前还没有 [[runners]] 块,请先完成下面步骤 7、8 在 GitLab 创建 runner 并执行 register,再回到本步编辑 config.toml。」
- 在 runner 宿主机上编辑:
/srv/gitlab-runner/config/config.toml - 在
[[runners]]对应的[runners.docker]下确保有:
privileged = true volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]- 保存后无需重启容器,runner 会读配置;若已注册多个 runner,确认改的是当前用的那个
[[runners]]块。
- 在 runner 宿主机上编辑:
正确可用的效果如图:
- 在gitlab UI上创建runner,保存好token,UI点击路径如图,demo-app/CICD/settings/register runner

-
注册runner,在gitlab-runner所在机器上执行下方命令,具体如图
docker exec -it gitlab-runner gitlab-runner register
按照提示,先填gitlab的内网地址 http://192.168.1.2,和上一步记录下来的token

-
现在在终端里继续按顺序输入:
- Runner 名字(随便写,比如):
- cvm-runner-1
- tag(可以直接回车留空):
- Enter tags for the runner (comma-separated):
[回车]
- Enter tags for the runner (comma-separated):
- 是否运行 untagged jobs(建议选 true,直接回车默认值或输入 true):
- Enter optional maintenance note for the runner:
[回车] - Enter an executor: docker, shell, etc:
docker
- Enter optional maintenance note for the runner:
- executor 选 docker,接着会让你输入 default image,比如:
- Enter the default Docker image (for example, ruby:2.7):
docker:24
- Enter the default Docker image (for example, ruby:2.7):
当命令结束、回到 shell 提示符时,注册就真正完成了。如图6.png
- Runner 名字(随便写,比如):

-
然后在 GitLab UI 里确认一下:
- 进 demo-app → Settings → CI/CD → Runners
- 在 Project runners 区块应看到一个 绿色 Active 的 runner(名字就是你刚填的 cvm-runner-1)
如果是 Active,就说明 Runner 已经 OK,下一步你就可以开始写 .gitlab-ci.yml,在 UI 里点 Run pipeline 跑一次 CI 了。

-
在 demo-app → Settings → CI/CD → Variables 中配置
HARBOR_USER、HARBOR_PASSWORD(建议勾选 Masked),否则下面 script 里的docker login会报错。 -
在gitlab UI创建新的runner的时候,会让填写tag,比如test04,这个tag如果定义了,那么在代码仓的.gitlab-ci.yml文件里面就要写build_and_push: [tags: [“test04”]],如图:


image: docker:24
variables:
DOCKER_TLS_CERTDIR: ""
HARBOR_HOST: "192.168.1.3:80" # 换成你的 Harbor 内网 IP:80
HARBOR_PROJECT: "demo"
HARBOR_REPO: "spring-demo"
IMAGE: "$HARBOR_HOST/$HARBOR_PROJECT/$HARBOR_REPO"
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "web"'
when: always
- when: never
stages:
- docker
build_and_push:
stage: docker
tags: ["test04"]
script:
- docker info | grep -A3 "Insecure Registries" || true
- docker login "$HARBOR_HOST" -u "$HARBOR_USER" -p "$HARBOR_PASSWORD"
- docker build -t "$IMAGE:$CI_COMMIT_SHA" .
- docker push "$IMAGE:$CI_COMMIT_SHA"
only:
- branches
五、准备java测试代码
代码仓里面放个简单的测试java源代码:
- 代码仓目录结构:
demo-app/
pom.xml
src/
main/
java/
com/example/demo/
DemoApplication.java
HelloController.java
resources/
application.properties
Dockerfile
.gitlab-ci.yml
- pom.xml (Spring Boot 3 + Java 17)
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo Spring Boot app for CI/CD</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.3</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-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 启动类 DemoApplication.java
- 路径:src/main/java/com/example/demo/DemoApplication.java:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
- 控制器 HelloController.java
- 路径:src/main/java/com/example/demo/HelloController.java:
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "hello from demo-app";
}
}
- application.properties
- 路径:src/main/resources/application.properties:
server.port=8080
management.endpoints.web.exposure.include=health,info
- Dockerfile
- 放在项目根目录 demo-app/Dockerfile
FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn -B -Dmaven.test.skip=true clean package
FROM eclipse-temurin:17-jre
WORKDIR /app
COPY --from=build /app/target/*.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]
六、 跑pipeline流水线
- 在gitlab的UI
- demo-app → Build → Pipelines → Run pipeline
- 构建应该可以顺利完成 Maven 打包 + Docker build/push,Harbor 里会出现一个新镜像。



七、 补充说明
- gitlab-runner的机器里面的runner的容器里面,记得改过一个参数,但是忘了是哪一步改的了,如图就是这个提权,这个不改成true的话,job跑不通。

- 中间还有一步,是在gitlab UI上加环境变量HARBOR_USER和HARBOR_PASSWORD,将harbor上创建的用户,并且加入到了demo项目成员的用户的账号密码作为值,填到gitlab上,当gitlab-runner根据.gitlab-ci.yml里面的指引跑流水线的时候,可以找到这两个环境变量的值。如图14.png

八、总结
- 本次CI架构是基于gitlab和gitlab-runner来做的流水线,目的是通过这两个软件将java源代码,以.gitlab-ci.yml、Dockerfile、pom.xml为引导,通过gitlab-runner进程,来调用gitlab-runner容器所在宿主机的docker进程来在容器里面跑pipeline流水线,根据Dockerfile,基于一个基础镜像来在容器里面进行Maven然后在容器里面把jar包打好放到固定的位置,然后用java -jar命令启动这个jar包,也就是java程序。这样就做出来了一个java的服务镜像。这一步docker build -t的指引是写在.gitlab-ci.yml文件里面的。然后build好这个服务镜像之后,同样是根据.gitlab-ci.yml文件里面的指引步骤,将image push到harbor。这样就完成了一次,从java代码到build image,再到把image push到harbor的自动化流水线。之后每次开发提交代码之后,在gitlab上点一下build -> pipelines -> run pipeline,就可以以最新的commit为image的tag,把java代码Maven成jar包,打好服务镜像,并且把服务镜像推送到harbor了。这样一个CI就搞定了。那么第二步就是在argocd上去进行cd了,操作就是修改argocd watch的那个gitlab代码仓,里面就放上一个deployment.yaml就可以了。然后每次改一下deployment.yaml里面的image的tag,改成最新的。然后提交这次修改。当argocd监控到这个git仓库的变化之后,会自动把这个修改同步到TKE集群上。就完成了CD。CD这一步也可以手动到argocd UI上面去点,也可以设置好webhook对git仓库进行实时监控。
九、 再补充说明
- GitLab:负责编排 pipeline 和下发 job
- Runner 宿主机 (192.168.1.4):负责跑所有容器(runner / job / maven build)
- Harbor (192.168.1.3:80):负责收镜像
十、后记(我让AI检查这篇教程,AI提出的问题,后面照着教程从零部署时,可能会遇到,我贴在这里)
整体来说,这篇教材思路清晰、步骤基本正确,用它从 0 搭一套 CI 完全没问题。有几处地方,如果补充说明一下,会更严谨、也更方便你以后“照着做”不踩坑:
1. 镜像 / 包准备的小细节
gitlab-ce-16.11.1.tar的使用步骤没写
你前面列了这个离线镜像,但后面docker-compose.yml直接用gitlab/gitlab-ce:16.11.1-ce.0,没有写如果是离线环境要docker load -i gitlab-ce-16.11.1.tar。建议在“环境准备”或“部署 gitlab”里加一句:docker load -i gitlab-ce-16.11.1.tar- 修改
/etc/docker/daemon.json后记得重启 docker
在 GitLab/Harbor 机器配置腾讯云镜像加速器时,最好像 runner 那里一样明确加一句:systemctl restart docker
2. GitLab Runner + Docker 的关键配置没写全
你现在的做法是:
- runner 容器启动时挂了
-v /var/run/docker.sock:/var/run/docker.sock - 选的 executor 是
docker .gitlab-ci.yml里image: docker:24,直接在 job 里跑docker build / docker push
要让这种模式稳定工作,config.toml 里有两个关键点建议写死在文档里(你现在只用截图提了一句“提权要改成 true”):
[[runners]]
[runners.docker]
privileged = true
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
privileged = true:就是你截图 13.png 里的那个,不改的话很多docker build会各种权限问题。volumes挂载 docker.sock:挂到 runner 容器上只是第一步,还需要在config.toml里把这个 volume 传递到真正跑 job 的容器里,否则 job 内看不到/var/run/docker.sock。
建议在“部署 gitlab-runner”里单独加一步“编辑 /srv/gitlab-runner/config/config.toml”,把这两个字段写清楚。
3. .gitlab-ci.yml 逻辑本身是通的,但可以再解释清楚一点
- 当前写法是“job 容器里通过 docker.sock 操作宿主机 Docker”
这一点你在总结里有提到,但建议在.gitlab-ci.yml段落前面明确一句:“这里不是起docker:dind,而是通过/var/run/docker.sock调用 runner 宿主机的 Docker”——方便以后自己看时立刻想起来这是哪种模式。 HARBOR_USER/HARBOR_PASSWORD的位置
你在“补充说明”第 2 条里说了要在 GitLab UI 中配置这两个变量。可以在.gitlab-ci.yml段落前加一个“前置条件:在项目 Settings → CI/CD → Variables 中配置HARBOR_USER、HARBOR_PASSWORD”,这样一眼就看得到,不用看到后面补充说明才发现。
4. 版本和安全相关的提示(不是错误,但可提醒一下)
- runner 版本与 helper 镜像
你写了要提前拉gitlab/gitlab-runner-helper:x86_64-v18.9.0,但没说明 runner 版本要与 helper 对齐(通常拉gitlab/gitlab-runner:alpine-v18.9.0)。建议在拉 runner 镜像时带上版本号,并注明“helper 版本要与 runner 版本一致”。 - HTTP Harbor + insecure-registries 的风险
在“总结”或“补充说明”里加一句“生产环境建议给 Harbor 配 https,去掉insecure-registries,这里只是为了教学方便”。
5. 文档结构上的小优化建议
- 开头加一个总览图 / 步骤列表
比如“1. 搭 GitLab → 2. 搭 Harbor → 3. 搭 Runner → 4. 准备 demo app → 5. 写.gitlab-ci.yml→ 6. 跑一次 Pipeline”,让你以后回来看时可以先整体扫一眼。 - 把“容易忘的坑”集中成一小节 Checklist
例如:- docker 的
/etc/docker/daemon.json改完有没有重启 - runner 的
privileged = true是否改了 HARBOR_USER、HARBOR_PASSWORD是否配置在 GitLab Variables 里- helper 镜像是否提前拉好
- pipeline 报错时先看 job log 里的哪一步挂了(登录 Harbor、build 还是 push)
- docker 的
总结一下:大方向和关键步骤是对的,可以成功跑通 CI,现在主要是少了 2~3 个关键配置的显式文字说明(尤其是 runner 的 config.toml 和 docker.sock),再加一点“坑点 checklist”,这篇教材就非常适合作为你以后反复复用的私有手册了。
如果你愿意,我可以帮你直接把这些修改合并进当前 gitlabCI教学.md,改成一个更完善的版本。
十一、 架构图

更多推荐
所有评论(0)