ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

GitLab实战指南:从账号权限到Docker部署与仓库清理

GitLab实战指南:从账号权限到Docker部署与仓库清理 简介GitLab 是一款基于 Web 的 Git 仓库管理器为团队提供了项目托管、版本控制与协作开发的统一平台。这份《GitLab 用户手册 v2》面向需要快速上手 GitLab 的开发工程师、运维人员及技术初学者围绕从零配置到日常高频操作的完整链路进行讲解。资源包共 1 个文件为 PDF 格式整体大小 1.04MB轻量精炼方便离线查阅。手册首先介绍 Windows 环境下 Git 客户端的下载与安装接着说明如何通过 Git Bash 配置全局用户名和邮箱并详细演示 SSH 密钥的生成、导入 GitLab 服务器的过程在此基础上进一步扩展到项目创建、克隆、提交记录查看等基础操作以及 CI/CD 流水线、代码审查、权限管理等高级功能帮助读者建立系统化的使用框架。已有 537 人学习/下载既可用于个人自学也适合作为团队内部技术培训的配套参考资料。1. GitLab 用户手册 v2 到底在讲什么从“按钮在哪”到“为什么这么点”拿到《gitlab用户手册v2.pdf》的人通常不是不知道 GitLab 是什么而是已经踩过几轮坑明明照着界面点了 New Project同事却拉不到代码SSH 密钥配了三遍还是报 Permission deniedCI 跑起来全是红色。手册里每个按钮都有截图但没人告诉你这些按钮背后的权限模型长什么样所以换个人、换个环境就翻车。这份手册真正要解决的问题是把 GitLab 从“一个有网页的代码托管工具”变成“团队能顺畅复用的研发协同平台”覆盖账号注册与权限、SSH 与 HTTP 拉取、分支协作与合并请求、CI/CD以及服务器上的部署与备份。适合三类人刚接手 GitLab 的新手维护者、每天要和分支和 MR 打交道的开发、以及负责在自己服务器上跑社区版的管理员。后面的内容不按菜单顺序讲按“你马上会遇到的问题”讲。2. 从账号到仓库GitLab 使用的第一层门槛这一章是给所有人看的。团队里 80% 的“GitLab 用不了”都发生在账号和仓库之间而不是功能本身。账号审批卡住、SSH 密钥不生效、本地仓库推不上远端这三件事处理完使用体验立刻顺畅一大截。2.1 注册流程、审批状态与登录失败先搞清楚你是哪类用户GitLab 的用户分两类平台内部员工与外部协作者。大部分公司都开了注册审核新账号注册后不会立刻生效界面会挂一行提示your account is pending approval from your gitlab administrator。这个状态说明你的账号进了管理员的待审批列表不是你操作错了是管理员还没点 Approve。解决办法是找管理员确认不要反复注册新账号容易出现多个同名账号后面权限和项目归属都跟着乱。有的团队还限制了注册邮箱的域名后缀注册时填了公司域名之外的邮箱系统根本不会放行。另一种登录失败更隐蔽通过 IDE 或 API 工具连 GitLab 时提示 login failed. check api token or gitlab versionGitLab 版本对 API 的字段格式有要求老版本不认识新 token 类型。遇到这种情况先看一眼 GitLab 版本号再确认你在 Personal Access Tokens 里创建的是 access token 还是 OAuth tokenIDE 里填错了字段就会翻车。GitLab 使用教程大多只讲网页操作登录失败通常要看三个位置账号状态、Token 有效期、GitLab 版本。把这三样确认清楚比盲目重装客户端或重置密码有效得多。2.2 用 SSH 密钥连接 GitLab生成、配置与常见报错SSH 是 GitLab 最常用的拉取方式原因有两个不用频繁输密码且公钥只存在服务器上私钥不出本机。生成密钥用 ed25519 算法对 GitLab 来说兼容性足够命令如下ssh-keygen -t ed25519 -C your_emailexample.com -f ~/.ssh/id_ed25519-f 指定文件名如果你本机已经有一对密钥建议用单独文件名如 id_ed25519_gitlab避免覆盖原来的部署密钥。生成后把公钥内容复制到 GitLab 的 Preferences → SSH Keys 页面公钥是 .pub 后缀那个文件别复制私钥。然后测连通性ssh -T gitgitlab.example.com第一次连接会问你确认指纹输入 yes 后如果返回 Welcome to GitLab 就代表通了。这一步常见的失败是 Permission denied (publickey)原因通常是公钥没复制完整、复制到了私钥或者 ~/.ssh/config 里没有指定用哪把私钥。多密钥环境建议在 config 里加一段Host gitlab.example.com HostName gitlab.example.com User git IdentityFile ~/.ssh/id_ed25519_gitlab这段配置的含义是当 ssh 连接到 gitlab.example.com 时使用指定的私钥文件进行认证。SourceTree 这类桌面工具配置私有 GitLab 服务时也要在工具设置里把 SSH 客户端指向这个私钥否则工具会绕开你的 ssh 配置再报一遍同样的错。如果公司服务器改了 SSH 端口config 里再加一行 Port 对应端口即可修改后立即生效。提示如果服务器上被人改动过 sshd 配置SSH 连不上属于正常现象改走 HTTP Personal Access Token 也能克隆不必死磕 SSH。2.3 导入项目与本地推送两条主流入口的边界“GitLab 导入项目”有两条路径从外部地址导入以及本地仓库推到指定新仓库。从 GitHub 或另一台 GitLab 导入时在 New Project 里选 Import Project填外部仓库 URL 和访问令牌GitLab 会保留提交历史与分支。这条路径对迁移友好但不适合导入体积特别大的仓库导入过程会占用服务器 CPU 和磁盘建议在低峰期操作。本地已有仓库推送到指定仓库则更常见尤其是团队从旧平台迁到自建 GitLab 的场景cd existing-project git remote add origin gitgitlab.example.com:group/project.git git push -u origin master如果你的默认分支是 main把 master 换成 main。加 -u 是为了把本地分支和远端分支做关联后续直接 git pull、git push 不再带参数。如果远端仓库里已经初始化了 README 或 LICENSE推送会被拒原因是非 fast-forward。这种情况要么先 git pull --rebase origin master 把本地历史接上去要么在新建仓库时故意不勾选初始化文件。新建空仓库时GitLab 会给出三种推送指引已有文件夹、已有仓库、空白仓库“GitLab 新增项目流程”指的就是这个入口选“已有仓库”最省事。还要提一句删除仓库。GitLab 默认禁止通过界面直接删除项目需要在管理后台开启删除权限删除后仓库会进回收站保留期内可以恢复。内部培训时我一直强调删除仓库前先确认是否有 CI 变量、Webhook 和应用 Token 绑定在这个项目上这些不会跟着回收站一起回来删了就没了。3. 日常协作的完整闭环分支、合并请求与代码评审分支模型怎么选、MR 什么时候能合并、回退用什么命令这几件事直接决定一个团队的协作效率。手册里翻来覆去讲按钮位置但真正影响体验的是规则和命令边界。3.1 分支模型选择trunk-based 与 Git Flow 怎么取舍分支模型没有标准答案但有适用范围。Git Flow 有 master、develop、feature、release、hotfix 五类分支结构清晰但在 5 人以内的小团队里维护成本偏高合并路径长每次发版要在 release 和 master 之间来回跳。trunk-based 则只有一个主干分支功能分支生命周期短合并频繁配合 CI 自动跑测试。我见过不少团队号称用 Git Flow实际上 develop 和 master 长期不同步最后发版时发现功能没进到 master这不是 Git Flow 的错是流程没跑起来。建议是10 人以内、一天多次发布的团队直接 trunk-based发布节奏固定、需要同时维护多个版本的 to B 项目用 Git Flow。还有一点容易被忽略分支命名规范要提前定。比如 feature/、fix/、release/ 前缀虽然 GitLab 不会强制但它会影响后续 MR 的检索和 CI 规则的编写。如果手册里只讲了“怎么开分支”而没讲“怎么命名”那只是操作说明不是团队规范。3.2 合并请求的完整过程目标分支、冲突处理与 CI 介入在 GitLab 里分支合并通常不是直接 git merge而是先发起 MRMerge Request。MR 的核心价值不是合并而是给代码一个“被检查和被机器人跑测试”的场所。创建 MR 时Source branch 是功能分支Target branch 是主干分支完成后页面会告诉你是否可以合并。如果出现冲突常见做法是本地把主干分支合进功能分支git fetch origin git merge origin/main # 解决冲突后 git add . git commit -m Merge main into feature branch git push重点解释两个地方为什么先 fetch 再 merge 而不是直接 pull因为 pull 会同时做 fetch 和 merge隐式操作出问题不好排查为什么冲突解决后直接 push 就能更新 MR因为 MR 关联的是分支分支更新后 MR 自动刷新。GitLab CI 在 MR 上的表现是一条 Pipeline常见配置是编译、单元测试、代码规范检查。如果 pipeline 失败MR 合并不了这是有意的设计防止坏代码进主干。如果希望“机器人先过一遍再人工评审”可以在项目 Settings → General → Merge Requests 里打开 Pipelines must succeed。分支合并时建议在 MR 标题里加上关联 issue 的引用比如 Closes #12GitLab 在合并后会自动关闭对应 issue这对追踪需求很关键。团队人多了以后每个 MR 是否有 issue 关联、是否有人 Approve都该在合并检查项里强制打开减少口头沟通成本。3.3 回退与撤销把代码状态改回你要的样子“GitLab 怎么回退到某个版本”是高频问题但问题本身经常没说清楚是回退本地未推送的提交还是回退已经推送的远端分支。这两种场景用的命令完全不同。本地提交回退用 git reset推送到远端的安全回退用 git revert。reset 会移动 HEAD 指针revert 会生成一个反向提交保留原来的历史。对于团队主干分支只建议 revert因为 reset 后需要 force push会把同事基于旧提交开发的代码搞乱。在 IDEA 里操作也很直观在 Version Control 的 Log 面板选中目标提交右键选择 Interactively Revert from Here 或 Reset Current Branch to Here。前者会弹一个对话框逐步选择提交后者直接退到指定提交。我的经验是开发机上的分支随便 reset远端共享分支一律 revert。注意reset 用了 --hard 之后工作区改动会被丢弃且无法找回。真的有人把一天的工作量丢在 --hard 上没有后悔药。回退之后还要处理本地与远端的差异。如果你被迫对共享分支用了 reset需要 git push --force-with-lease 而不是 --force。--force-with-lease 会先检查远端分支是否还是你最后一次拉取的状态如果有人在你 reset 之后推了新提交它会拒绝执行防止把别人的活覆盖掉。这个细节 IDEA 里也有对应选项在 Push 对话框里勾选 Force Lease 即可别选 Force overwrite。4. 管理员视角Docker 部署、备份与仓库瘦身如果你要把 GitLab 部署到自己服务器上这一章避不开。GitLab 社区版用 Docker 部署是最常见的做法备份与仓库清理则是长期运行的必修课。最怕的不是不会装而是装完不管半年后磁盘满了、内存爆了才来救火。4.1 Docker 部署 GitLab 社区版最小 compose 与内存控制GitLab 官方推荐至少 8GB 内存但在 Docker 环境里可以通过配置把内存占用压下来。一份最小可用的 docker-compose.yml 大概长这样version: 3.8 services: gitlab: image: gitlab/gitlab-ee:latest container_name: gitlab restart: always hostname: gitlab.example.com environment: GITLAB_OMNIBUS_CONFIG: | external_url http://gitlab.example.com gitlab_rails[initial_root_password] ChangeMe123! puma[worker_processes] 2 sidekiq[max_concurrency] 5 postgresql[shared_buffers] 256MB gitlab_rails[prometheus_enabled] false ports: - 80:80 - 443:443 - 22:22 volumes: - ./gitlab/config:/etc/gitlab - ./gitlab/logs:/var/log/gitlab - ./gitlab/data:/var/opt/gitlab shm_size: 256mGITLAB_OMNIBUS_CONFIG 是入口GitLab Omnibus 安装包启动时会把这段配置合入主配置改核心配置都从这里进。puma 的 worker_processes 和 sidekiq 的 max_concurrency 是内存占用大户小服务器上调低效果明显postgresql 的 shared_buffers 设 256MB 对小型团队足够prometheus_enabled 在资源紧张时关掉。shm_size 设置成 256m 是因为默认的 64MB 在编译或 CI 任务多并发时容易触发共享内存不足这是 Docker 场景独有的坑。启动后第一次访问会比较慢因为要初始化数据库等 curl -I http://localhost 返回 302 再开始用。如果你用的是衍生 Linux 发行版建议统一用 Docker 部署避免依赖包版本对不上。热词里“docker gitlab 占用内存过多”的答案大部分在上面剩下的来自 Prometheus 和日志。gitlab-ctl status 可以看到各服务的内存占用用 docker stats gitlab 看总量正常情况下社区版在 2GB 附近是合理的。Ubuntu 用户注意GitLab 19.x 之后只支持 24.04 这类较新版本老系统直接装会被告知不再受支持换 Docker 反而没有这个限制。遇到高危漏洞时优先做小版本升级安全公告里的修复方案通常已经合入最新版本手工打补丁风险更高。4.2 备份与恢复手动命令与恢复流程gitlab-backup 命令是 Omnibus 自带的备份工具不做这步等于没部署。手动备份命令如下docker exec -t gitlab gitlab-backup create默认备份文件名带时间戳内容包括 Git 仓库、数据库、上传文件。备份文件落在 /var/opt/gitlab/backups对应宿主机挂载的 ./gitlab/data/backups。要备份配置文件gitlab.rb 和 secrets需要单独拷贝 /etc/gitlab 目录因为 gitlab-backup 不包含配置备份搬家时缺了 这个文件恢复完服务起不来这个坑得提前记住。恢复流程需要先停掉相关服务否则数据库文件被占用会恢复失败docker exec -t gitlab gitlab-ctl stop puma docker exec -t gitlab gitlab-ctl stop sidekiq docker exec -t gitlab gitlab-backup restore BACKUP1699999999_2024_01_01_gitlab_backup docker exec -t gitlab gitlab-ctl restart恢复前备份当前状态是好习惯。我见过有人恢复失败后想回到旧版本结果旧备份也被覆盖了最后只能对着一个半坏的 GitLab 彻夜加班。自动备份可以用 crontab 每天凌晨跑保留最近 7 份备份脚本本身很简单关键是定期人工检查备份文件大小和时间戳别让备份任务悄悄失败。4.3 仓库体积失控pack 文件过大与历史清理热词里那条 pack-fb5fe7dfac8e953d5cc65d26074f72d5fa961d98.pack 很长其实说的是 Git 仓库的 pack 文件过大导致克隆缓慢或服务器磁盘报警。pack 文件过大的原因几乎都是历史里提交过大文件删除当前版本不代表 Git 历史里没有它克隆时 git 要完整下载所有历史所以仓库依旧庞大。第一步先看仓库体积git count-objects -vH如果 size-pack 超过几百 MB就要考虑清理历史。小仓库可以用 git gc 做一次常规整理但只整理松散对象对历史大文件无效。真正的做法是用 filter-repo 或 BFG 把大文件从历史里剔除然后在 GitLab 界面或者命令行强制推送git filter-repo --path big_file.zip --invert-paths git push origin --force --all强制推送之后旧提交在服务器上可能还残留需要去项目设置里执行 Repository Cleanup 或重新 pack否则服务器磁盘不会立刻释放这是很多人清完历史发现磁盘没变小的原因。整个操作序列是强制推送后在 Admin Area 里对该项目执行 GC或者重编引用让旧对象进入 unreachable 状态再等 GitLab 的后台清理任务回收磁盘。清理后要求所有开发者重新 clone 一次仓库避免旧本地仓库再次把历史推回去。注意force push 会重写远端历史团队里所有 clone 过的本地仓库都会与远端失去关联。操作前务必通知全员或选低峰时段执行别在周五下午干这事。5. GitLab 避坑清单翻车最多的五件事及对应的排查路径这章不讨论功能专注排查。以下五条是团队培训和运维里反复处理的每一条都按“现象 → 原因 → 解决”展开。5.1 账号与登录的坑审批卡住与 publickey 失效现象一新同事注册账号后登录页面一直提示 your account is pending approval from your gitlab administrator。原因管理员没有在 Admin Area → Users 里对申请账号做审批或者审批后该账号邮箱未验证。解决登录管理员账号在用户列表里找到状态为 pending 的账号点 Approve 后让同事重新登录。如果邮件验证卡住检查 SMTP 是否配置成功很多内网环境没有配置邮箱验证邮件发不出去这不全是账号问题需要管理员手动确认邮箱。还有一类情况是注册时填写的邮箱后缀不在允许名单里GitLab 设置了 restricted signup domains 后会直接拦截请求根本到不了审批队列。现象二git clone 时提示 Permission denied (publickey)但 SSH key 明明已经加进 GitLab。原因私钥路径不对、用 sudo 执行 git 命令导致找不到 /home/你的用户名/.ssh、或公司安全策略改了 SSH 端口。解决先执行 ssh -T gitgitlab.example.com 看返回加 -v 参数看具体卡在哪一步。输出里出现 no such identity 是 Git 没找到密钥出现 server refused our key 说明公钥没正确关联。sudo 执行 git 时加 -E 保留环境变量或者在 root 用户下重新生成密钥别借用用户目录的密钥文件。5.2 资源与 Token 的坑内存飙到 4GB 与 API 登录失败现象三docker 部署的 GitLab 运行一段时间后docker stats 显示内存逼近 4GB服务器开始卡。原因prometheus、Grafana 等监控组件默认开启加上 puma 和 sidekiq 按 CPU 核数自动扩容小内存机器直接被吃满。解决按 4.1 的 GITLAB_OMNIBUS_CONFIG 关闭 prometheus、调低 puma 和 sidekiq 并发然后 gitlab-ctl reconfigure 并重启容器。这是“docker gitlab 占用内存过多”的标准解法改完内存降到 2GB 以内是常态。如果关完还高用 gitlab-ctl status 看哪个服务占得多通常是 postgresql 的 shared_buffers 调太小导致它频繁读写缓存反而更活跃。现象四CI 里调用 GitLab API 或 IDE 连接时报 login failed. check api token or gitlab version但网页端登录正常。原因GitLab 不同版本对 API 的 token 校验逻辑不同老版本不支持某些新增权限范围或者 token 创建后权限范围没勾全。解决用管理员账号确认 GitLab 版本在 Personal Access Tokens 重新创建 token权限范围至少要勾 api 和 read_repository。如果 GitLab 版本较老新版 OAuth token 格式反而不被识别需要显式选旧版 access token 类型。CI 里拉代码或推送制品有条件优先用 CI_JOB_TOKEN它按 job 的临时权限走不占用个人 token 配额也少一层被泄漏的风险。5.3 合并与清理的坑CI 全绿但合并按钮是灰的现象五MR 页面合并按钮是灰的点不了CI 明明全绿。原因分支保护规则或合并检查项没有满足。常见的有目标分支被保护只有 Maintainer 角色才能合并设置了“合并前必须至少一个评审通过”但评审人还没点 Approve或者 MR 有冲突没有解决。解决看 MR 页面下方的 Checklist哪一项没打勾就是哪个原因。如果提示 Request changes要找对应评审人点 Approve而不是自行解除保护如果是因为分支保护找 Maintainer 处理管理员可以在 Project Settings → Repository → Protected Branches 临时调整合并权限。还有个小坑如果合并方式设置成“合并后删除源分支”按钮文字本身会变成 Merge and delete source branch有些新手以为是灰色其实是文案不同看按钮别只看颜色。6. 更进一步把高频操作用 GitLab API 串成自己的小工具团队从十几人变成几十人手册里那些“网页点几下”的操作就会变成负担。手动建仓库、手动加成员、手动翻 MR 列表这些动作一天重复十几次就该交给 API 了。GitLab 有完整的一套 REST API统一入口是 /api/v4认证用一个 Personal Access Token 就够。这里我放一个 Python 脚本把“列出所有项目 显示近期 MR 状态”拼在一起这也是团队晨会看板最常见的需求import requests GITLAB_URL https://gitlab.example.com/api/v4 TOKEN glpat-xxxxxxxx headers {PRIVATE-TOKEN: TOKEN} projects requests.get( f{GITLAB_URL}/projects, headersheaders, params{membership: true, per_page: 20} ).json() for p in projects: mrs requests.get( f{GITLAB_URL}/projects/{p[id]}/merge_requests, headersheaders, params{state: opened, per_page: 5} ).json() print(p[path_with_namespace], len(mrs), 个 MR 待处理)逻辑很简单先拿当前用户有权的项目列表再逐个项目拉未关闭的 MR打印数量。用这个脚本做每日待评审看板比逐个开网页快得多。参数说明membershiptrue 限定只返回我参与的项目避免拉出全平台的内网项目per_page 控制分页默认 20要做全量统计就写个循环读 next 页否则会漏项目。headers 里用 PRIVATE-TOKEN 是 GitLab 的老认证方式新版也兼容。做自动化要记住一个教训脚本不要写太全。我最早写过一个小工具能自动建项目、加 wiki、设 CI 变量功能很全结果半年后没人维护API 升级后脚本直接报废。后来只保留两三个频率最高、结构最简单的调用比如查 MR 状态、建带描述的项目、批量加成员。高频的小工具才有生命力低频的大工具最后都变成技术债。希望帮到你。本文还有配套的精品资源点击获取
返回列表