2025自建Git服务选型与部署:Gitea、GitLab、Bitbucket对比

发布时间:2026/9/20 4:26:31
2025自建Git服务选型与部署:Gitea、GitLab、Bitbucket对比
1. 自建Git服务前先想清楚这几个核心问题做技术选型最忌讳一上来就比功能清单。我在帮团队和客户搭建自建Git服务时遇到最多的场景就是几个人临时组个项目发现GitHub私有仓库名额不够用或者公司有代码保密要求源码不能放到公有云上于是决定自己搭一套。这个需求本身没有对错但动手之前有三件事必须先想明白否则后面大概率要走弯路。先说说你自建Git到底要解决什么实际问题。对个人开发者来说可能只是想要一个能存私有代码、多设备同步的远程仓库类似一个自己掌控的GitHub对三五人小团队来说需要的是代码集中管理、基本权限隔离、能看提交历史和分支动态到了几十人上百人的规模需求就复杂了包括代码评审、CI/CD集成、细粒度权限控制、LDAP/SSO对接、高可用部署。很多人在第一步就搞混了自己的需求层级比如小团队一上来就上Kubernetes集群部署GitLab结果维护成本比代码开发成本还高这就不太划算了。再一个问题是维护者的技术水平和时间预算。自建Git服务的核心成本不在安装那一刻而在后续的升级、备份、迁移、故障恢复。你是否愿意在忙完业务代码之后再去处理Git服务出现的问题团队成员有没有人能看懂部署日志和排查问题这些都会直接影响你对工具的选择结果。还有一个经常被忽略的点你未来的数据规模和团队增长速度。Git仓库和普通文件不一样它是全量历史记录的堆叠一个活跃项目两三年下来仓库体积轻松超过几个GB。如果你预期项目会快速膨胀或者团队规模会从几个人涨到几十人那工具的可扩展性和迁移成本就必须提前评估不能只看眼下够用。搞清楚这三点之后再进入具体方案的对比心里才会有底。下面我按部署复杂度从低到高逐个分析2025年目前值得考虑的主流自建方案。2. 2025主流自建Git方案横向拆解2.1 轻量级Gitea与GogsGitea在轻量级方案里基本是社区共识级的选择Gogs则是它的前辈。Gitea是Gogs的一个分支后来居上社区的活跃度和功能的丰富程度已经远超Gogs。两者用Go语言编写部署形态上都是单个二进制文件MySQL、PostgreSQL、SQLite都支持对服务器资源的占用非常小——512MB内存的VPS跑起来毫无压力甚至树莓派上都能跑得挺顺。我第一次接触Gitea时印象很深从下载二进制文件到服务跑起来前后不到十分钟。它对运维新手极其友好连数据库都可以用默认的SQLite基本就是下载、赋权、运行三步走。功能方面Gitea覆盖面相当完整包括仓库管理、Issue追踪、Pull Request、WebHook、内置CIGitea Actions、里程碑规划、组织团队管理甚至还有轻量级的项目看板。对一个二三十人的技术团队来说这些功能在日常协作中已经很难看到明显短板了。Gogs相对Gitea的优势是更轻、启动更快但开发和维护节奏明显放缓功能迭代停滞了很久。除非你有特别的历史包袱否则现在新部署我强烈建议直接选Gitea没必要在Gogs上投入时间。实际体验下来Gitea的升级路径设计得也不错小版本升级基本是替换二进制文件重启服务数据兼容性做得很到位这对自建服务来说是很重要的隐性优势。轻量级的另一大好处是迁移灵活。你随时可以把整个仓库目录和数据库打包带走从一个服务器搬到另一个服务器过程不需要停机太长时间这在自己用服务器时是很大的心理安心。2.2 企业级GitLabGitLab是自建Git方案里能力天花板最高的一个功能覆盖从代码托管到DevOps全链路包括CI/CD流水线、容器镜像仓库、依赖扫描、安全漏洞检测、需求管理、Epic/子任务拆解等。如果你不只是要一个代码仓库而是想要一套完整的研发管理平台GitLab确实是绕不开的选择。但功能全面是有代价的。GitLab基于Ruby on Rails开发自身的架构非常庞大对服务器资源的要求也比Gitea高出两个数量级。官方建议的最低配置是4GB内存但实际跑一个几十人规模的实例8GB内存才勉强从容16GB才能说得上舒服。CPU方面也建议4核及以上。如果你用虚拟主机月成本会比Gitea那套高不少而且GitLab的升级很吃时间和精力偶尔还会遇到升级后配置项变化导致服务起不来的情况这需要一定的技术储备和排障耐心。GitLab分CE社区版和EE企业版CE版本限定了部分企业级功能比如某些高级的LDAP控制、审计事件。但社区版对绝大多数中小团队来说已经非常够用了。我团队现在用的就是GitLab CE主要用于有正式流程的项目配合它的内置CI把构建部署串联起来整体用下来管理效率有明显提升。2.3 老牌劲旅Bitbucket与自托管Gitea的再比较Bitbucket Server现在叫Bitbucket Data Center是Atlassian家族的一员和Jira、Confluence的集成是它的看家本领。如果你已经在用Jira做项目管理选Bitbucket会是顺理成章的事情因为代码提交和Issue之间的联动、Pull Request与Jira工单的双向绑定都做得相当丝滑。许可证按用户数收费价格不算便宜但相比GitLab EE还是有一定优势。Bitbucket Data Center在部署上比GitLab轻量一些但也不是一个二进制就能搞定的需要Java环境、外部数据库和共享文件系统。它的代码评审体验在我用过的方案里属于上乘行内评论、任务清单、审阅人分配这些交互细节做得非常自然。如果你没有Atlassian生态的依赖Bitbucket的优势就会打些折扣它的API能力和生态丰富程度也不如GitLab和Gitea。2.4 新趋势基于云原生的自托管组合方案还有一个值得关注的思路是不完全用现成的Git服务软件而是用Gitea或GitLab作为代码托管前端配合对象存储比如MinIO、自动化备份工具比如BorgBackup或restic以及自家CI系统组成一套贴合自己业务的组合方案。这个思路适合DevOps能力比较强的团队不太适合只想开箱即用的场景。比如Gitea本身支持把仓库存储放在外部存储路径下你可以把仓库存储目录对应到挂载的NAS或对象存储接口上这样数据容量弹性就很大了。配合相应的定时任务和备份脚本既保留了轻量使用的体验又能灵活扩展。GitLab也同样支持对象存储配置把Git LFS、制品包这些大文件类数据放到S3兼容的对象存储中本地存储压力可以明显降低。这种组合方案的优点是灵活资源利用效率更高符合成本控制比较严格的团队的需求。缺点也明显——你开始为基础设施负责了对象存储挂了怎么办、备份策略怎么设计、灾备演练怎么执行每一项都需要有人跟进对小团队来说是在给自己增加工作量。我个人的建议是如果你连Git服务都没搭过别一上来就上这种组合方案先把基础的自托管跑稳再考虑锦上添花。3. 选型决策不同场景对应的最优解为了让选型思路更直白我把常见场景和推荐方案放在一张表里后面再针对每种场景详细解释选型的逻辑。场景推荐方案推荐理由个人开发者/极简需求Gitea SQLite部署极简资源占用低迁移方便5~20人小团队Gitea MySQL/PostgreSQL功能够用维护轻松支持WebHook20~100人需要CI/CDGitLab CE集成度最高流水线功能强大深度使用Jira的团队Bitbucket Data Center与Atlassian生态无缝衔接有合规/多租户需求GitLab EE / Bitbucket DC细粒度权限、审计日志满足管控要求3.1 个人开发者场景的最优解个人自建的优先级是足够轻、省心、随时能迁移。Gitea用SQLite作为数据库整个实例就一个进程加一个数据库文件备份直接把目录打包就行。不需要配置MySQL账号不需要处理数据库连接池不需要考虑缓存服务。我自己的个人代码存了一台老笔记本上装的Gitea跑了一年多内存占用稳定在两三百MB完全无感。一些文章会推荐个人用Gitea加Docker的方式部署但如果你只是想一个人用我不太建议用Docker。裸二进制部署的升级就是一个文件替换而Docker部署还需要考虑容器编排和镜像升级带来的变量。多一个人的维护心智负担在个人场景里没有必要。等以后有协作需求了再迁移到带数据库的Docker部署方式也不难Gitea的数据兼容性完全支撑这种渐进式演进。3.2 小团队协作场景为什么Gitea能扛住小团队最尴尬的节点是从拉个微信群传代码过渡到使用统一代码托管平台这一步的阻力不在于功能缺什么而在于学习成本。Gitea的界面风格和GitHub非常接近团队里用过GitHub的人基本没有陌生感这就大大降低了推广门槛。可以这样说GitHub用户迁移到Gitea的学习成本几乎趋近于零。另外Gitea支持组织级别的团队管理可以设置Owner、Write、Read等权限层级配合仓库的私有/公开属性基本满足小团队对权限问题的所有想象。分支保护规则、签名提交要求、合并请求审批这些功能它也都有只是操作界面没有GitLab那么庞大复杂但核心能力并不缺。3.3 中大型团队与正式研发流程GitLab为什么值当团队规模上来、研发流程变重以后Gitea的很多轻量假设就不成立了。比如你需要管理者能直观看到各项目的CI执行情况需要代码质量门禁卡住合并请求需要合规审计记录谁在什么时候访问了哪个仓库、拉取过什么代码这些需求GitLab能整体覆盖而Gitea就要多个系统拼凑了。GitLab的CI/CD功能尤其值得展开说。它采用.gitlab-ci.yml文件描述流水线定义在代码库中天然支持分支维度的pipeline策略。比如develop分支跑测试和构建master分支跑部署和发布配置好后全自动触发。这个能力在企业交付中会直接提升好几个层级的效率因为从代码到部署的可追溯性非常强每次部署对应哪次提交、哪个MR都能快速定位这在故障排查时有很大的价值。GitLab CE在实际运维中的资源开销确实是硬伤。我建议把GitLab部署在独立的服务器或者容器里不要和业务应用混淆在一起因为GitLab的内存占用会随活跃用户数增长持续走高而且后台的BackgroundJobSidekiq任务对CPU也有稳定消耗。曾经有一次我因为没有及时处理机器上日志膨胀导致磁盘写满GitLab直接进入了只读模式整个开发团队当天下午集体停摆从那以后我把监控和告警放在了选型工作中很重要的位置。3.4 特定生态绑定Bitbucket的取舍团队已经在用Jira和Confluence的情况下Bitbucket Data Center带来的衔接体验是最无缝的。比如开发者提交代码时只要在commit message里带上Jira任务号Jira的工单面板上就会自动显示相关提交记录代码评审的审批状态也能反馈到Jira流程中。这种联动如果自己通过WebHook实现费用不低且稳定性不一定好。但Bitbucket的许可证成本是个需要认真评估的问题。Atlassian的Server版本不再提供新许可证销售相关支持和安全更新也在逐渐收窄中小团队如果没有很强的预算和运维能力在Atlassian生态里的投入需要有长期打算。开源替代方案和插件社区的丰富程度GitLab比Bitbucket要强不少。4. 实操部署以Gitea为例的完整过程理论聊够了下面是真实可复现的部署过程。我用Gitea做示例因为它在各种场景下最容易跑通、也最通用。下面所有操作都在Ubuntu 22.04 LTS上验证过其他Linux发行版大同小异核心思路是一致的。4.1 环境准备与初始化部署前先确认服务器信息。我个人建议Gitea单独用一个普通用户运行而不是直接用root这样可以限制意外操作对系统的影响。先创建用户并规划目录sudo adduser --system --group --disabled-password --home /var/lib/gitea gitea sudo mkdir -p /var/lib/gitea/custom /var/lib/gitea/data /var/lib/gitea/log sudo chown -R gitea:gitea /var/lib/gitea sudo chmod -R 750 /var/lib/gitea文件目录规划上我习惯把custom目录理解成存放自定义配置模板和静态资源的地方data目录是仓库和数据库的实际存储位置log目录则单独作为日志输出路径。这样划分的好处是备份时只需要把data和配置文件打包日志和临时文件可以直接丢弃不用费心去筛选。4.2 下载与安装Gitea到Gitea官网或GitHub Release页面获取最新版二进制。下载时注意选对平台架构我的服务器是x86_64就用linux-amd64。安装方式很简单sudo wget -O /usr/local/bin/gitea https://github.com/go-gitea/gitea/releases/download/v1.22.0/gitea-1.22.0-linux-amd64 sudo chmod x /usr/local/bin/gitea校验文件签名是很多人会跳过的环节但我还是建议至少做个SHA256校验确保下载没有被篡改。下载安装完毕可以先手动跑一次服务测试配置sudo -u gitea GITEA_WORK_DIR/var/lib/gitea /usr/local/bin/gitea web --port 3000这时用浏览器访问http://服务器IP:3000应该能看到Gitea的首次安装引导页面。如果一切正常按CtrlC停掉手动进程然后配置成系统服务。4.3 配置systemd服务并处理SSH端口Gitea官方提供了systemd服务文件模板直接使用即可但要注意几个关键参数。我的服务文件放在/etc/systemd/system/gitea.service核心内容如下[Unit] DescriptionGitea (Git with a cup of tea) Aftersyslog.target Afternetwork.target [Service] RestartSec2s Typesimple Usergitea Groupgitea WorkingDirectory/var/lib/gitea/ ExecStart/usr/local/bin/gitea web --config /etc/gitea/app.ini Restartalways EnvironmentUSERgitea HOME/home/gitea GITEA_WORK_DIR/var/lib/gitea [Install] WantedBymulti-user.target重点说一下SSH端口问题。如果Gitea想让用户通过SSH协议克隆代码常规方式是请求服务器的22端口但22端口通常已经有系统OpenSSH服务在监听会让Gitea的SSH功能冲突。解决办法有两种一是让Gitea直接使用系统的ssh命令来代理Git SSH流量二是让Gitea使用内置SSH服务器并监听一个独立端口比如2222。我推荐使用内置SSH监听在2222端口因为这样Gitea就能完全管理SSH公钥而不影响系统账号。在安装引导页的SSH设置里填上2222然后在克隆地址上会自动带上端口号用户侧的Git命令会写成git clone ssh://git你的服务器IP:2222/owner/repo.git这个体验和默认SSH 22端口略有差别但对大多数情况来说影响不大。如果你希望用户直接走22端口就要在系统SSH配置里做更复杂的配置新手阶段不建议搞。4.4 数据库配置从SQLite到MySQL的迁移动机Gitea安装引导页会让你选数据库类型。单用户或学习环境选SQLite完全没问题但一旦有5个以上的人协作我建议选MySQL或PostgreSQL因为并发写入和数据一致性更好后续备份恢复也更灵活。MySQL数据库的创建语句很简单CREATE DATABASE gitea CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER gitealocalhost IDENTIFIED BY 这里换成强密码; GRANT ALL PRIVILEGES ON gitea.* TO gitealocalhost; FLUSH PRIVILEGES;注意Gitea配置的app.ini在数据库连接串、仓库根目录、服务端协议等参数上都有讲究建议安装后先打开/etc/gitea/app.ini核对一遍。我的常用配置片段如下[repository] ROOT /var/lib/gitea/data/repositories ENABLE_PUSH_CREATE_USER false [server] PROTOCOL http DOMAIN git.example.com HTTP_PORT 3000 ROOT_URL https://git.example.com/ DISABLE_SSH false SSH_PORT 2222 LFS_START_SERVER true [database] DB_TYPE mysql HOST 127.0.0.1:3306 NAME gitea USER gitea PASSWD 这里换成你的密码 [service] DISABLE_REGISTRATION falseDISABLE_REGISTRATION这个参数要特别留意。如果Gitea部署在公网上开放注册会很快被广告机注册垃圾账号严重影响服务体验。我建议注册功能仅限于你自己需要时打开平时关掉成员通过管理员后台手动添加或导入。4.5 备份与恢复自建服务最不能省的一课自建Git服务很容易被忽略的就是备份等硬盘损坏了才后悔是很多人的真实经历。Gitea的备份分为两部分数据库和仓库存储。如果使用SQLite备份就是把数据库文件和仓库目录一起打包如果使用MySQL需要mysqldump导出数据库然后和仓库目录打包。我的备份脚本如下用crontab每日执行一次#!/bin/bash BACKUP_DIR/backup/gitea DATE$(date %Y%m%d%H%M) mysqldump -u gitea -p密码 gitea $BACKUP_DIR/gitea-db-$DATE.sql tar -czf $BACKUP_DIR/gitea-repos-$DATE.tar.gz /var/lib/gitea/data/repositories find $BACKUP_DIR -mtime 7 -name *.sql -delete find $BACKUP_DIR -mtime 7 -name *.tar.gz -delete在恢复时顺序是先把数据库导入再把仓库目录解压回去最后调整目录属主并重启Giteamysql -u gitea -p密码 gitea gitea-db-$DATE.sql tar -xzf gitea-repos-$DATE.tar.gz -C / sudo chown -R gitea:gitea /var/lib/gitea sudo systemctl restart gitea这里有个小坑值得提醒仓库目录内除了裸仓库还有lfs目录存放大文件备份时一定要确保这个目录也被包含。如果漏了LFS数据代码仓库能打开但大文件无法正常拉取处理起来会很麻烦。5. 换装升级与踩坑实录5.1 GitLab部署的典型故障与调优有些人可能跳过了Gitea直接被GitLab的丰富功能吸引。我见过很多团队在GitLab部署上调优踩坑以下是我印象最深的几个问题第一个是内存持续走高最终被OOM Killer杀掉。GitLab的Prometheus监控、Sidekiq后台任务、Gitaly仓库进程每个组件都有不小的内存占用。小型VPS上GitLab经常会在跑几天后莫名挂掉查内存日志基本都是OOM。解决的办法是调整GitLab的/etc/gitlab/gitlab.rb中的prometheus_monitoring[enable]为false关掉自带监控以及为Sidekiq配置并发数上限sidekiq[max_concurrency] 5 puma[worker_processes] 2经过这些调优一台4GB内存的服务器也能相对流畅地跑起小规模GitLab实例但前提是别指望它同时承载几十人高并发操作。第二个问题是磁盘被日志塞满。GitLab的日志非常啰嗦尤其在生产环境下。我在生产服务器上遇到过/var/log/gitlab目录膨胀到几十GB的情况。需要定期做日志轮转GitLab自带logrotate但默认策略对某些场景还不够激进我通常会把production_json.log的保留周期调短同时用cron任务做定期日志清理。第三个问题是升级中断导致数据库迁移失败。GitLab每次大版本升级间会执行若干数据库迁移操作期间要求服务不可用。如果升级到一半失败就要用备份回滚。GitLab的备份和恢复命令比较简单sudo gitlab-backup create sudo gitlab-ctl stop unicorn sudo gitlab-ctl stop sidekiq sudo gitlab-ctl status sudo gitlab-backup restore BACKUPxxxx但注意务必先停止相关服务再恢复否则数据库和文件系统可能产生不一致。这个环节踩坑的人很多恢复前花点时间看官方的版本升级路径指引确认当前版本到下个版本之间没有跳级能省去很多麻烦。5.2 数据库与存储选型的一点心得很多人问Gitea到底用MySQL还是PostgreSQL我的看法是如果你是个人或小团队两者都可以如果团队里有熟悉PostgreSQL的成员可以优先考虑PostgreSQL它在处理大批量并发写入和复杂查询上表现更好。Gitea官方文档对两者的支持都很完整代码仓库的数据模型并没有用到多少数据库特有功能所以不用太纠结重要的是把数据库的定期备份做好。存储方面仓库目录建议用独立的磁盘分区或者云盘尽量避免和系统盘共用。原因很直接仓库体积增长容易把系统盘撑满进而影响系统日志、临时文件、数据库的正常运行。我用云服务器时会把/var/lib/gitea/data挂载到独立的数据盘迁移时直接把数据盘快照带走非常省事。5.3 SSH密钥与权限配置的常见误区自建Git服务中SSH密钥配置问题出现的频率相当高。Gitea和GitLab都支持在网页端上传公钥但有些用户上传后依然无法克隆代码。排查看起来复杂其实只要按顺序确认几个点就能定位。先确认你的Git命令连接的是不是自建服务的SSH端口。Gitea如果用2222端口你需要在克隆地址里显式指定系统SSH默认会连22端口一旦端口不对就直接拒绝。确认端口正确后检查你这台机器上有没有配置多个SSH KeyGit客户端使用密钥时可能会按名称顺序选择不匹配的那一把。此时可以在~/.ssh/config中对目标主机单独指定IdentityFileHost git.example.com HostName git.example.com Port 2222 User git IdentityFile ~/.ssh/id_ed25519还有一点如果服务器端用的是Gitea内置SSH功能~/.ssh/authorized_keys中会出现Gitea管理的密钥条目。有些运维人员不清楚这点会顺手清理掉那些看起来奇怪的密钥结果用户全部无法克隆排查半天才发现是自己清理过头了。遇到SSH连接异常时先别急着删东西多看几眼/var/log/auth.log系统日志通常能告诉你怎么回事。6. 从部署到长期运营的几点实用建议如果你已经选定方案并跑起来了接下来最重要的是建立运营习惯而不是沉浸在终于有了自己Git服务的满足感里。先说一条我吃了亏才明白的经验定期做恢复演练比定期做备份更重要。备份做了不等于灾难发生时能恢复。我的习惯是每季度挑一台空虚拟机按恢复文档完整跑一遍数据库导入和仓库解压的过程确认服务能正常起来。整个过程可能花掉一两个小时但能换来非常大的安全感。我见过不少团队备份脚本跑了一年多真正需要恢复时才发现备份文件是坏的或者恢复步骤文档和实际版本对不上那个场景下的时间成本和社会成本都远高于平时的一次演练。第二个建议是监控告警要尽早落地。Gitea本身就带一些简单的健康检查配合外部监控工具比如探针或UptimeRobot可以做到服务宕机时第一时间收到通知。对GitLab这类重量级服务更是如此磁盘使用率、内存占用、GitLab自身的健康检查接口都要纳入监控范围。自建服务最怕的就是不知不觉挂了——等团队成员主动报告时一般已经过了很久仓库上所有的推送和评审操作全部中断这种体验会严重影响大家对自建平台的信任。第三点是关于版本升级策略。无论选哪款工具我认为都不要长期停留在旧版本上但也不用追求每个版本一发布就立刻升级。GitLab建议跟随大版本周期走每次升级前先看官方升级路径指南不要跳级。Gitea的升级相对平滑同样建议先在测试环境验证一次再上生产。升级前务必备份当前状态万一失败可以回滚。最后分享一个小技巧不管用哪个方案都可以配置一个自定义的WebHook把仓库的推送、合并请求等事件转发到团队的即时通信工具或者工单系统。比如当有新合并请求创建时自动推送一条卡片消息到群里相关审核人员。这个小功能不需要复杂开发Gitea和GitLab都在管理界面上提供WebHook配置入口填一个URL就搞定。它带来的体验提升是很直观的——代码协作的节奏感会变得清晰很多不会出现代码推完没人管的情况。自建Git服务的本质是以运维成本换取代码的自主可控。2025年的方案选择比过去任何时候都多从五分钟上手的Gitea到功能强大的GitLab每个工具都有自己的生态位。选型不必追求最强而应该找到最匹配你团队规模和维护能力的那个方案。先跑起来再逐步演进这比一开始就规划一个庞大系统要务实得多。