一文看懂Gitlab环境搭建及配置
概述
| 软件简介 | GitLab 是一个基于 Web 的 DevOps 全流程平台,集成了代码托管、版本控制、CI/CD、项目管理、安全扫描等功能,支持从代码提交到部署的端到端软件开发与协作。 |
|---|---|
| 软件归属 | 最初由乌克兰开发者 Dmitriy Zaporozhets 和荷兰企业家 Sytse “Sid” Sijbrandij 共同创立,现在归属于GitLab Inc. |
| 产生时间 | 2011年 |
| 相关地址 | 官网 |
1 Gitlab环境部署
本文采用docker容器搭建方式,分别采用3种方式进行部署适用于不同的应用场景。
1.1 不带ssl证书部署
本地简单使用可采用这种方式。
将如下内容复制到docker-compose.yml文件中:
services:gitlab:image:gitlab/gitlab-ce:latestcontainer_name:gitlabrestart:alwayshostname:'10.56.223.19'privileged:true# 内存限制(10人以内团队:建议8g,10~50人团队:建议32g,50人以上团队:不限制[大约会占用40G+内存])# mem_limit: 8g# memswap_limit: 8genvironment:GITLAB_OMNIBUS_CONFIG:|#external_url 'http://10.56.223.19' # 配置时区 gitlab_rails['time_zone'] = 'Asia/Shanghai' # 邮件设置(可选) # gitlab_rails['smtp_enable'] = true # gitlab_rails['smtp_address'] = "smtp.gmail.com" # gitlab_rails['smtp_port'] = 587 # gitlab_rails['smtp_user_name'] = "your-email@gmail.com" # gitlab_rails['smtp_password'] = "your-password" # gitlab_rails['smtp_domain'] = "smtp.gmail.com" # gitlab_rails['smtp_authentication'] = "login" # gitlab_rails['smtp_enable_starttls_auto'] = true # gitlab_rails['smtp_tls'] = false # gitlab_rails['gitlab_email_from'] = 'your-email@gmail.com'ports:-'80:80'-'443:443'-'22:22'volumes:-'./config:/etc/gitlab'-'./logs:/var/log/gitlab'-'./data:/var/opt/gitlab'shm_size:'256m'networks:-gitlab-networknetworks:gitlab-network:driver:bridge说明:
hostname为服务器IP地址、ports中的端口及networks中的网络名称等参数均可自定义。如下端口会被浏览器禁止,不能使用,具体可参考这里。
邮箱配置需配合邮箱服务器使用,可实现代码推送或重置密码等消息发送,自建邮箱服务器可参考这里。
external_url为界面下载代码的地址,如果不设置hostname和external_url,则会显示为容器的ID,如下所示:
1.2 带ssl证书部署
内网搭建Devops可采用这种方式,配合本地搭建DNS服务器可实现内网域名访问。
将如下内容复制到docker-compose.yml文件中:
services: gitlab: image: gitlab/gitlab-ce:latest container_name: gitlab restart: always hostname:'10.56.223.19'privileged:true# 内存限制(10人以内团队:建议8g,10~50人团队:建议32g,50人以上团队:不限制[大约会占用40G+内存])# mem_limit: 8g# memswap_limit: 8genvironment: GITLAB_OMNIBUS_CONFIG:|# 使用 HTTPS 并指定端口external_url'https://10.56.223.19:4433'# ===== 关键修复:强制 Nginx 监听 IPv4 =====nginx['listen_addresses']=['0.0.0.0']nginx['listen_port']=443nginx['listen_https']=true# 配置时区gitlab_rails['time_zone']='Asia/Shanghai'# SSL 证书配置nginx['ssl_certificate']="/etc/gitlab/ssl/gitlab.pem"nginx['ssl_certificate_key']="/etc/gitlab/ssl/gitlab.key"# 可选:配置 SSL 协议和加密套件(推荐)nginx['ssl_protocols']="TLSv1.2 TLSv1.3"nginx['ssl_ciphers']="ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384"nginx['ssl_prefer_server_ciphers']="off"# 可选:启用 HSTS(强制 HTTPS)nginx['hsts_max_age']=31536000nginx['hsts_include_subdomains']=false# 可选:HTTP 自动跳转到 HTTPSnginx['redirect_http_to_https']=true# ===== Let's Encrypt 自动证书配置(二选一)=====# 如果想使用 Let's Encrypt 自动获取证书,取消下面注释并注释掉上面的 ssl_certificate 配置# letsencrypt['enable'] = true# letsencrypt['contact_emails'] = ['your-email@example.com']# letsencrypt['auto_renew'] = true# letsencrypt['auto_renew_hour'] = 0# letsencrypt['auto_renew_minute'] = 30# letsencrypt['auto_renew_day_of_month'] = "*/7"# 邮件设置(可选)# gitlab_rails['smtp_enable'] = true# gitlab_rails['smtp_address'] = "smtp.gmail.com"# gitlab_rails['smtp_port'] = 587# gitlab_rails['smtp_user_name'] = "your-email@gmail.com"# gitlab_rails['smtp_password'] = "your-password"# gitlab_rails['smtp_domain'] = "smtp.gmail.com"# gitlab_rails['smtp_authentication'] = "login"# gitlab_rails['smtp_enable_starttls_auto'] = true# gitlab_rails['smtp_tls'] = false# gitlab_rails['gitlab_email_from'] = 'your-email@gmail.com'ports: -'10088:80'-'4433:443'-'20022:22'volumes: -'./config:/etc/gitlab'-'./logs:/var/log/gitlab'-'./data:/var/opt/gitlab'-'./ssl:/etc/gitlab/ssl'shm_size:'256m'networks: - gitlab-network networks: gitlab-network: driver: bridge该方法需要先创建ssl目录,将ssl证书(可使用自签名证书)放入对应目录。
1.3 内网穿透部署
需要通过公网访问,但公网服务器资源资源有限可采用这种方式。
将如下内容复制到docker-compose.yml文件中:
services: gitlab: image: gitlab/gitlab-ce:latest container_name: gitlab restart: always hostname:'10.56.223.19'privileged:true# 内存限制(10人以内团队:建议8g,10~50人团队:建议32g,50人以上团队:不限制[大约会占用40G+内存])# mem_limit: 8g# memswap_limit: 8genvironment: GITLAB_OMNIBUS_CONFIG:|# 配置外网访问地址(Git clone 等会显示这个地址)external_url'https://xxx.xxx.com'# 配置时区gitlab_rails['time_zone']='Asia/Shanghai'# 关键配置:允许通过不同地址访问nginx['listen_port']=80nginx['listen_https']=false# 禁用自动重定向nginx['redirect_http_to_https']=false# 信任来自反向代理的请求头nginx['real_ip_trusted_addresses']=['0.0.0.0/0']nginx['real_ip_header']='X-Forwarded-For'nginx['real_ip_recursive']='on'# 邮件设置(可选)# gitlab_rails['smtp_enable'] = true# gitlab_rails['smtp_address'] = "smtp.gmail.com"# gitlab_rails['smtp_port'] = 587# gitlab_rails['smtp_user_name'] = "your-email@gmail.com"# gitlab_rails['smtp_password'] = "your-password"# gitlab_rails['smtp_domain'] = "smtp.gmail.com"# gitlab_rails['smtp_authentication'] = "login"# gitlab_rails['smtp_enable_starttls_auto'] = true# gitlab_rails['smtp_tls'] = false# gitlab_rails['gitlab_email_from'] = 'your-email@gmail.com'ports: -'10088:80'-'20022:22'volumes: -'./config:/etc/gitlab'-'./logs:/var/log/gitlab'-'./data:/var/opt/gitlab'shm_size:'256m'networks: - gitlab-network networks: gitlab-network: driver: bridge其中,external_url为公网域名,内网穿透方法可参考这里。
在公网服务器上的web服务器添加代理配置,以nginx为例,可在nginx.conf中添加如下片段:
server { listen 443 ssl; server_name xxx.xxx.com; ssl_certificate /etc/nginx/ssl/server.pem; ssl_certificate_key /etc/nginx/ssl/server.key; location / { proxy_pass http://xxx.xxx.xxx.xxx:10088; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } }其中:server_name需替换为实际公网域名,proxy_pass需替换为实际公网服务器的ip和对应端口。
2 Gitlab配置
2.1 登录及密码修改
在前面docker-compose.yml所在目录执行如下命令,创建并启动容器
docker-compose up-d等待容器状态健康后(约4~5分钟),即可登录,登录界面如下所示:
登录用户名为root,初始密码通过如下方式获取:
dockerexec-itgitlabgrep'Password:'/etc/gitlab/initial_root_password其中,容器名以实际的为准。
登录成功后如下:
登录后参考如下方式修改密码:
2.2 设置语言及主题
参照如下方式设置为中文:
没有实现100%翻译,设置成功后如下:
设置模式、主题及语法高亮等:
设置成功后如下:
2.3 禁用用户注册
为有效管控代码仓权限,通常需要禁用用户注册功能,由管理员分配账号及权限,参考如下方式:
2.4 设置双重认证
如需加强登录权限控制,可参考如下方式设置所有用户登录需进行双重认证:
设置成功后,所有用户登录时会有类似如下提示,需在管理员设置后两天内完成双重认证设置。
双重认证通常是在移动端(如:手机)上安装一个具有认证功能的应用,登录时系统会发送一个具有时效性的验证码给该应用,通常有以下几种应用可供选择,本文选择使用FreeOTP
参考如下方式设置双重认证:
在手机上安装FreeOTP后扫描上面的二维码,输入用户密码和FreeOTP上收到的验证码,即可完成设置,设置成功后如下:
这里会生成10个恢复码,比如换了手机,新手机没法接受验证码,可使用恢复码代替验证码,登录系统后,用新手机上安装的FreeOTP重新扫码设置双重验证,当然也可以提前把旧手机上FreeOTP的配置备份出来,在新手机上导入配置,也能正常接收验证码。
双重认证设置成功后,用户再次登录时,输入用户名密码后,会需要提供验证码,如下所示:
找到这一行 /* That’s all, stop editing! Happy publishing. */,在其前面添加如下内容:
// 支持反向代理if(isset($_SERVER['HTTP_X_FORWARDED_PROTO'])&&$_SERVER['HTTP_X_FORWARDED_PROTO']==='https'){$_SERVER['HTTPS']='on';}// 强制设置站点URL(推荐在反向代理场景使用)define('WP_HOME','https://www.xxx.com');define('WP_SITEURL','https://www.xxx.com');注意:其中的https://www.xxx.com需换为实际的域名
2.5 设置访问令牌
当启用双重认证后,不能再通过用户名+密码的方式调用Gitlab的API,需要改成用户名+访问令牌的方式,参考如下方式添加令牌:
令牌名称根据用途自定义,日期最长为1年,根据实际情况勾选设置,权限说明如下:
| 权限 | 中文含义 | 能做什么 | 典型使用场景 |
|---|---|---|---|
| read_service_ping | 读取服务状态统计 | 通过 API 获取 GitLab Service Ping 数据(实例级统计) | 运维监控、官方支持 |
| read_user | 读取用户信息 | 获取用户名、公开邮箱、姓名等用户信息 | SSO、内部系统对接 |
| read_repository | 只读仓库 | git clone / pull 私有仓库 | 服务器拉代码、CI 拉代码 |
| write_repository | 读写仓库 | git push、创建/修改提交 | CI 自动提交、版本发布 |
| read_virtual_registry | 只读容器镜像仓库 | docker pull 私有镜像 | 部署服务器、K8s |
| write_virtual_registry | 读写容器镜像仓库 | docker push / delete 镜像 | CI 构建并推送镜像 |
| read_api | API 只读访问 | 读取项目、Pipeline、Job、变量等 | 自动化脚本、监控 |
| api | API 完全访问 | 创建/修改项目、触发流水线、改变量 | 运维自动化、管理工具 |
| self_rotate | 令牌自我轮换 | 允许当前 Token 调用 API 更新自己 | 安全轮换机制 |
| ai_features | AI 功能访问 | 访问 GitLab Duo AI 相关 API | AI 辅助开发 |
| create_runner | 创建 Runner | 注册/创建 GitLab Runner | CI 基础设施管理 |
构建流水线通常选择:read_api、read_repository、write_repository。
3 Gitlab代码管理
3.1 新建项目
参考如下方式新建项目,新建项目支持空白项目、从模板创建和导入项目3种方式:
这里以新建空白模板为例,项目名称自定义,URL中的群组可在左侧新增
新建成功后如下:
3.2 设置SSH keys
如需使用ssh认证替代用户名/密码方式拉取代码,需要先在服务器上生成ssh密钥对,然后将公钥添加到gitlab中,具体参考如下:
这里以在linux服务器上操作为例,windows上操作类似。
- 首先在服务器上新建一个目录,将该目录初始化为git仓库
gitinit- 添加并执行脚本
#!/bin/bashset-eKEY_NAME=$1IP_OR_DOMAIN=$2SSH_PORT=$3REMOTE_NAME=$4REMOTE_URL=$5SSH_DIR="$HOME/.ssh"KEY_FILE="$SSH_DIR/$KEY_NAME"# 参数检查if[[-z"$KEY_NAME"||-z"$IP_OR_DOMAIN"||-z"$SSH_PORT"||-z"$REMOTE_NAME"||-z"$REMOTE_URL"]];thenecho"====================需在git仓库所在目录执行======================"echo"用法:$0<key_name> <address> <port> <remote_name> <remote_ssh_url>"echo"参数说明: "echo" <key_name>:生成ssh密钥对的名称(自定义,后续添加到gitlab代码仓的SSHkey默认显示该名称)"echo" <address>:gitlab仓库所在服务器的IP地址或域名"echo" <port>:gitlab使用的SSH端口"echo" <remote_name>:远程代码仓的名称(通常为origin)"echo" <remote_ssh_url>:远程代码仓的URL地址(项目里克隆代码的地址)"echo"示例:$0server_11 code.test.com 22 origin git@code.test.com:tester/iot.git"exit1fi# 判断 $REMOTE_URL 格式,并提取主机名if[["$REMOTE_URL"=~^git@([^:]+):.+\.git$]];thenHOST_NAME="${BASH_REMATCH[1]}"elseecho"错误: \$REMOTE_URL格式不正确,请检查"exit1fi# 确保 $HOME/.ssh 目录存在mkdir-p"$SSH_DIR"chmod700"$SSH_DIR"# 生成密钥对(不设置密码)if[[-f"$KEY_FILE"]];thenecho"密钥文件$KEY_FILE已存在,跳过生成。"elsessh-keygen-ted25519-N""-f"$KEY_FILE"-C"$KEY_NAME"echo"已生成密钥对:$KEY_FILE和${KEY_FILE}.pub"fi# 确保 ~/.ssh/config 存在并添加 Host 配置CONFIG_FILE="$SSH_DIR/config"touch"$CONFIG_FILE"chmod600"$CONFIG_FILE"ifgrep-q"Host$HOST_NAME""$CONFIG_FILE";thenecho"Host$HOST_NAME已在$CONFIG_FILE中存在,跳过添加。"elsecat>>"$CONFIG_FILE"<<EOF Host$HOST_NAMEHostName$IP_OR_DOMAINUser git Port$SSH_PORTIdentityFile$KEY_FILEIdentitiesOnly yes EOFecho"已在$CONFIG_FILE中添加 Host$HOST_NAME配置"fi# 配置远程仓库 SSH 地址ifgitremote|grep-qw"$REMOTE_NAME";thengitremote set-url"$REMOTE_NAME""$REMOTE_URL"echo"已将远程仓库$REMOTE_NAME地址设置为$REMOTE_URL"elsegitremoteadd"$REMOTE_NAME""$REMOTE_URL"echo"已添加远程仓库$REMOTE_NAME地址$REMOTE_URL"fi# 打印公钥内容,提示添加并测试 SSHechoecho"请将以下公钥内容添加到远程仓库的 SSH Keys 中,"echo"---------------------------------------------------"cat"${KEY_FILE}.pub"echo"---------------------------------------------------"echoecho"成功添加公钥后可执行:"echo" ssh -T git@$HOST_NAME:测试 SSH 连接远程仓库$REMOTE_URL是否成功"echo" git push$REMOTE_NAME:推送本地分支代码"echo" 若是首次推送,则使用git push -u$REMOTE_NAME$current_branch,$current_branch为本地当前分支,能够自动在远端建立一个和本地当前分支同名的分支,并建立跟踪关系"脚本添加成功后如下,脚本名称可自定义:
执行脚本不带参数可查看用法:
执行脚本:
./genSSHkey.sh server_1510.56.223.1520022origin git@21e5dbd51d8d:root/iot_mqtt.git- 在gitlab中添加公钥
参考如下方式添加公钥:
添加成功后如下:
公钥会存入authorized_keys中,进入容器可以查看
dockerexec-itgitlab /bin/bashcat/var/opt/gitlab/.ssh/authorized_keys客户端使用私钥进行登录时,会根据私钥提取公钥发送给gitlab服务端,服务端分别计算发来的公钥指纹与authorized_keys中存放的公钥指纹,若匹配成功,则可以登录,同时也能知晓是那个用户在登录。
- 测试连接远程仓库
ssh-Tgit@21e5dbd51d8d#若私钥未存放在默认路径~/.ssh下,则需要添加-i参数显示指定私钥文件。可以看到远程仓库已通过ssh连接成功(首次连接需要将远程仓库添加为信任的主机列表),为避免每次推送都需要认证,可缓存ssh密钥(会话期间有效):
eval"$(ssh-agent-s)"ssh-add /root/.ssh/server_15#以实际密钥地址为准- 查看远程仓库
gitremote-v3.3 配置用户提交信息
gitconfig--globaluser.email"xxx@163.com"# 需替换为实际邮箱gitconfig--globaluser.name"simen"# 需替换为实际用户名3.4 添加提交时的忽略跟踪项
这里以history为后缀的文件为例
echo"*.history">>.gitignore3.5 代码拉取与推送
3.5.1 代码拉取
选择某个空目录,将该目录初始化为git仓库
gitinit添加并查看远程仓库地址
gitremoteaddorigin git@a79907fffb0e:tester/iot.git#添加远程仓库地址gitremote-v#查看远程仓库地址拉取对应分支代码
gitpull origin master3.5.2 代码推送
- 在服务器上推送
rm-rfgenSSHkey.sh# 删除创建ssl证书脚本touchtest.txt# 新建测试文件gitadd.# 添加新文件gitcommit-m"首次提交"# 提交修改gitpush-uorigin master# 推送分支(自动在远程仓库建立master分支并建立跟踪关系)推送成功后到远程仓库查看master分支:
- 本地推送
通常在linux服务器上修改代码不方便,可参考这里远程连接服务器后在本地修改代码,找到1.2.2节插件使用里的Remote-SSH插件,远程连接成功后如下,即可在本地推送和拉取代码
3.6 合并分支
通常代码都在开发分支进行维护,版本迭代结束时需要合并到主干分支,合并分支参考如下:
- 创建合并请求
- 选择源分支和目标分支
选择好对应分支后,点击“比较分支并继续”
- 填写合并请求参数
根据实际情况填写合并标题、描述及指派合并请求审批人等
注意去掉“接受合并请求时删除源分支”前面的勾选(默认会勾选上),然后点击“创建合并请求”。
为避免忘记去掉勾选“接受合并请求时删除源分支”,导致误删除源分支,可以参考如下方式进行设置。
另外,Gitlab默认采用相对时间,比如提交时间与合并时间默认显示大致时间,为了便于查看精确时间,可参考如下方式将“使用相对时间”前面的勾选去掉。
- 审批合并请求
根据实际情况进行合并审批
若需多人审批,则可点击批准,等所有批注通过后点击合并
若仅需单人审批,可直接点击合并
若审批不通过,则可以点击下方的“关闭合并请求”
合并通过后可以在“已合并”中查看合并详情
4 用户及成员管理
4.1 系统用户
进入用户管理页面,可以看到如下几个用户,除管理员以外,还有3个内置机器人账户
3个内置机器人账户对比如下:
| 对比项 | GitLab Alert Bot | GitLab Duo | GitLab Support Bot |
|---|---|---|---|
| 邮箱地址 | alert@a79907fffb0e | gitlab-duo@a79907fffb0e | support@a79907fffb0e |
| 主要用途 | 告警通知和监控 | AI 智能助手 | 服务台和工单管理 |
| 核心功能 | • Prometheus 告警 • 系统性能监控 • 安全事件通知 | • AI 代码建议 • 智能代码生成 • MR 摘要 | • 处理支持邮件 • 创建工单 Issue • 自动分配任务 |
| 典型场景 | CI/CD 流水线失败告警 | 代码编辑器智能提示 | 用户发邮件报告 Bug |
4.2 添加用户
参考如下方式添加用户:
添加成功后如下:
4.3 添加成员
可以针对某个群组或某个项目添加成员,最大角色和访问到期日期根据实际情况选择,访问到期日期若不选择表示永久有效。
若针对某个群组添加成员,则该群组下的所有项目均会集成该成员。
- 添加群组成员
参考如下方式:
各角色权限对比如下:
| 角色 | 英文名称 | 权限级别 | 主要权限 | 典型用途 | 能否推送代码 | 能否合并 MR | 能否管理项目 |
|---|---|---|---|---|---|---|---|
| 访客 | Guest | 最低 | 查看 Issue 评论 Issue 查看公开内容 | 外部协作者、临时查看者 | 否 | 否 | 否 |
| 计划者 | Reporter | 低 | 查看代码 下载项目 创建 Issue 查看 CI/CD | 产品经理、测试人员、项目管理 | 否 | 否 | 否 |
| 报告者 | Developer | 中 | 推送代码 创建分支 创建 MR 管理 Issue | 开发人员(最常用) | 是 | 否 | 否 |
| 开发者 | Developer | 中 | 同上(与报告者相同) | 开发人员 | 是 | 否 | 否 |
| 维护者 | Maintainer | 高 | 合并 MR 保护分支 添加成员 管理 CI/CD | 团队 Leader、核心开发 | 是 | 是 | 部分 |
| 所有者 | Owner | 最高 | 删除项目 转移项目 管理所有设置 管理所有成员 | 项目负责人、管理员 | 是 | 是 | 完全 |
添加成功后如下:
选择该群组下某个项目,查看成员,可以看到继承了群组成员,如下所示:
- 添加项目成员
参考如下方式:
添加成功后如下:
5 总结
本文主要讲解了使用docker容器部署Gitlab的方法,并给出了常规配置及代码拉取、推送的示例。