2025自建Git服务指南:从选型对比到生产部署全解析
最近几年我明显感觉到身边问“自建Git服务用什么工具”的人变多了。前几年大家更喜欢直接往 GitHub、Gitee 上一推了事但后来陆陆续续遇到仓库体积限制、私有仓库数量上限、团队权限管理不方便甚至公司合规要求代码只能存到内网服务器里的情况。于是“自己搭一个 Git 服务”就成了很多团队绕不开的选项。但真正动手的时候才发现问题没那么简单。你在搜索引擎里一翻会发现方案特别多Gitea、Forgejo、GitLab、Gogs、Gerrit甚至还有人拿裸仓库加一堆脚本自己拼一个出来。每个方案都有人说好也有人说坑。这篇博文我想把自己实际用过、配置过、也踩过坑的经验整理出来从底层逻辑到方案对比再到部署实操和问题排查一次性把“2025 年自建 Git 服务”这件事讲清楚。不管你是一个人用、三五人小团队还是准备做公司级私有化部署这篇文章应该都能帮你少走不少弯路。1. 选型前的底层功课自建Git服务到底在解决什么问题很多人一上来就在对比功能列表却忽略了一个基本问题你到底需要一个什么样的 Git 服务。Git 本身是一个分布式版本控制系统核心能力是版本管理、分支合并这些底层操作。但团队协作和私有化部署光靠 Git 命令行是不够的。你还需要一个“中央仓库”作为可信来源大家往里推送代码、拉取代码需要一套账号体系控制谁能读、谁能写需要一个 Web 界面让新人能浏览代码、提 Merge Request可能还需要和 CI/CD、消息通知、Issue 管理打通。所以这里的“自建 Git 服务”实际上是在问我要选一套整合了Git 仓库托管 用户认证 权限控制 协作功能PR/MR、Issue 可扩展性CI/CD、Webhook的解决方案。想明白这一点就不会被“哪个工具功能多”牵着鼻子走而是先看自己的真实需求层级。我把自建需求分成几个典型层级先对号入座个人/极简使用自己写代码、同步几台电脑、偶尔给朋友一个只读仓库。这个层级最重要的是轻量、省心不需要复杂权限模型也不用评审流程。小团队协作5~20人需要账号体系、私库权限、Pull Request/合并请求、简单的 Issue 管理。最好部署和维护成本都很低。中型团队 DevOps20~100人除了代码托管还需要内置或外接 CI/CD需求可能是“一个平台搞定代码、构建、发布”。企业级/强合规需要细粒度权限、审计日志、AD/LDAP 对接、高可用、灾备甚至还要做代码扫描、安全合规。这个层级对选型、部署架构都有额外要求。特殊流程比如强代码评审驱动的团队那就要考虑 Gerrit 这样以 Review 为核心的系统。同样的工具在不同层级下的表现差异非常大。GitLab 功能全但让它在树莓派上跑起来纯属自虐Gitea 轻量好用但硬要它承担千人企业级权限治理也会捉襟见肘。一句话总结选型思路先定需求层级再谈工具性能。接下来我就把 2025 年里值得考虑的几套主流方案摊开逐一说清楚它们各自的优缺点和适合场景。2. 2025主流自建方案横向对比先说结论这个领域现在真正值得认真考虑的基本上是这几个方案开发语言资源占用功能范围推荐场景Gitea / ForgejoGo低仓库托管、PR/MR、Issue、Actions、Packages个人与中小团队首选GitLab CE/EERuby/Go高完整 DevOps 平台、CI/CD、安全扫描企业级一体化平台GogsGo极低基础托管、Issue、PR老设备、极简场景GerritJava中代码评审为核心强 Review 流程团队裸仓库 Gitolite/脚本Shell/Perl极低只有源码与 SSH 权限教学、极致简单2.1 Gitea / Forgejo个人与小团队的默认答案先说我最常用的 Gitea。它是一个用 Go 写的轻量级 Git 服务单二进制文件就能跑起来部署方式也很简单可以用 Docker 一条命令拉起也可以直接执行二进制文件。到了 2025 年Gitea 的功能已经覆盖了绝大部分团队需求仓库托管、Issue、Pull Request、里程碑、Webhook 通知、内置 CIGitea Actions兼容 GitHub Actions 语法、Package Registry 集成还有不错的 LDAP/OAuth 支持。Forgejo 是 Gitea 的一个分叉原因是社区治理分歧代码层面两者大体同源功能相差不大。如果你对开源社区治理有洁癖可以选 Forgejo如果想图稳定省心Gitea 的用户和文档生态更大一些。两个项目现在都在活跃迭代没有哪一方有压倒性优势。Gitea 最打动我的地方是资源占用低。实测一个 10 人左右小团队的 Gitea 服务2 核 4G 内存的云主机跑得非常舒服内存占用大概几百兆再挂个 PostgreSQL 都绰绰有余。如果你只有一台 1 核 1G 的小机器只要不开太多后台任务也能勉强运行。有人可能会担心“Gitea 这么轻量功能是不是太基础了”说实话2025 年的 Gitea 已经不是当年那个“玩具”了。它内置了 CI/CD、Docker Registry、NPM Registry 这些能力还能和很多第三方工具集成。对小团队来说它不是“低配版 GitLab”而是“够用且不折腾”的版本。2.2 GitLab CE企业级全家桶但别在小机器上硬跑GitLab 是自建 Git 服务里功能最完整的方案之一。它不仅仅是代码托管平台更是一整套 DevOps 平台内置强大的 CI/CD.gitlab-ci.yml、容器镜像仓库、制品库、安全扫描、代码质量、问题跟踪、价值流管理等等。很多公司选择 GitLab 的原因是“一套系统覆盖研发全流程”。但它的代价也摆在明面上资源占用确实大。官方建议最低 4GB 内存我个人体验是这个配置跑小团队勉强跑到 10 人以上并行操作时明显能感觉到页面响应变慢、Pipeline 排队。真想流畅使用8GB 内存起步比较现实。如果在 AWS 或国内云厂商买一台 4C8G 的机器一个月费用并不低。另外要留意 GitLab 的免费版CE和企业版EE之间的功能差异。很多高级功能比如某些安全扫描、代码所有者等需要付费订阅。选型之前建议先拿着自己必须的功能清单去官方文档比对一遍别部署完才发现需要的功能在付费墙后面。GitLab 适合什么样的人适合“我就是要一个全面的平台不想在多个工具之间反复切换”的团队以及预算和运维能力都能撑起一台像样服务器的企业用户。Gitea 是一个 Git 服务而 GitLab 在往“研发管理平台”的方向进化两者定位其实已经拉开了。2.3 Gogs轻量但偏保守Gogs 是比 Gitea 更早出现的 Go 语言 Git 服务Gitea 最初就是从 Gogs 分叉出来的。Gogs 最大的卖点是极度轻量官方曾宣传在树莓派这样的设备上也能跑。如果你有一台老旧的 1核512M 内存设备想跑一个 Git 服务Gogs 可能是为数不多能装下的选择。但我的建议是除非你手头真的只有一台“电子垃圾”级设备否则在 Gogs 和 Gitea 之间还是优先选 Gitea。原因很简单Gogs 的社区维护节奏相对慢功能迭代和 issue 响应速度都不如 Gitea 活跃。我自己在实际使用时发现Gogs 的 UI 交互和 Pull Request 流程做得比较基础面对稍微复杂一点的协作场景就有点吃力的感觉。它能满足“有一个 Git 远程仓库”这个底线需求但如果你后续想加 CI/CD、Webhook 深度对接、复杂的权限配置很快就会碰到能力瓶颈。2.4 Gerrit为代码评审而生的专业化方案Gerrit 是一套独立于 Gitea/GitLab 体系的代码评审系统。它的核心设计理念是“没有经过 Review 的提交不能直接进入主干”。开发提交代码到 Gerrit 后会以 Change 形式存在评审者批准后才合入整个过程和 Git 原生的分支协作方式很不一样。比较大的开源项目里像很多系统级项目就用了类似的流程。Gerrit 的学习成本和运维成本都不低。普通 Git 用户的习惯是 push 到远程分支但 Gerrit 是 push refs/for/master这是一套全新的心智模型。如果团队里大家都没用过引入 Gerrit 的过程本身就会是一场文化变革。所以我的看法是Gerrit 不是给大多数团队准备的通用方案而是给对代码评审有硬性要求的团队准备的专用利器。如果你想要的只是“代码审一下再合并”Gitea 或 GitLab 的 Pull Request/Merge Request 流程已经够用不必直接上难度。2.5 裸仓库 脚本最小方案与最大自由这套方案是“自己用 Git 命令加脚本拼一个 Git 服务出来”。最简单的形态就是在服务器上git init --bare建一个仓库然后通过 SSH 让其他人推拉代码。如果要做权限管理可以用 Gitolite 这类工具它通过 SSH key 和配置仓库管理用户与仓库权限服务端脚本会自动生成对应的 authorized_keys 和 hooks。这种方式的好处是极度透明每一层都能自己控制没有多余依赖也不会被平台功能绑架。坏处也很明显没有 Web 页面、没有 Issue、没有 PR 工具团队成员想看一眼代码都得 clone 下来协作体验基本回到 2008 年。我自己的判断是裸仓库方案比较适合两种场景一种是教学演示让人理解 Git 的底层协作机制另一种是对“只需要一个不被厂商锁定的远程备份仓库”的人比如给个人笔记库做一个 Git 备份点。正规团队协作别拿业余时间来拼这种轮子后面维护成本远比你想象得高。3. 分场景选型决策表与硬件配置建议每次有人问我“到底选哪个”我不会直接给一个答案而是会追问几个问题你们团队多少人要不要内建 CI/CD有没有统一的运维人员对代码审计和权限合规有没有硬性要求问完这些问题答案基本就出来了。下面这个决策表是我根据多年实际经验整理的参考标准不一定绝对正确但至少在 2025 年的环境下按照这个思路去选型大概率不会踩大坑团队规模与场景推荐方案建议最低配置备注1~5 人个人项目/极简流程Gitea1核2GSSD 20GSQLite 也行数据库都省了5~50 人需要代码托管轻量CIGitea Gitea Actions2核4GSSD 50G如果跑多个 CI 任务再加资源5~50 人重度依赖 CI/CD 和 DevOpsGitLab CE4核8GSSD 100G至少 4G 内存理想是 8G50~200 人企业级合规要求高GitLab EE / 专业支持8核16G 起按需扩展考虑高可用和异地备份强代码评审流程Gerrit或 GitLab Review 功能4核8G需要团队接受工作流变化极简/教学/老旧设备Gogs 或 裸仓库脚本512M~1G功能妥协明显关于硬件配置我多说两句。这里说的“内存大小”是指 Git 服务自身软件栈的需求比如 GitLab 的 Sidekiq、Puma 进程都是吃内存大户而 Gitea 的二进制文件本体非常省资源。真正影响体感的往往是磁盘 IO 和网络带宽因为 Git 大量小文件读写机械硬盘在并发访问时会明显卡顿所以有条件一定要上 SSD这是性价比最高的提升方式。存储规划上还有几个细节值得提前想清楚。第一仓库数据默认存在服务端所在磁盘但随着 Git LFS、容器镜像仓库的引入数据量会快速膨胀。建议把存储目录挂载到独立数据盘不要和系统盘混在一起。第二备份不是“复制一下仓库目录”就完事。数据库、配置文件、密钥、LFS 文件目录都要纳入备份范围否则遇到事故恢复的时候会非常痛苦。如果你需要的是企业级私有化部署我建议不要只停留在自建单机的思路上。可以考虑把 Git 服务部署到 Kubernetes 集群里搭配对象存储和外部数据库做成高可用架构。当然这属于投入成本较高的路线适合有专门运维团队的场景普通小团队前期完全不需要搞这么重。4. 部署实操以Gitea为例从零搭建一套生产可用的Git服务聊完选型接下来是实操环节。我以 Gitea 为例因为它最轻量、最适合多数人。整个部署过程大概 20 分钟能完成跟着做就行了。我不建议一上来就选择源码编译安装直接用官方打包好的二进制或 Docker 镜像是最靠谱的方式。下面我用 Docker Compose 的方式来讲因为这套流程最容易迁移和备份。4.1 环境准备与 Docker Compose 编排首先准备一台 Linux 服务器Ubuntu 22.04 或 Debian 12 都可以按照官方文档装好 Docker 和 docker compose 插件就行。然后创建目录结构mkdir -p /opt/gitea cd /opt/gitea编写docker-compose.ymlversion: 3 services: db: image: postgres:16-alpine restart: always environment: POSTGRES_USER: gitea POSTGRES_PASSWORD: change_me_strong_password POSTGRES_DB: gitea volumes: - ./db:/var/lib/postgresql/data networks: - gitea server: image: gitea/gitea:latest restart: always depends_on: - db ports: - 127.0.0.1:3000:3000 - 127.0.0.1:2222:22 environment: GITEA__database__DB_TYPE: postgres GITEA__database__HOST: db:5432 GITEA__database__NAME: gitea GITEA__database__USER: gitea GITEA__database__PASSWD: change_me_strong_password volumes: - ./data:/data networks: - gitea networks: gitea: driver: bridge这里有几个配置点需要注意我把 Web 端口 3000 和 SSH 端口 2222 都绑定到了127.0.0.1也就是只允许本机访问。外部访问统一走反向代理比直接把端口暴露到公网更安全。数据库我选了 PostgreSQL。如果只是三五个人用SQLite 也完全可以但 PostgreSQL 在并发和可靠性上更好而且后续迁移、扩展都方便干脆一步到位。把数据目录映射出来了后面升级镜像、备份数据都靠宿主机的./data和./db目录。启动服务docker compose up -d等一两分钟再检查容器状态docker compose ps如果两个容器都是 Up 状态基本就成功一半了。4.2 首次安装配置的关键参数浏览器访问http://127.0.0.1:3000如果本机没开图形界面就通过 SSH 隧道先临时访问进入 Gitea 的安装向导页面。这里有几个参数非常关键填错了后面改起来很麻烦数据库设置数据库类型选 PostgreSQL主机填db:5432这是 Docker 网络里的服务名数据库名、用户名、密码填上面 env 里对应值。站点标题随便写比如“XX团队代码仓库”后面可以改。仓库根目录保持默认/data/git/repositories。SSH 服务器端口这里填2222对应上面容器映射出来的 SSH 端口。如果之后客户端 clone 要走的 SSH 不是默认 22这一栏必须配对。Gitea 基础 URL这个要填最终用户访问的地址比如https://git.example.com/。如果现在没配域名就先填http://IP:3000/但后面配好 HTTPS 后记得在配置里改回来。禁用用户自注册小团队默认建议勾选避免外部无关人员注册进来。账户由管理员统一创建。填完后点安装Gitea 会自动建库、建表、初始化配置。安装完成后再去系统管理后台里调整更多细节。4.3 HTTPS、SSH端口与日常管理刚才特意把端口绑到本机就是为了配合反向代理统一处理 HTTP/HTTPS。我最常用的方式是 Caddy因为它能自动申请和管理 HTTPS 证书配置非常简洁。在宿主机上装好 Caddy写一个 Caddyfilegit.example.com { reverse_proxy 127.0.0.1:3000 }重启 Caddy 后https://git.example.com就能直接访问了。Caddy 会自动申请 Lets Encrypt 证书并续期完全不需要手动干预。如果你习惯 Nginx也可以做到类似效果但需要自己解决证书申请和定时续期的问题。SSH 端口这里要单独讲一个实践中高频踩坑的点。Gitea 容器内默认的 SSH 端口是 22但宿主机上往往有系统自带的 sshd 服务占用了 22。所以才有了上面那份配置里的127.0.0.1:2222:22映射把宿主机的 2222 转发到容器的 22。如果团队里有人想用 Gitea 的 SSH 方式 clone 代码那 clone 地址会变成git clone ssh://gitgit.example.com:2222/username/repo.git这里git是 Gitea 内置的系统用户名端口要写对。如果团队不习惯记端口可以考虑在宿主机上关闭系统 sshd 并让 Gitea 直接占用宿主机的 22 端口这样 clone 地址就和 GitHub 一样简洁。但这个操作会影响到服务器的远程管理建议只在专属代码服务器上这么做。日常管理主要靠 Gitea 的后台页面。管理员可以在“管理面板”里看到系统运行状态、用户列表、仓库统计也能直接创建用户、创建团队、配置 OAuth2 应用。命令行的gitea admin命令则适合在容器里做自动化和批量操作比如docker exec -u git gitea gitea admin user create --username xy \ --password temp_pass --email operatorexample.com4.4 备份策略别等数据丢了才想起来自建服务最怕的是什么不是功能少而是数据丢失。我在实践中遇到过硬盘故障、容器数据卷误删、机器被重置等各种意外。有一句话我每次都要强调自建 Git 服务备份和恢复流程必须和部署同步完成别等真出事了再想辙。Gitea 的备份可以简单靠宿主机的定时任务完成。核心是三个部分数据库、仓库数据文件、配置文件。用docker exec配合pg_dump如果是 PostgreSQL导出数据库把导出文件和宿主机上的./data目录打包上传到对象存储或另一台机器即可。我最常用的是写一个 shell 脚本放到cron.daily里#!/bin/bash set -eu BACKUP_DIR/data/backup/gitea STAMP$(date %Y%m%d-%H%M) mkdir -p $BACKUP_DIR docker exec -t $(docker compose ps -q db) pg_dump -U gitea gitea \ | gzip $BACKUP_DIR/gitea-db-$STAMP.sql.gz tar czf $BACKUP_DIR/gitea-data-$STAMP.tar.gz -C /opt/gitea data # 清理7天前的旧备份 find $BACKUP_DIR -mtime 7 -name *$STAMP* -delete恢复流程也很关键。最常见的恢复方式是新部署一套相同版本的 Gitea停掉服务后用备份文件覆盖./data目录再往数据库里导入gitea-db-*.sql.gz最后重新启动容器。这里必须注意数据库版本与 Gitea 版本兼容性最好把备份时用的 Docker 镜像版本记录下来避免恢复时因为版本跨度太大而出现迁移问题。光有备份还不够建议至少留一份备份在异地或对象存储上。本地单机备份在服务器被删、机房断电、机器被盗这些场景下是无效的。可以用rclone等工具把备份文件同步到云存储或者另一台服务器这个操作不复杂但关键时刻能救命。5. Git客户端与服务端的衔接要点服务端搭好之后客户端怎么连上去又是一个大话题。尤其团队里如果混合了 Windows、macOS、Linux 用户这套配置过程就更有必要提前统一了。5.1 SSH密钥生成与配置无论是 Gitea 还是 GitLab我推荐首选 SSH 方式认证。相比 HTTPS 密码或 TokenSSH key 更稳定不用反复输密码权限控制也更直接。Linux/macOS 用户直接在终端生成ssh-keygen -t ed25519 -C your_emailexample.comWindows 用户在 Git Bash 里也是一样的命令。生成后默认会在~/.ssh/id_ed25519.pub保存公钥把它整个内容复制出来粘到 Gitea 网站的“设置 - SSH密钥”里。然后本地验证ssh -T -p 2222 gitgit.example.com如果是 Gitea看到类似 “Hi there, username!” 的欢迎语就说明 SSH 配置成功了。这时候再去 clone 就用 SSH 地址一次配置之后免密推送拉取体验非常顺滑。5.2 HTTPS与Token方式的补充有些公司网络环境限制了 SSH 端口比如只开放 443 端口或者服务器上不能映射非标准端口那就只能用 HTTPS 方式访问。Gitea 和 GitLab 都支持 HTTPS clone。认证方式可以用密码也可以创建访问 Token在 Git 命令行或 IDE 里用 Token 代替密码。我个人强烈建议用 Token 而不是密码因为 Token 可以精确设置权限范围、临时性也更强。万一泄露去后台吊销换新即可不需要改全局密码。在命令行里配置全局用户信息就可以正常提交了git config --global user.name your_name git config --global user.email your_emailexample.com如果你在公司电脑上不想把用户名和邮箱写进全局配置也可以在每个仓库内单独设置。Git 的配置优先级是仓库级配置 用户全局配置 系统级配置。5.3 几个高频实用的Git进阶技巧自建服务之后很多人会遇到一个高频问题怎么把本地分支推送到服务器。git push origin main这是最常规的。但如果代码推到一半发现提交信息写错了可以用git commit --amend修改最近一次提交信息或补充漏掉的文件git commit --amend -m 新的提交信息注意这个操作只适合提交还没有推送到远端的情况。如果已经 push 到远端再 amend 会导致本地和远端历史不一致此时再 push 会被拒绝。解决办法是强制推送git push --force-with-lease origin main--force-with-lease比--force安全它会先检查远端引用是否和你上次拉取的一致避免把别人的提交覆盖掉。还有一个被严重低估的技巧是git worktree。它让你可以从同一个仓库同时检出多个分支到不同目录特别适合“我正在 A 分支开发突然要切去 B 分支改 bug”的情况不用反复 stash。常用方式git worktree add ../hotfix hotfix-branch改完 bug 后在hotfix目录内正常提交、推送即可。这个操作不会影响你在原目录里的工作现场体验比 stash 来回切换舒服太多。6. 常见问题与排查技巧自建 Git 服务踩过的坑真的不少我整理了几个出现频率极高的问题和对应的排查方法可以先收藏起来真遇到的时候直接翻。fatal: not a git repository (or any of the parent directories): .git这个报错几乎每个新手都遇到过。原因很简单你所在的目录不是 Git 仓库或者当前目录不在仓库内。检查一下是否在项目根目录或者执行git init初始化有些人还会因为环境变量GIT_DIR设错而触发这个报错。fatal: Permission denied (publickey)SSH 认证失败。按顺序排查第一步确认密钥确实加到了 Gitea/GitLab 后台第二步检查是否用了正确的端口和用户Gitea 的用户是git第三步在本地执行ssh -T -p 2222 gitgit.example.com看输出信息第四步确认~/.ssh目录权限是否正常在 Linux/macOS 上对私钥文件执行chmod 600 ~/.ssh/id_ed25519很有必要。IDE 连接失败login failed. check api token or gitlab version这个通常发生在 IDEA 或 VS Code 的 Git 插件连接 GitLab 时。原因一般是 Access Token 配置错误、scope 权限不足或者 GitLab 版本与插件版本不匹配。建议在密码/Token 栏里填一个有api、read_repository、write_repository权限的访问令牌而不是填登录密码。如果还是不行去“用户设置 - 访问令牌”里重新生成一个 Tokenscope 尽量给全再试。git clone 或 push 时上传/下载变慢或卡住首先看是不是网络链路问题特别是跨地域访问自建服务器时绕路会造成很高延迟。其次查看服务器 CPU、内存、磁盘 IO如果磁盘 IO 被打满大量并发 clone 时会明显卡顿。再检查反向代理层有没有设置过小的client_max_body_size有时候大文件推送会被 Nginx 直接拒绝。最后如果 Gitea/GitLab 启用了强制 HTTPS而客户端却用 HTTP 访问也容易遇到奇怪的重定向问题把客户端 URL 统一改成 HTTPS 即可。git目录泄露这个不算故障而是安全隐患。如果你用 Nginx 或 Apache 把某个目录直接作为静态站点暴露而不小心把.git目录放进了 Web 站点根目录攻击者可以通过 HTTP 直接下载.git目录里的历史版本信息这是很经典的源码泄露路径。自建 Git 服务时一定要避免把仓库目录直接暴露给 Web 服务。如果发现已经泄露建议立即撤销相关凭据、轮换所有密钥同时审查暴露的代码是否包含敏感信息。SSH 端口被人改了之后连不上如果团队里有人习惯直接 clonessh://gitgit.example.com/username/repo.git而服务端 SSH 不在默认 22 端口就会连不上。解决方法有两个要么在~/.ssh/config里给git.example.com单独指定端口Host git.example.com HostName git.example.com Port 2222 User git IdentityFile ~/.ssh/id_ed25519要么就在服务器上让 Gitea 直接占用 22 端口从根上消掉端口差异。忘记管理员密码Gitea 里忘记管理员密码也有救执行命令直接重置docker exec -u git gitea gitea admin user change-password \ --username admin \ --password new_strong_passwordGitLab 需要进入 Rails 控制台操作会稍重一些但官方文档里也有标准恢复流程。PostgreSQL 连接数满小团队一般不会遇到但如果你的 Gitea 同时接了很多 CI 并发任务连接数可能会打满。最简单的方式是调大 PostgreSQL 的max_connections配置同时检查 Gitea 的数据库连接池设置是否合理。修改完数据库配置要重启数据库容器才生效。切忌无脑调到上万内存会先撑不住。搜索站点速度很慢当仓库数量上来以后Gitea 的代码搜索可能会变慢。可以到管理后台检查是否启用了代码索引器把索引任务交给后台执行会改善很多。如果仓库数量特别大可以考虑将索引器从默认的内存索引切换到 Bleve索引文件会持久化到磁盘重启后不会重新全量扫描。最后再分享一点个人体会我在多个团队的实践下来越来越觉得自建 Git 服务这件事最难的部分往往不是技术而是想清楚“你到底需要什么”。有次我给朋友团队部署 GitLab花了整整一个周末调内存、配 Runner最后他们所有人其实只用了仓库和 Merge Request优越感没撑到第三天就转成了运维焦虑。后来换成 Gitea一周内大家就适应了CI 接入之后效率反而更高。所以如果你让我给一个最朴素的操作建议我会说按需选型别把功能列表当清单。3~5 个人的团队直接上 Gitea配一台小机器、做好备份完全够了真到了需要企业级审计、安全扫描、复杂权限体系的时候再认真评估 GitLab 也不迟。工具是服务的不是用来给自己设置障碍的。希望这篇文章能帮你省掉那些不必要的折腾把精力放回写代码本身。