前言
这一周我都在折腾在自己的内网服务器中部署私有 Git 服务器,对于目前用的最广泛的 Gitea 与 GitLab 都进行了实际部署,并邀请了多人进行试用。
对于这两个被广泛使用的可自托管的 Git 托管方案,网上似乎都是几张清单式的功能对比表,所以我想在这篇文章中对比两者在我实践中感受到的的差别,以及说说这几天我趟过的坑,为准备自建 Git 托管网站的用户提供参考与建议。
在正文开始前,我先提醒一件事情:不推荐在非自己托管的 Gitea 上使用 GitHub TOKEN 等个人敏感信息,目前(v1.16.4) Gitea 的隐私管理缺陷可能会向站点管理员泄露你的隐私。这个问题可以说是我遇到的最大的坑,也是让我转向 GitLab 的主因,我会在正文中详细说明这个问题。
更新:Gitea v1.16.6 已经修复了泄露 TOKEN 的问题,但对于切记注意第三方 Gitea 托管站点的版本。
在本文发布后,Gitea 作者已经看到了部分对 Gitea 缺失功能的吐槽,并开始在新版本中实现它们,所以部分内容可能有所过时。
概述
作为可以自己部署的 Git 托管服务器方案,Gitea 与 GitLab 有很多相似之处:有着和 GitHub 相似的仓库界面,一样有着基本的 Git Server 功能,一样同时支持 http(s) 与 ssh,一样支持 Issue 和 Pull requests……
Gitea 是完全开源免费的项目,而 GitLab 有着开源并免费的版本 GitLab CE,也有付费并有闭源功能的 GitLab EE。它们也都提供了由各自的官方托管版网站,你可以前往 gitea.com 与 gitlab.com 体验它们的用法。
这些最基础的东西双方都很相似,只看双方提供的功能对比表很难感受出它们有多大差别,但在实际部署它们后,你可以很直观地感受到它们骨子里就是不同的,它们之间的区别就和 com.sun.net.httpserver
和 Spring 全家桶一样,是单一功能的库与一个生态的区别。
Gitea 是一个功能较为单一的 Git 托管服务器,所有功能都围绕着 Git 托管而来,而且给出了较高的可定制性。在部署 Gitea 的时候,我很明确自己的目的是实现 Git 托管功能,部署后我再根据自己的需求去组合其他工具来满足我的工作流。
GitLab 则是一个大而全的解决方案整合,将 Git 托管、持续集成/部署等功能做在了一起,试图解决你的所有需求。在我部署它之后,我需要探索它的功能,学习它的工作流,适应它来完成我的工作。
资源占用
作为 Git 托管服务器使用时,Gitea 资源占用明显要低得多。
静态硬盘占用上,Gitea 核心是一个 100 MiB 上下的可执行文件,外加上作为必要依赖的 Git(如果内置 SQLite 不够的话也需要单独部署一个 MySQL 或者 PostgreSQL 做数据库),而 GitLab 光 Docker image 大小就 GiB 级了……不用我多说,截一下 GitLab 的日志文件夹就知道这玩意有多重量级了:
1 | $ ls ./gitlab/logs |
我断断续续跑了两天,这日志就快 200MiB 了……
内存方面,我这里 Gitea 日常占用内存通常在几百 MiB 浮动,而 GitLab 的 Docker 容器目前内存占用是 14GiB。
GitLab CPU 占用率(相对于一个核心计算)日常待机在 35% 上下,而 Gitea 通常是 0.2% 左右。(这些都是日常无负载状态下的情况,如果有机会的话我试试进一步比较,现在正在停用 GItea,懒得折腾了。)
网站配置
Gitea 大部分配置都要通过修改 app.ini
并重启 Gitea 服务器来应用,后台管理面板基本没有可修改的配置,不能进行配置热修改。
GitLab 部分网络相关的配置(域名,端口,代理,邮箱等)需要修改 gitlab.rb
并重启 GitLab,剩下的大多选项都是在管理员面板里通过 Web UI 进行热修改并及时生效。
对于要稳定运行的 Git 托管服务器来说,Gitea 每次修改配置后想要生效都要离线一段时间,好在 Gitea 启动很快,我这里从启动到能正常访问大概只要 10 秒钟(数据库跑在另一个容器里,没有计算它的启动时间),而 GitLab 启动一次要一分多钟,但由于 GitLab 大部分配置都是热修改,除了最开始部署时需要修改配置,运行中基本没有重启的需求。
想要自定义页面布局在 GitLab 上非常困难,除了首页内容可以通过管理面板修改外,剩下的地方似乎都无法用常规手段修改。Gitea 放开了很多 tmpl 文件可配置,我想要给站点每个页面底部添加一条链接,自己提供一个 extra_links_footer.tmpl
就能完成,但在 GitLab 我是没有找到什么好办法去实现。(似乎能改 /var/opt/gitlab
里的东西来修改布局,但我改了这个文件夹里的一些配置后再重启后,我修改的地方都被还原了,有空再做进一步的探索。)
另外有一点就是,Gitea 内几乎所有链接都在使用基于 ROOT_URL
的绝对链接,所以基本绑死在这个 ROOT_URL 上,配置好后基本没办法用多个域名访问同一个 Gitea。准备使用内网穿透的用户要注意一下这个问题,很多内网穿透服务分配给用户的都是非标准端口,如果想在内外网都能良好访问自己的 Gitea 服务器,最好让 Gitea 内网的端口与公网端口一致,不然很多麻烦事情。
GitLab 会检测你用来访问 GitHub 所用的域名,而且很多地方都会根据这个更改显示,不会因为用不同于 external_url
的地址访问而出现问题,这方面问题会比 Gitea 少很多。 (注意一下,如果你在 external_url
中写了带端口号的地址,GitLab 的侦听端口也会跟着变更。不想改侦听端口的话记着覆盖 nginx['listen_port']
设置)
隐私保护
隐私保护方面我觉得是 Gitea 最值得诟病的问题,也是我转而投向 GitLab 的主因。
Gitea 的一些功能需要 GitHub TOKEN 实现(譬如从 GitHub 导入私有项目等),GitHub TOKEN 作为用户隐私,本身应该受到良好保护,但我在实际使用过程中发现,目前版本(v1.16.4)的 Gitea 有严重的安全问题:
当用户正在进行使用 GitHub TOKEN 访问 GitHub 仓库的任务时,包含了 GitHub TOKEN 的 URL 直接明文出现在管理后台中,管理员可以轻松的从后台看到这些隐私信息:
这应该开发者考虑不周造成的问题,相对而言能明显感受到 GitLab 要更关心用户的隐私保护问题,涉及到隐私信息时都高度敏感,在不修改服务器本身的情况下,管理员也无法触及它们。(当然在管理员能接触到 GitLab 服务器的情况下,依然可以通过篡改服务器来窃取用户隐私,所以对第三方托管的服务器并不能无保留的信任。)
GitLab 中带有用户 TOKEN 的 URL 显示
功能
消息通知
GitLab 与 Gitea 都能配置邮件消息通知。
GitLab 每个用户都能设置自己接受的通知,或者完全拒绝邮件通知,设置的粒度可以细分到组/项目级别,管理员还能通过管理后台对用户手动群发邮件通知。
Gitea 的用户无法控制自己接受的通知,只能由管理员配置通知的类型,而且也只能进行全局范围的配置,无法细分到用户身上,而且所有通知都是 Gitea 的自动通知,管理员无法发送自定义通知。
对于 Gitea 这个邮件通知,不能说不能用,但对于多用户的服务器来说,我觉得难用到很难接受的程度,我在配好邮箱后尝试了一会就关掉了。
存储库导入与镜像
Gitea 和 GitLab 也都支持导入第三方 Git 仓库,特别是提供了原生的迁移 GitHub 仓库的办法,可以连带着 Issue、PR 等其他数据一同导入进来。
此项功能需要 GitHub TOKEN 来完成,Gitea 有泄露 TOKEN 的问题,这点在前面已经说过了,所以不建议在第三方托管的 Gitea 上进行此操作。
但如果在你自己的 Gitea 上执行,不需要担心隐私问题的话,我尝试下来的体验非常好,仓库内容基本都能原模原样地导入过来。
Gitea 导入的 Issue
而 GitLab 的迁移功能个人体验就比较差了。Issue 虽然也能搬过来,但是无法做到 Gitea 这样保持创建者信息,所有的 Issue 创建者都会变成进行导入的用户,然后在内容中添加一条 Created by
信息来标识原创建者。
问题更大的是,GitLab 的 Issue Markdown 语法和 GitHub 有一定差别。最典型的问题是,GitHub Issue 中单个换行符就能换行,GitLab 则是保持了标准的 Markdown 语法,需要连续两个换行才可以,这导致导入的 Issue 格式全都乱成一团,根本没法看:
GitLab 导入后的样子
除此之外,Gitea 和 GitLab 还支持存储库镜像功能,能够让一个 Gitea/GitLab 存储库与一个外部的存储库(譬如 GitHub 上的存储库)保持关联。它们都支持这两种镜像模式:
- Push 镜像:以当前仓库为主要仓库,在当前仓库发生修改后自动将修改推送到外部仓库中。
- Pull 镜像:以外部仓库为主要仓库,在固定间隔后或者手动触发时从外部仓库拉取内容更新当前仓库中。
在镜像功能上,GitLab 很离谱的把 Pull 镜像归属到了 EE 功能中,也就是要付费才能使用,这一点我是完全没有想到的,因为这个功能怎么看都应该属于 CE 的范畴,这也是我对 GitLab CE 意见最大的地方。我自己部署的是 GitLab CE,所以无法尝试 Pull 镜像了。
GitLab 的 Push 镜像功能会在每次用户修改仓库或者手动触发时进行推送,我使用下来体验良好。
Gitea 的 Pull 镜像当然是完全能免费使用的,基本的定时与手动更新仓库功能都可用,就是可惜无法同时同步 wiki、Issue 和 PR。
而 Gitea 的 Push 镜像,我自己没有尝试过,但看文档的描述,Gitea 的 Push 镜像同步是定时触发的,我觉得这就挺迷惑的,还是 GitLab 的策略更好用。
而且特别要注意,Gitea 同步时唯一的认证方式是账号密码认证,但 GitHub 现在禁止账密认证,导致无法正常进行认证,唯一的解决方案是把 GitHub TOKEN 写在 URL 里,但除非是你自部署的 Gitea 并且其他人无法访问这个仓库,否则就会导致你的 GitHub TOKEN 泄露。
GitLab 原生就支持使用 GitHub TOKEN 或者通过 SSH 进行认证。SSH 不知道为什么我这里配好公钥也无法通过认证,但用 GitHub TOKEN 认证的方式工作一切正常,而且对 TOKEN 也有应有的保护,作为主要仓库使用并用它同步到 GitHub 上是没问题的。(SSH 地址必须是 ssh://git@github.com/<group name>/<repo name>.git
的形式,GitHub 的 Code 按钮里那个地址不能直接用,前面要补上 ssh://
,中间的冒号也要改成正斜杠)
CI/CD
谈 Gitea 与 GitLab 的区别,那肯定少不了 CI/CD 这个重头戏。
Gitea 没有提供内置的 CI/CD 支持,但是可以用 Gitea 提供的 API 与其他 CI 集成,目前推荐的比较多的似乎是是自部署 Drone CI,但也可以与 Travis CI 这类现成的 CI 集成。
Gitea 与 Drone CI 的集成
Gitea 与 CI 的集成我没有亲自尝试过,但可以参考上面 gitea.com 里现成的例子。我本来想尝试部署 JetBrains TeamCity,但 Gitea 目前的 API 并不足以与 TeamCity 集成,这在后续版本中可能会改进。
而 GitLab 原生就集成了一套强大的 CI 功能,而且就像 GitHub Action 与 GitHub 那样,它与 GitLab 有着极为紧密的结合。
GitLab 用于执行 GitLab CI 的程序叫做 GitLab Runner。在刚开始看文档的时候,我一直很疑惑为什么 GitLab Runner 的介绍在用户指南里,而非管理员的配置指南中,在配置好后我才豁然开朗,因为 GitLab 不止允许管理员注册全局可用的共享 GitLab Runner,它还允许一般用户为自己或者组注册自托管的 GitLab Runner 实例,让 CI 仅跑在自己的机器上。
目前我只是简单的配置并跑了一些简单的样例,尝试后我觉得很喜欢这样一套高度集成而且灵活易配置的 CI 方案,我认为这方面 GitLab 要比 Gitea强很多。
总结
根据到目前为止我自己的实际体验,对于仅个人或者小型团队内部的 Git 服务器来说,我更推荐 Gitea,它更轻量,更容易定制化,GitLab 相对来说太吃资源了,而且很多高级功能一般用户可能永远用不上。
如果是中大型团队/企业,或者是要搭建公开服务的站点,那么我只推荐 GitLab。Gitea 对于隐私的保护实在有很多欠缺,而且用起来的时候经常能感受到很多设计并不适合向大量用户提供稳定的服务。GitLab 虽然重,但是整体考虑更加完善,更适合作为商业化的产品使用。
目前我还没有来得及尝试更多功能,所以暂时也给不了更多建议,以后或许会继续更新踩坑经历,希望能帮到更多用户。
本文转载自: 知乎