自建Git服务这个事,这些年问的人越来越多。尤其是2025年这个节点,团队代码资产安全、合规审计、内网隔离这些需求越来越具体,GitHub/Gitee这类托管平台虽然省事,但真到了私有化、离线部署、深度定制这些环节,还是得自己搭一套。另一个现实问题是,很多中小团队一开始用免费托管挺顺手,等规模上来,要么是仓库数量受限,要么是权限粒度不够,要么是代码托管平台本身成了单点——托管方一维护、一限流,整个研发流程就卡住。这时候,自建Git工具就从“野生选项”变成了“标准答案”。
这篇文章我从实际选型角度,把2025年主流自建Git方案拉出来逐项对比,覆盖Gitea、Forgejo、GitLab、极狐GitLab、Gerrit这些高频选择,也聊一些偏门但特定的场景工具。会直接给出适合什么规模的团队、需要什么硬件资源、配置时容易踩哪些坑。不管你是个人开发者想搞个私有仓库,还是运维同学要给百人研发团队搭一套代码托管中心,这篇都能当一份可落地的选型参考。
1. 选型前先对齐认知:自建Git解决的是什么问题
1.1 自建与托管的边界在哪里
先说一个很常见的误区:很多人一谈自建Git,第一反应是“GitHub私有仓库都免费了,还自建干嘛”。这个想法只对了一小半。
GitHub、Gitee这类公共托管服务,解决的是“开箱即用”的问题,你注册账号、建仓库、推代码就行,几乎零运维。但自建Git解决的是另一组问题:代码数据主权、内网访问速度、私有化合规、深度定制能力、以及与内部系统的打通。比如你的代码仓库需要跟公司内部的统一身份认证(LDAP/AD/OAuth)对接,或者需要代码仓库在完全离线的环境里工作,再或者你的CI/CD流水线需要跟内网某个特定资源池联动,这些场景下,公共托管平台要么做不到,要么成本高得离谱。
还有一个容易被忽略的点:自建不等于自讨苦吃。2025年的自建Git工具,部署复杂度已经比五年前低了一个量级。我见过不少团队拿一台2核4G的旧服务器跑Gitea,几十个人的研发团队用了一年多都没出过问题。所以“自建=重运维”这个印象,其实更多是早期GitLab给的。
1.2 选型前需要先确定的四个基础条件
在选具体工具之前,建议先花半小时把以下四个问题想清楚,不然很容易选错方向:
- 团队规模多少?是几个人、几十人,还是几百人?这直接决定你对性能、高可用、并发评审的要求。
- 部署环境是什么?纯内网、混合云、还是海外节点?这影响你选哪个方案更顺手,尤其是镜像拉取和依赖下载的速度。
- 需要哪些核心能力?仅仅是代码托管,还是要有CI/CD、制品库、Wiki、Issue管理这些全家桶功能?
- 运维能力有多少?有没有专人维护这套系统?如果团队里没人熟悉Ruby、Go或者容器编排,那学习成本和维护成本就要算进选型里。
这四个问题没有标准答案,但它们决定了你的选型范围。比如你只想托管代码,那上GitLab全家桶就是浪费;如果你要合规审计、分级权限、MR审批流,那Gitea的基础权限模型可能会让你改到怀疑人生。
1.3 2025年主流自建方案的版图速览
按使用场景大致分三类,大家心里有个数:
第一类是轻量级代码托管,代表是Gitea和Forgejo。部署简单、资源占用极低、界面清爽,适合个人、小团队,以及“只要基本托管+轻量权限”的场景。Forgejo是Gitea的一个社区分支,理念上更强调去中心化和开放性,功能和Gitea高度相似。
第二类是重量级DevOps平台,代表是GitLab(CE/EE)和极狐GitLab(JH)。功能全家桶,包含代码托管、MR评审、CI/CD、容器镜像库、依赖扫描、安全治理等。适合中大型团队、对DevOps一体化要求高的组织。缺点是资源占用大、部署运维复杂度高。
第三类是专业化Code Review工具,代表是Gerrit。它对“评审-合入”这件事非常激进,一个commit必须经过严格的review流程才能入库。适合对代码质量极致的团队,比如大型开源项目、内核开发这类场景。但它的工作流对普通团队来说偏重,日常开发会觉得繁琐。
图形化的管理界面对小团队是加分项,但对运维老手来说,很多时候反而是累赘。小团队可以靠配置文件搞定的事情,上全家桶就是给自己找事。这个判断标准,大家选型时要始终记着。
2. 主流方案横向拆解:Gitea、Forgejo、GitLab、Gerrit怎么选
2.1 Gitea:轻量托管的低成本首选
Gitea是一个用Go语言写的开源Git服务,可以从一个单二进制文件运行,对硬件的要求低到令人发指——官方推荐配置只需要1核2G,我甚至见过有人在树莓派上跑过。它支持多种数据库后端,比较推荐SQLite起步、MySQL或PostgreSQL上量。对新手来说,Gitea的安装体验非常友好,下载解压、配置好基本项、启动服务,几分钟就能用起来。
从功能上看,Gitea除了基础的代码托管、分支保护、Pull Request和管理后台,还内置了轻量级的Issue、Wiki、项目看板、Webhooks、以及仓库镜像同步。这些功能跟GitLab比当然不全,但实际操作中,一个小团队日常用到的核心功能基本都覆盖了。2025年发布的Gitea 1.21/1.22版本,还完善了Act Runner(自托管CI),用它跑一些简单的构建任务也够用。
Gitea的权限模型走的是“用户-组织-团队-仓库”路线。可以给组织设多个团队,不同团队绑定不同仓库的读、写、管理权限。大部分小团队用这套模型就足够了。不过有一个槽点:它的权限识别粒度比GitLab要粗,如果你们有“同一个仓库里不同目录划分不同可见范围”这类需求,Gitea做不了,得考虑GitLab。
部署方式上,Docker Compose是最常见的路线。Gitea官方提供了容器镜像,配合Caddy或者Nginx反代,半个小时内能跑起来。升级也很简单,换镜像版本、重启容器就行。数据迁移成本也低,Git本来就分布式的,仓库直接裸库复制,用户和权限数据存在数据库里,整体迁移并不复杂。
2.2 Forgejo:Gitea分叉后的开源社区选择
Forgejo是2022年从Gitea分叉出来的,起因是Gitea项目当时被一家商业公司收购后引发了社区对治理模式的担忧。Forgejo主打的是“非营利、社区驱动、完全开放治理”,代码托管在欧洲一个非营利组织Codeberg名下。
功能层面,Forgejo和Gitea重合度超过90%,基本使用体感几乎一样。但2024到2025年这段时间,两个项目实际上在往不同方向演进。Forgejo更强调去中心化和ActivityPub联邦功能,意思是未来不同实例之间可以互联互通;而Gitea则更聚焦在传统单实例功能的稳定和打磨。
选型建议很直接:如果你们团队更看重“社区自主可控”“不被商业公司绑定”,Forgejo是更稳的选择;如果只想要一个成熟稳定、社区生态更大、文档和教程更多的方案,那Gitea依然胜任。从运维角度看,两者几乎一致,Docker部署、数据目录结构、环境变量配置方式都大同小异。我自己做过从Gitea迁移到Forgejo的实验,直接把仓库裸库和数据库搬过去,基本30分钟搞定。
这里要多说一句:很多人会觉得“开源就是免费、无商业公司介入”,其实2025年的开源世界,商业公司与开源项目的关系非常复杂。Gitea被收购后依然保持开源,但对某些需要长期稳定供应链的团队来说,治理模型的变化本身就是一个潜在风险。Forgejo的出现,本质上是社区对这种风险的一种“对冲”,所以选型时把治理模式纳入考量是合理的,特别是对国企、事业单位这类看重合规背景的团队,尤其值得关注。
2.3 GitLab与极狐GitLab:全家桶的能力上限
GitLab分为CE(Community Edition)和EE(Enterprise Edition),CE免费、功能丰富,EE收费、多了更细的权限控制、审计事件、安全扫描等高级特性。
GitLab的优势在于“全家桶”这个定位。除了代码托管和MR评审,它内置的CI/CD是自建Git方案里最成熟的——.gitlab-ci.yml一套配置,从编译、测试、部署到发布全都串起来。这个能力,Gitea系的Act Runner和它不在一个量级。对于想要无缝衔接DevOps流水线的团队来说,GitLab是一个很自然的入口。
但GitLab的资源消耗是真的高。最低配置虽然写着2核4G,实际跑起来你会发现很不流畅。我们团队第一次装GitLab CE,给了4核8G,跑了一个多月后内存占用长期满格,后来升到8核16G才稳定下来。Gitea能做到的事,GitLab要多吃一个数量级的资源。这个差距背后主要原因是技术栈:GitLab是Ruby on Rails + Go Sidekiq等多进程复杂架构,而Gitea是单Go二进制——架构本身决定了资源消耗的起点。
极狐GitLab(GitLab JH)是GitLab Inc.与国内公司成立的合资公司运营的版本,同样基于GitLab EE二次开发,但做了本土化适配:内置了国产化适配、中国区部署优化、以及一些合规要求相关的调整。它的授权模式和纯GitLab CE不同,商业化路径更贴近国内团队的购买习惯。如果团队对信创、等保有硬性要求,极狐GitLab往往是更省心的选择,毕竟纯GitLab EE的合规咨询、采购流程、技术支持在国内是有落差的。
版本选择建议:先想清楚你需要哪些能力。如果只是代码托管和MR,GitLab CE就够用;如果要企业级权限矩阵、审计日志、多级审批流,那要么上EE或极狐GitLab,要么直接考虑Gitea+外部工具的替代组合。
补充一个很多人在意的点:GitLab的升级迁移是出了名的“渠道复杂”。从CE升到EE是小问题,但从旧大版本直接跨到新大版本(比如15.x直接跳17.x),官方强烈建议分段升级,因为数据库迁移和背景迁移在跨大版本时容易崩。这部分一定要在选型时评估好:负责维护这套系统的人,是否愿意承接这类运维复杂度。
2.4 Gerrit:代码评审驱动的特殊流派
Gerrit在自建Git工具里算是异类。它由Google发起,最初是为了管理Android开源项目而生。它的核心逻辑是“每笔提交必须经过在线评审才能合入”,不是先推到主干再评审,而是所有提交都先进“待评审区”,经过reviewer验证、approve之后才真正合入代码库。
这种模型和一个关键概念挂钩:Gerrit把“推送”和“合入”彻底拆开了。普通开发者的git push实际上推到了一个引用空间 refs/for/master,而不是真正的master分支。通过这样的机制,Gerrit能确保每一行进入主干的代码都经过了至少一个人以上的review。这对质量敏感型团队来说非常有价值。
但代价也很直观:工作流变了。开发者不能像GitHub/GitLab那样随便开PR,而是要用git review这类工具配合Gerrit的Change模型。Git命令从git push变成git review,分支合并方式从本地merge变成线上rebase,团队每个人都要重新适应。对非重度代码评审需求的团队来说,这个学习成本偏大。
从资源的视角看,Gerrit是Java体系的,基于Apache Gerrit + Java虚拟机运行,比Gitea重,但比GitLab轻。它不内置CI/CD、Wiki、Issue这些,专注做好“代码评审”这件事。如果团队已经有一套成熟的CI系统(比如Jenkins),只是想找一套更严格的评审工具,Gerrit可以做很漂亮的互补。
选型时切记一点:Gerrit不适合把它当“普通Git托管+顺手开个PR”的场景来用。它天生是为了“严格协作”而生,如果团队文化和流程还没有到那个成熟度,上了Gerrit只会让“每天push代码”这件本该简单的事变复杂。
2.5 其他值得关注的补充方案
主流的聊完,顺手再补充几个特定场景下值得留意的方案:
- Gogs:Gitea的前身,曾经很流行,但现在更新节奏明显放缓,新项目不太建议选它做长期承载。它的Web界面和功能比Gitea简单,优点是内存占用更低,适合特别老的硬件。
- Bitbucket Server:Atlassian出品,2021年后官方已经停止售卖新许可证,现有老用户可以继续用,但新团队不建议入坑。它的优势是和Jira深度集成,很多老团队因为Jira生态还挂在上面。
- 自建裸库 + Ginatra/cgit:极客路线。直接在服务器上用git init --bare建裸仓库,再用cgit之类的Web前端去浏览代码。适合个人学习Git原理,或者单仓库极简场景,不适合作为团队协作的主工具。
- 基于对象存储的Git LFS方案:严格说不是“Git服务”,但代码仓库上了规模、依赖大二进制文件时,LFS的存储方案选型同样会影响“自建Git体验”。GitLab自带的LFS管理、Gitea的LFS插件、以及独立LFS服务器,各有适用边界。
选择标准就一条:不要被工具的功能列表牵着走。先看团队的核心痛点到底是什么,再反推哪个方案能解决、能顺手解决多少。这也是我整篇文章最想说的一句话。
3. 核心能力对比:一张表看清差距
3.1 功能与性能对照表
选型最终要落到细节参数上。下面这张表是我按2025年各项目最新稳定版整理的横向对比,大家可以随手存下来:
| 对比维度 | Gitea | Forgejo | GitLab CE | 极狐GitLab (JH) | Gerrit |
|---|---|---|---|---|---|
| 开发语言 | Go | Go | Ruby + Go | Ruby + Go | Java |
| 最低硬件建议 | 1核2G | 1核2G | 2核4G起步,实际建议4核8G以上 | 同GitLab | 2核4G |
| 代码托管 | 支持 | 支持 | 支持 | 支持 | 支持 |
| Pull/Merge Request | 支持 | 支持 | 支持 | 支持 | 支持(以Change为核心) |
| Code Review流程 | 基础 | 基础 | 较强,支持多级审批 | 较强,支持多级审批 | 极强,强制评审 |
| CI/CD | 内置Act Runner,轻量 | 内置Forgejo Runner,轻量 | 内置GitLab CI/CD,功能强大 | 内置GitLab CI/CD,功能强大 | 不内置,需外部CI配合 |
| 内置容器镜像库 | 支持(较基础) | 支持 | 支持 | 支持 | 不支持 |
| Wiki/Issue/看板 | 支持 | 支持 | 支持 | 支持 | 不支持 |
| LDAP/AD集成 | 支持 | 支持 | 支持 | 支持 | 支持 |
| OAuth/SSO | 支持 | 支持 | 支持,成熟度高 | 支持,成熟度高 | 支持 |
| 细粒度权限 | 一般 | 一般 | 强 | 强 | 一般 |
| 审计日志 | 基础 | 基础 | 强(EE更强) | 强(合规审计完善) | 基础 |
| 部署方式 | 二进制/Docker/K8s | 二进制/Docker/K8s | Omnibus/Docker/K8s | Omnibus/Docker/K8s | WAR包/Docker |
| 社区生态 | 很大 | 较大 | 很大 | 国内服务完善 | 中等 |
| 典型适用规模 | 个人/中小团队 | 个人/中小团队 | 中大型团队 | 中大型团队/政企 | 注重评审流程的团队 |
不算GitLab系的话,Gitea和Forgejo这条线把“轻量”做到了极致,而Gerrit则是“评审严谨性”的尖兵。选型时不用追求“全能”,更重要的指标是“匹配你的主要矛盾”。
3.2 资源开销不只是数字问题
很多人看硬件资源对比,只盯着“够不够跑”,这是不够的。运营一个自建服务,硬件开销背后还藏着三个隐性成本:备份成本、升级成本、排障成本。
拿GitLab举例,一台4核8G机器跑GitLab CE,内存吃饱之后,GitLab自身的备份流程(gitlab-backup create)会非常吃力。如果仓库大了,备份期间甚至会拖慢正常服务响应。反观Gitea,备份就是拷走整个目录加一个数据库dump,简单两个字。升级方面更明显:Gitea升级可以靠替换二进制或换镜像搞定,GitLab跨大版本升级则要查升级路径图,有时候还要先升到中间版本再升到目标版本,光是维护这个节奏就要单独立一条SOP。
所以资源开销不仅是“钱”的问题,更是“运维复杂度”的乘法因子。如果一个团队的运维力量本来就薄弱,选Gitea更现实。如果团队有专职运维且对DevOps一体化有强需求,GitLab的复杂度才是可接受的。
3.3 仓库规模与性能的实测参考
关于“大仓库”,轻量工具是不是就搞不定?这得看“大”到什么程度。
以我自己测试过的数据为例:一个包含约5万次提交、单个裸仓库体积约8GB、有大量二进制历史文件的仓库,Gitea的网页浏览、提交历史加载、Tag管理都还流畅,但做diff和在线代码搜索时会有一点延迟。同样的仓库在GitLab上表现反而更稳定一些,尤其是它的高级代码搜索(Advanced Search)能靠Elasticsearch支撑,索引完搜代码飞快,这是Gitea系目前比不了的能力。
如果团队的仓库主要是代码文件、体积在1GB以下、提交频率正常,那Gitea/Forgejo完全没问题。但如果仓库动辄几十GB、大量LFS文件、全组每天都在频繁做跨分支diff,那GitLab系或者Gerrit这类Java生态的工具更兜得住。选型时可以做一个粗糙的预判:未来两年内,你们最大的仓库体积会膨胀到多少?以及仓库面积的增长主要来自代码、大文件、还是操作频次?带着这些问题去看方案,比单纯对比特性清单靠谱得多。
4. 分场景选型建议:按团队状态对号入座
4.1 个人开发者:仓库托管的第一台服务器
自己的私活代码、实验项目、以及不方便往公共平台放的脚本,个人开发者自建Git图的就三件事:省事、隐私、不花钱。
Gitea是这个场景下的单推。一台云服务器最低配(1核2G即可),装好Docker和Caddy,拉一个Gitea镜像,剩下的就是把数据卷挂到宿主机目录。日常push/pull速度比公共托管快出一个量级,毕竟物理距离近、没有平台限流。甚至可以不用单独买域名,IP加端口也能凑合用,只是配上反向代理和HTTPS更安心。
唯一要提醒的是:不要在折腾工具上花太多时间。个人场景下Gitea直接上SQLite后端,不需要上MySQL,免得没事还要维护一个数据库服务。备份就是压缩整个数据目录,隔三差五扔到对象存储或者另一台机器就行。记住,个人自建服务的核心目标是为代码服务,不是为运维服务。
4.2 中小型团队(10~50人):平衡功能与维护成本
这个规模段我看过的真实案例最多,也是最容易“上错车”的区间。常见错误有两个:一是图省事选Gitea但没想清楚未来的CI/CD需求;二是觉得GitLab才“正规”结果硬件和维护全部超预算。
这个阶段我建议分三步走:
第一步,先确认“核心需求是否超过Gitea的能力上限”。如果只是代码托管、Protected Branch、Issue跟踪、以及轻量CI,Gitea就是最优解。部署在2核4G的服务器上,开SSH和HTTPS两个入口,不用单独搞高可用架构,日常运行极其稳定。
第二步,快速看团队对CI的依赖程度。如果需要相对完整的流水线,又有专人维护环境,可以考虑上GitLab CE。但前提是硬件至少给到4核8G以上,并且要预留出升级备份的时间预算。如果团队里没有专人愿意投入这个运维,那还是用Gitea/Forgejo配合外部GitLab Runner或Jenkins,自己搭一条轻量流水线更稳妥。
第三步,留好迁移的退路。Git是分布式的,仓库迁移很轻巧,但Issue、Wiki、MR历史这些“元数据”就绑死在服务里了。如果团队预判未来三五年内有可能上GitLab全家桶,那从一开始就选GitLab更省心,否则迁一次元数据能让人脱层皮。
4.3 中大型团队(100人以上):一体化平台与合规需求
团队到100人以上后,对自建Git的需求会从“能不能托管代码”升级成“能不能支撑研发流程本身”。权限矩阵要更细,审计日志要能查,MR评审要有迹可循,CI跑起来要稳定,账号系统要跟公司SSO打通。这些东西单独拼装是可以,但维护多个系统的成本会陡增。
这个阶段GitLab CE或EE是主流,理由简单:一套系统覆盖代码、CI、制品库、安全扫描。尤其当研发规范要求“从提交到部署全链路可回溯”时,GitLab的审计日志和流水线记录能比较完整地还原问题现场。如果是政企单位,或者业务涉及等保合规,极狐GitLab(JH)会更对路,不光是因为本土化好,更重要的是它在国产化软硬件适配、等保测评材料、技术服务响应这些维度上比纯开源版更省心。
高可用是另一个绕不开的话题。100人以上的团队,单体GitLab挂一次可能影响整个研发节奏。建议至少做“主备”而不是“单机”。GitLab官方支持了多种HA方案,最省事的是通过K8s部署配合云厂商的托管数据库和对象存储,把有状态的部分抽出来,这样GitLab实例本身可以做到快速重启和水平扩展。架构复杂度上去了,但这是大团队必须交的“运维税”。
4.4 重视Code Review的团队:Gerrit的适用边界
如果团队把“代码评审”当作质量生命线——典型场景是嵌入式、底层内核、对稳定性极敏感的业务系统——那Gerrit值得认真评估。
举个例子:你有100个开发者并行往一个核心仓库提交代码,每次提交都要求至少两个reviewer严格审阅并通过CI验证后才能合入主干。Gerrit的Change模型能把这类流程管得非常清楚,评审意见、补丁版本都挂在同一个Change上,修改历史一目了然。GitLab虽然也能做MR审批,但它的核心模型是“分支合并”,在严格的“逐Commit评审”上,Gerrit更彻底。
但别忘了,Gerrit也有明确的天花板:它不做CI,不做制品管理,不做Issue跟踪。你仍然需要一整套外部工具来补全DevOps链路。而且团队学习成本不低,不是所有开发者都愿意切换git push的习惯。我的建议是:除非你的团队已经有强烈意愿去推行严格评审文化,否则不要因为“听说Gerrit质量高”就上。工具只是辅助,流程才是最重的部分。
5. 部署与维护实操:选型落地第一步
5.1 轻量路线:Docker Compose快速部署Gitea
选型选了半天,不如直接上手跑一遍。下面给一套我常用的Gitea Docker Compose配置,适合在Linux服务器上快速验证:
version: "3" services: gitea: image: gitea/gitea:1.22 container_name: gitea environment: - USER_UID=1000 - USER_GID=1000 - GITEA__database__DB_TYPE=sqlite3 - GITEA__service__DISABLE_REGISTRATION=false - GITEA__service__REQUIRE_SIGNIN_VIEW=true - GITEA__server__DOMAIN=git.example.com - GITEA__server__ROOT_URL=https://git.example.com/ - GITEA__server__SSH_DOMAIN=git.example.com - GITEA__server__SSH_PORT=2222 ports: - "3000:3000" - "2222:22" volumes: - ./gitea:/data restart: always这里面有几个点要专门说:
SSH_PORT=2222是因为我习惯把宿主机的22端口留给系统SSH,Gitea的SSH服务走2222映射。这样开发者在clone仓库时,需要把SSH地址写成ssh://git@git.example.com:2222/user/repo.git。如果嫌这个多绕一层麻烦,直接用HTTP克隆也行。GITEA__service__REQUIRE_SIGNIN_VIEW=true是让非登录用户看到登录页而不是直接看公共仓库列表。如果你是纯私人仓库,建议开启。- 数据卷直接挂宿主机目录,备份时打包整个
gitea目录即可。升级就改镜像版本号,容器重建后数据都在。
启动后浏览器访问服务器IP:3000,首次会跳到安装引导。填好站点名称、数据库类型(SQLite)、管理员账号,几分钟就能建好。
5.2 重载路线:GitLab Docker部署注意事项
GitLab的部署体积和流程都比Gitea重,但也不算复杂。用Omnibus Docker镜像是最常见的路线:
sudo docker run --detach \ --hostname git.example.com \ --publish 443:443 --publish 80:80 --publish 2222:22 \ --name gitlab \ --restart always \ --volume $GITLAB_HOME/config:/etc/gitlab \ --volume $GITLAB_HOME/logs:/var/log/gitlab \ --volume $GITLAB_HOME/data:/var/opt/gitlab \ --shm-size 256m \ gitlab/gitlab-ce:latest跑起来之后,第一次启动要等3~5分钟做初始化,期间CPU和内存会飙高,这很正常,别看着负载高就以为坏了。初始化完成以后,用docker exec gitlab grep 'Password:' /etc/gitlab/initial_root_password拿到root初始密码,登录后台第一件事就是改密码、关注册、配置SMTP。
GitLab的配置改起来和Gitea完全不同。Gitea是启动时读取环境变量,GitLab则是改/etc/gitlab/gitlab.rb后执行gitlab-ctl reconfigure。比如配HTTPS、关掉一些不需要的模块(比如不需要的Prometheus监控),都在这个文件里动。搜索量大、教程多,遇到问题基本能靠关键词查出来。
5.3 反向代理与HTTPS:统一入口的标配做法
不管选哪个工具,我都强烈建议在服务前面挂一层反向代理。一方面是把80/443统一接管,方便日后换域名或换后端;另一方面是HTTPS证书的申请和续期,集中在一个入口处理,比每个服务各自搞省心得多。
Caddy是2019年之后我最常用的选择,配置简单到感人:
git.example.com { reverse_proxy 127.0.0.1:3000 }这个配置会自动申请和处理Let‘s Encrypt证书,不需要手动配证书文件。Nginx的话要自己管证书,但好在灵活度高。如果服务器在国内,需要注意Let's Encrypt的连通性,也可以换成云厂商的免费证书,几个月手动续一次,成本也低。
5.4 备份与恢复:自建服务最容易翻车的环节
备份这件事,重要到我愿意用一整节来强调。因为它是所有自建服务里初期最容易被忽略、后期出事时最要命的点。
Gitea的备份简单粗暴:把数据目录复制走就算完事。但我建议用官方提供的备份命令gitea dump,它会连数据库、仓库、配置一起打包成一个zip文件,适合定期跑。GitLab则是走gitlab-backup create,它会做数据库和仓库的归档,配置文件通过/etc/gitlab卷的备份来覆盖。
我的实操建议是双保险:
- 每日全量备份到本机另一个磁盘目录;
- 定期再把备份文件同步到异地(可以是云对象存储或另一台服务器)。
恢复演练一定要做。选型上了、部署好了、天天自动备份,但从来没人去验证“备份能不能恢复”,等到真出了事才发现备份文件损坏,这是比没做备份更惨的结局。最少每季度手动演练一次“整机恢复”再到架空环境跑一下,确认真的能拉起来,才算备份闭环。
6. 常见问题与避坑经验:来自一线的血泪教训
6.1 SSH端口冲突与克隆地址的坑
自建Git最容易踩的第一个坑就是SSH端口冲突。宿主机22端口被系统SSH占着,Git服务只能另选端口。很多新手没注意,导致clone地址永远是ssh://git@host:2222/user/repo.git这种格式,到另一台机器上怎么都连不上。
排查方法:先ssh -p 2222 git@host看返回信息,Gitea等正常的服务会打印欢迎语和一段说明;如果提示Permission denied或者Connection refused,去看服务是否在监听、防火墙有没有放行。另外还要注意云服务器安全组,很多云厂商默认只放行22、80、443,2222这种自定义端口需要在安全组里单独开。
6.2 大仓库推送超时与HTTP缓冲区
Gitea这类Go服务默认走Git原生HTTP,推送大仓库时,如果Nginx或Caddy没配好client_max_body_size,会在push过程中出现“413 Request Entity Too Large”。部署时访问量大或者仓库体量大,一定要提前改反代配置。
Nginx示例:
server { listen 443 ssl; server_name git.example.com; client_max_body_size 1024m; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }Caddy则默认对请求体没有限制,不需要额外配置。GitLab自带Nginx,默认限制也够,但如果你再套一层Nginx,依然要调。
6.3 LDAP/SSO打通时的属性映射
团队内部已经有AD或LDAP,自建Git服务要跟它对上,这一步看着简单,实际容易翻车。Gitea和GitLab都支持LDAP认证,但默认属性映射都得改。
比如很多AD环境里的用户姓名字段是displayName,不是OpenLDAP常用的cn;邮箱字段有些环境下叫mail,有些叫userPrincipalName,不一致会导致登录后用户名全是数字ID或者邮箱为空。配置时建议先在本地用ldapsearch确认清楚实际返回的属性名,再往Gitea/GitLab里填映射关系。
Gitea的LDAP配置入口在后台管理面板,GitLab在gitlab.rb里的gitlab_rails['ldap_servers']一段,两者都不难,但务必先小范围测试账号,再全员放量。
6.4 CI Runner与自建仓库的联动问题
选了Gitea/Forgejo,自带的轻量CI Runner(Act Runner)在使用上比GitLab Runner多了一些小坑。最常见的是容器执行器在Docker-in-Docker模式下权限不足,官方文档更新也比较频繁,版本升级后配置格式可能变化。
如果团队本身已经有Jenkins、GitHub Actions这套体系,那Gitea的CI可以完全不开,代码托管归托管、流水线归流水线,集成靠Webhook触发就行。没必要为了“全家桶”硬把CI塞进Gitea,反而给自己增加排查问题的范围。
6.5 升级大版本的顺序焦虑
GitLab跨版本升级最考验团队耐心。官方有Upgrade Path文档,明确列出了一些必须经过的中间版本。比如老版本是14.x,直接升到17.x是不可取的,因为数据库架构和后台任务队列跨得太大,容易导致升级过程卡住甚至数据损坏。
经验做法:先看看当前版本离目标版本隔了几个大版本,如果超过两个,就按半个月一次的节奏逐版本升级。每次升级前,先全量备份,升级后看后台任务队列是否跑完,跑完再继续下一步。Gitea在这方面轻松得多,它的小版本升级基本是向前兼容的,备份好数据目录,换镜像版本重开容器就行。
6.6 权限管理混乱:谁动了我的main分支
最后说一个“软性坑”:很多人自建Git时,权限配置太随意,后期一定会出现“某成员误删分支”“临时加的人忘了移除”“main分支谁能push谁都行”这类问题。
实操上,建议从建号第一天就明确规范:
- 仓库管理员单独设一个Team,只有少数人有管理权限;
- 主干分支开启Protected Branch,禁止直接push,只允许通过MR合入;
- 所有External用户、Guest用户都放到独立的只读组里,避免权限扩散。
这些规则在Gitea和GitLab里都配置在仓库设置里,操作不复杂,但贵在“从第一天就执行”。等仓库乱了、权限乱了再去整理,运维成本和时间成本都远高于一开始就动手。
7. 写在最后的一场迁移实验
大概一年前,我把一个20多人团队的自建Git从Gitea迁到了Forgejo,原因是团队里有同事对Gitea被商业公司收购后的治理模式有顾虑。整个迁移过程没有想象中麻烦:先把Gitea的数据目录做了完整快照,然后在另一台机器起一个同版本的Forgejo实例,导入同一个数据目录,重启服务,仓库、用户、权限、Webhook全部原样恢复。我们没有做任何数据转换,Forgejo完美兼容了Gitea的存储结构。
但这次迁移让我更清楚一件事:选型不是选“最强”的工具,而是选“最不容易让你翻车”的工具。对那个20多人团队来说,Gitea和Forgejo在功能上没有任何差别,但团队对“由谁治理”“未来走向如何”的信任感,会成为长期维护一支研发队伍时真正的变量。
所以这篇指南写到最后,我的实操建议依然是:先看你的核心痛点,再看团队的运维底子,最后才看工具功能清单。Git自建是一件“一次选型、多年受益”的事情,花点时间把需求和场景想透彻,远比纠结于某个工具的某个小特性有价值。