
上周一个做技术负责人的朋友问我“有没有国产 GitLab老板让我找。”这句话乍一听很简单但真聊起来才发现特别容易跑偏——因为“国产 GitLab”在不同人嘴里根本是两个意思。有人要的是“功能上对标 GitLab、数据留在境内、能私有化部署的平台”有人要的只是“国内访问稳定、免费好用的代码托管服务”。前者的答案绕不开极狐GitLab后者的答案里 Gitee 是出现频率最高的名字。我自己既帮团队自建过 GitLab也踩过迁移和运维的坑今天就把这三个方向的差异、选型思路和实操要点一次说清楚。1. “国产 GitLab”的两个答案极狐与 Gitee 的定位分野先说结论极狐GitLab 和 Gitee 根本不是同一个赛道的产品把它们放在一起比较就像拿“微信”和“企业微信”比都是社交软件但服务对象和使用方式完全不同。1.1 极狐GitLab它不是“山寨”是 GitLab 官方的中国发行版极狐GitLabJiHu GitLab是什么它不是哪个团队拿 GitLab 源码改出来的仿制品而是 GitLab 公司与中国团队合作成立的公司推出的官方发行版代码上游与 GitLab 保持一致所以你熟悉的那套 MR、Issue、CI/CD、容器仓库、Pages 功能极狐全都有界面和操作逻辑也几乎一模一样。换句话说如果团队原来就在用 GitLab切到极狐基本不需要重新学习这是它最大的隐性优势。极狐的部署形态分两种一种是直接用它的 SaaS 托管服务另一种是私有化部署把整套系统装到自己的服务器或云主机上代码数据完全由企业自己掌控。对有数据合规要求的行业来说“代码不出域”这个能力非常关键这也是很多团队把它当作“国产 GitLab 平替”的根本原因。1.2 Gitee它是“国产 GitHub”和 GitLab 不是一个物种Gitee 的定位更接近 GitHub它是一个代码托管平台核心服务是仓库托管、Pull Request、Issue、Pages、Gitee Go 之类的配套功能。国内大量开源项目和中小团队把它当成默认托管地因为它免费、访问速度快、中文友好很多知名开源项目在 Gitee 上也有官方镜像。但注意Gitee 做的事情是“帮我托管代码给我网页界面”而 GitLab 系产品做的事情是“在私有环境里部署一整套研发协作系统”。前者是 SaaS 服务后者是一套可自持的软件体系。为什么很多人把 Gitee 也当成“国产 GitLab”推荐因为对小团队来说GitLab 最常用的功能就是“仓库管理 分支合并 代码评审”这些 Gitee 都有而且完全不需要自己运维服务器。只是当你需要 GitLab 那种原生的 CI/CD 链路、细粒度权限模型和私有化部署能力时Gitee 替代起来就比较吃力了。1.3 聊方案之前先确认你要的是哪一类我给自己定了个简单的判断框架每次有人问“国产 GitLab”都会先反问三个问题想不想自己运维不想运维选托管平台 Gitee 或极狐 SaaS 版想自己掌控服务器再看极狐私有化或自建 GitLab 社区版。需不需要 GitLab 原生的 CI/CD 全家桶需要就走极狐或自建 GitLab只做代码托管和评审Gitee 够用。代码数据能不能放第三方平台能放托管平台省心不能放必须是私有化部署Gitee 企业版虽然也提供私有化但产品内核与 GitLab 差异较大。这就是下面所有对比的基础先把这个定位问题解决后面选型才不会纠结。2. 自建 GitLab 的真实成本内存、漏洞、仓库膨胀聊替代方案得先弄明白“被替代的方案”到底痛在哪。很多人想换掉自建 GitLab不是因为它功能不行而是被运维成本拖垮了。我完整经历过一遍这些坑每个都很实在。2.1 先过内存关Docker 装 GitLab 的硬件门槛“docker 安装 gitlab”是搜索热词但“docker gitlab 占用内存过多”才是真正的后续情节。GitLab 不是单个进程它默认会拉起 PostgreSQL、Redis、Gitaly、Prometheus、Sidekiq 等一大堆组件单体架构的代价就是内存占用非常夸张。官方建议低于 4GB 内存的服务器别跑实际上很多人的个人服务器只有 2GB装完直接卡死。我自己的优化思路是用GITLAB_OMNIBUS_CONFIG环境变量在 docker-compose 里关掉用不上的组件再把进程参数调小version: 3 services: gitlab: image: gitlab/gitlab-ce:latest container_name: gitlab restart: always hostname: gitlab.example.com environment: GITLAB_OMNIBUS_CONFIG: | prometheus_monitoring[enable] false puma[worker_processes] 2 puma[min_threads] 1 puma[max_threads] 4 sidekiq[max_concurrency] 5 gitlab_rails[env] { MALLOC_CONF dirty_decay_ms:1000,muzzy_decay_ms:1000 } ports: - 80:80 - 443:443 - 22:22 volumes: - gitlab_config:/etc/gitlab - gitlab_logs:/var/log/gitlab - gitlab_data:/var/opt/gitlab关掉 Prometheus 之后内存能明显降下来我自己实测大概能从 3GB 压到 1.5GB 左右但前提是仓库数量和并发不大。这段经历也说明一个道理自建 GitLab 不是装完就完事它每天都会向你收一笔“运维税”。2.2 安全补丁和版本升级不是一个周末能搞定的搜索词里“gitlab 高危漏洞修复方案”出现频率很高这背后是真实焦虑——GitLab 功能越多攻击面越大安全通告基本是季度性出。如果是企业自建就必须有人跟进补丁及时升级小版本。这还不算完新版 GitLab 对操作系统版本越来越挑剔我见过不少老服务器因为系统版本太旧压根升不了新版最后只能重装迁移风险一下子放大好多倍。我的实操建议很朴素订阅官方安全通告邮件保持小版本持续更新开启管理员两步验证有条件的限制注册方式不要裸奔开放定期备份且一定要做恢复演练——备份命令很简单sudo gitlab-backup create STRATEGYcopy但“备份成功”和“能恢复成功”是两件事没演练过之前都别信。2.3 仓库膨胀那几个 GB 的 pack 文件从哪来的搜索热词里有一条很具体“gitlab pack-fb5fe7dfac8e953d5cc65d26074f72d5fa961d98.pack 文件很大”。这种形如pack-40位哈希.pack的文件躺在 Git 仓库对象目录里是导致仓库越来越重的元凶。根因其实很少是 GitLab 本身的问题而是使用习惯问题大文件直接提交进历史、反复 rebase 和 force push 留下大量孤立对象、二进制资源没走 LFS、仓库常年不执行 gc。排查和修复的思路是这样先看仓库里到底谁占空间git count-objects -vH只清垃圾对象不碰历史git gc --prunenow --aggressive历史里已经有大文件的必须用git filter-repo或BFG Repo-Cleaner重写历史把特定路径从所有提交里剥掉。这一步会改写 SHA所有协作者都要强制重新同步必须提前通知团队。从管理侧限制开启 Git LFS、禁止提交 .zip/.exe/.jar 等二进制、设仓库大小上限。这个坑最容易出现在“团队过了两三年才想起优化”的场景越晚处理越痛苦。所以我在新团队落地 GitLab 的第一天就会把仓库规范写好比事后抢救省心太多。2.4 登录、审批、API 报错的日常消耗自建 GitLab 还有一些高频低烈度问题比如搜索词里的两条典型报错。一是“login failed. check api token or gitlab version”。这种情况大多是脚本或 CI 里配置的 Access Token 失效或 token 权限不足也可能是本地调 API 时用的参数格式和当前 GitLab 版本不匹配。排查思路固定先去 Admin Area 里找到对应 token确认 scope 是否包含api然后检查调用代码里 GitLab API 版本路径和当前实例版本是否兼容。二是“your account is pending approval from your gitlab administrator”。这是 GitLab 默认开了注册审批新用户注册后需要管理员在 Admin Area - Users 里手动激活。我以前给公司搭 GitLab 时第一周天天收到“帮忙审批账号”的私信后来直接在管理员设置里开了域白名单自动通过才消停。这些琐事单独看都不大但叠加起来就很磨人尤其团队没有专职运维的时候很多人就是被这些日常消耗磨到决定“换个省心的方案”。3. 核心横评极狐GitLab、Gitee、自建 GitLab 社区版怎么选这一节是全文重点我用一张总表开场然后每个关键维度展开说明。3.1 一张表看三个方案对比维度极狐GitLabGitee自建 GitLab CE部署形态SaaS / 私有化部署纯 SaaS企业版可私有化自己装在自己服务器功能完整度GitLab 全家桶仓库 PR Issue Pages 轻量CIGitLab 全家桶社区版功能CI/CDGitLab CI/CD 原生支持Gitee Go生态相对弱GitLab CI/CD 原生支持PagesGitLab Pages 配合 CI 自动发布Gitee Pages静态页面友好GitLab Pages 配合 CI 自动发布数据掌控私有化方案可自持托管方案由平台运维完全自持运维成本SaaS 为 0私有化仍需运维最低最高上手成本低GitLab 老用户零成本低中高要懂 Linux 和 GitLab 体系适合对象企业、对数据合规敏感团队个人、开源项目、中小团队有专职运维、追求完全掌控的团队3.2 MR 只是入口CI/CD 才是分水岭很多团队选型时只盯着“能不能开 Merge Request”这远远不够。真正的分水岭在 CI/CD。GitLab 系的 CI/CD 是内生的一个.gitlab-ci.yml文件放进仓库根目录Runner 一注册commit、MR、tag 都可以触发流水线构建产物能直接进容器仓库或 Pages整条链路不需要额外接系统。更关键的是 Runner 可以部署在你自己内网代码不出域这对很多研发团队是刚需。Gitee 的 Gitee Go 也提供 CI 能力但如果你的流水线比较复杂——多阶段并行、缓存、制品传递、动态生成文件名——Gitee Go 的成熟度相比 GitLab 还有明显差距。对只跑简单构建和部署的团队够用但对重度 DevOps 玩家会束手束脚。Pages 也是同理。GitLab Pages 配合 CI 是“推代码自动发页面”的全自动链路Gitee Pages 对纯静态网站很友好但在频繁更新、自动化发布这类场景操作手感和可控性有差别而且平台有内容管理要求发布前最好先看一遍规则。3.3 协作、权限和代码统计的差异权限模型上GitLab 系的角色很清晰Guest、Reporter、Developer、Maintainer、Owner配合 Group 层级做权限继承在几十上百人的研发团队里非常管用。Gitee 的企业版也有组织和成员管理但颗粒度和审计能力不如 GitLab 系完整。如果团队规模大了需要审计谁在什么时候改了什么、谁合并了哪个 MRGitLab 系的企业版体验要省心得多。另一个被反复搜到的需求是“gitlab 仓库代码量和注释率统计”。社区版 GitLab 没有开箱即用的统计面板我通常直接用命令行工具解决# 统计代码行数、注释占比 cloc --by-file . # 按提交者统计提交量 git shortlog -sn --allGitee 平台本身提供一些代码统计但维度和自定义能力有限。要拿到精细的“代码量 注释率”报表最靠谱的方式始终是围着本地 Git 仓库算平台那层只是锦上添花。3.4 开源许可证怎么选顺手补一个高频疑问搜索词里“gitee 开源许可证选什么”被问到很多这其实和平台无关但中文用户确实容易纠结。我的快速决策法想让大家随便用、随便改、随便商用选MIT最省事。希望有专利保护条款、企业项目友好选Apache-2.0。希望用了你代码的项目也必须开源选GPL-3.0但要注意它的传染性会劝退一部分使用者。处于两者之间、希望修改后的文件也保留相同许可可以看MPL-2.0。在 Gitee 创建仓库时选好许可证在 GitLab 里也一样。无论选哪个都记得把 LICENSE 文件放进仓库并纳入版本管理README 里最好也写一句“本项目基于 xxx License 开源”避免后续扯皮。3.5 价格背后的“总拥有成本”只看标价最容易踩坑。自建 GitLab CE 的软件费用是 0但服务器、磁盘、备份、安全补丁、升级、故障处理全要自己扛把人力算进去一年综合成本并不低。Gitee 免费版对个人和小团队非常友好但上了企业规模和私有化需求商务成本会逐渐显现。极狐GitLab 有免费的基础版本专业版和旗舰版按用户数订阅私有化部署的价格需要走商务。我的建议是不要单看“免费”两个字把“三年总成本 人力投入 风险兜底”放在一起算。很多团队选完之后才发现所谓免费方案最后都是拿自己的人力去填的。4. 迁移实操仓库导入、SSH 密钥与多账号冲突定了方案就要动真格这一节全是会反复踩的细节。我从仓库搬运、密钥配置到本地多账号冲突把最常见的坑都拆开讲。4.1 从 GitLab 搬到 Gitee/极狐的三种姿势第一种平台自带导入。Gitee 新建仓库时选“导入仓库”填 GitLab 仓库地址和 token 就能拉代码极狐也有导入工具。这种最省事适合历史简单、分支不复杂的仓库。第二种命令行纯 Git 迁移适合批量搬运也适合不想在平台界面点来点去的场景git clone --bare gitgitlab.example.com:group/project.git cd project.git git remote add new gitgitee.com:user/project.git git push --mirror new--mirror会把所有分支、tag、refs 一次性推过去比逐个分支 push 高效得多。第三种完整迁移这是我最推荐的正式做法除了代码还要把MR/Issue/CI 变量/Webhook/Protected Branches一并处理。很多人搬完代码才发现 MR 历史全没了CI 变量没导Webhook 没人配部署直接断掉只能加班补。经验之谈迁移前先导出一份 MR 和 Issue 清单重要历史能导入就导入不能导入就归档成文档别让信息断层。4.2 SSH 密钥配置的通用步骤“git 配置 gitee 密钥”这类搜索词说明好多人在第一步就卡住了。其实三大平台Gitee、极狐GitLab、GitHub配置逻辑一模一样会一次就会三次。# 1. 生成密钥用邮箱当注释 ssh-keygen -t ed25519 -C youexample.com # 2. 查看公钥内容 cat ~/.ssh/id_ed25519.pub # 3. 把公钥复制到平台的 SSH Keys 设置页 # Gitee右上角头像 - 设置 - SSH 公钥 # 极狐GitLab右上角头像 - Preferences - SSH Keys # 4. 本地测试连通性 ssh -T gitgitee.com ssh -T gitgitlab.cn常见问题无非几类公钥没复制全、文件权限不对、把私钥内容粘贴到了平台。记得~/.ssh目录权限最好是 700id_ed25519私钥是 600id_ed25519.pub是 644。PyCharm、VS Code、IDEA 上传或 clone 仓库本质上都是调用本地 git 命令配好命令行之后IDE 里填仓库地址就能正常用。4.3 本地同时存在 Gitee/GitHub/GitLab 的配置方案“本地全局设置了 gitee 和 github 两个库冲突”这条搜索词太典型了。现象一般是往 A 平台推代码时提交人名字却显示的是 B 平台的账号或者某个平台突然 push 不上去提示权限错误。根因有两个一是user.name和user.email被全局配置覆盖了。Git 的配置优先级是“仓库级 全局级 系统级”如果你在不同仓库里需要不同身份就别在全局写死而是在仓库里单独设置git config user.name 你的名字 git config user.email 你的邮箱二是 SSH key 冲突。Git 默认会用同一个私钥去连所有平台如果不同平台的账号需要不同密钥就必须在~/.ssh/config里显式指定。我的配置长这样Host gitee.com HostName gitee.com User git IdentityFile ~/.ssh/id_ed25519_gitee IdentitiesOnly yes Host gitlab.cn HostName gitlab.cn User git IdentityFile ~/.ssh/id_ed25519_jihu IdentitiesOnly yes Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519_github IdentitiesOnly yes配置好之后 clone 地址不用变git 会根据 host 自动选择密钥。IdentitiesOnly yes这行很关键它告诉 ssh 只用指定的密钥文件别把所有 identity 都试一遍。我建议不同平台用不同密钥文件虽然多一步操作但安全边界清晰出问题也好排查。5. 自建/私有化的细节落地CI/CD 与仓库治理如果你最终还是选了极狐私有化或自建 GitLab 社区版那这些落地细节是绕不开的。5.1 一个能直接上手的 GitLab CI 最小示例CI 的价值不用多讲关键是让团队快速跑通第一条流水线。以 Node.js 项目为例仓库根目录放.gitlab-ci.ymlstages: - test - build test-job: stage: test image: node:18 script: - npm ci - npm test rules: - if: $CI_PIPELINE_SOURCE merge_request_event build-job: stage: build image: node:18 script: - npm run build artifacts: paths: - dist/ - !expire_in: 1 week要点有三个第一rules控制流水线在什么时候触发比如只在 MR 事件时跑测试避免浪费资源第二artifacts会把构建产物留存下来方便后续部署或临时下载expire_in控制保留时间第三所有敏感信息token、密码一律放 Settings - CI/CD - Variables写成项目环境变量在脚本里引用严禁写进仓库。Runner 的注册也不复杂选一台机器装gitlab-runner然后用项目或群组的注册 token 执行sudo gitlab-runner registerexecutor 选docker最方便每个 job 跑在独立容器里环境互不影响。如果你选了 Gitee Go语法和平台不一样但思想完全一致阶段描述执行顺序、job 定义任务、最后产出的制品传到后续环节。只要理解了 GitLab CI 这套模型切换到其他 CI 产品也只是换个语法的事。5.2 分支模型和仓库治理别把仓库搞成垃圾场“gitee 拉取和上传项目”“gitlab 上传分支”“建立分支结构的指令”这类热搜词说明很多人还在手动管理分支。我的建议很简单小团队用主干开发trunk-based所有人频繁提交到主干用 MR 做评审发布时打 tag最简单也最不容易乱。有固定发版节奏的产品再用Git Flow或它的简化版但别让每个人拉一条长期分支堆着不合并合并得越晚冲突越大。仓库层面做硬性治理开启 Git LFS禁止提交二进制文件设置仓库大小限制定期执行 gc。这些治理规则最好在团队规范里写死并且用 GitLab 的“受保护分支”功能把主干保护起来普通人不能直接 push必须走 MR 合入。这个动作本身就能挡掉一大半仓库卫生问题。5.3 平台出问题时的定位路径自建 GitLab 最常见的场景是 502很多人第一反应是“重启大法”但重启治标不治本。我的排查顺序固定# 1. 看整体状态 sudo gitlab-ctl status # 2. 看磁盘别笑50% 的 502 是磁盘满了 df -h # 3. 看关键日志 sudo tail -f /var/log/gitlab/gitlab-rails/production.log sudo tail -f /var/log/gitlab/puma/current磁盘满、Puma 进程挂掉、Gitaly 连不上是最常见的三类根因。托管平台比如 Gitee出问题时你能做的有限一般就是看平台状态页、提工单然后等恢复。所以无论用哪个平台核心代码至少本地要有一份完整备份这是底线。6. 我的选型建议和几条实在话给个直接可抄的决策路径个人开发者、三五人小团队不想运维想免费私有仓库直接 Gitee 免费版功能对小型团队非常够用。深度使用 GitLab 全家桶需要数据私有化或合规能力首选极狐GitLab 私有化部署它是目前最接近“国产 GitLab”的答案老 GitLab 用户零成本迁移。有专职运维或 DevOps想完全掌控且预算敏感自建 GitLab CE但先想清楚内存、升级、漏洞修复这些运维成本有没有人力承接。只想轻量自建不依赖 GitLab 生态顺便看一眼 Gitea / Forgejo 这类更轻的平台对仓库数量和功能要求不高的情况下它们的运维成本低一个数量级。最后说几句个人体会。我真从 GitLab 迁出国产平台时最费时间的不是代码搬运而是 MR 历史和 CI 配置的迁移这两样东西往往比代码本身更值钱但很多人一开始根本意识不到。我的习惯是正式切换之前先内部跑一个月的并行期两边同时推代码团队先在新平台熟悉流程运维在旧平台做兜底等一切正常再关旧的。这个方法帮我躲过了好几次“切过去才发现某个 CI 变量没导、某个 Webhook 没配”的尴尬。说到底选哪一个平台不是选工具是选一套协作流程。先把团队的真实需求想清楚再回头看你手里的选项答案其实自己就出来了。