1
0
Fork 0
blog/content/posts/逍遥游/Hello,Forgejo.md

234 lines
22 KiB
Markdown
Raw Permalink Normal View History

---
title: HelloForgejo
date: 2025-02-09
summary: Forgejo以及一点碎碎念
description: 本文讲述了自托管 Git 服务 Forgejo以及作者由此引发的对开源社区治理的思考。Forgejo 是 Gitea 成立商业公司后Codeberg 创立的坚守自由理念的分叉。作者首先梳理了从 Gogs 到 Gitea 再到 Forgejo 的演化过程,然后通过亲身部署,指出 Forgejo 与 Gitea 现阶段功能差异不大,但更契合理想主义者的精神诉求。文章后半部展开深度思辨,将开源运动与国际共运类比,剖析「分叉自由」背后的治理困境:去中心化理想与制度化需求的矛盾,理念纯洁性与现实可行性的冲突,以及技术乌托邦愿景在人类社会组织规律前的局限性。作者以乐观、充满希望的笔触收尾,坚信开源社区将不断进步,理想的「技术天国」也会越来越近。
categories: ["逍遥游", "沉思录"]
series:
tags:
- Forgejo
- 开源
- 哲学
slug: hello-forgejo
featuredImage: https://img.viento.cc/cover/hello-forgejo-cover.webp
---
各位老友,下午好。这里是 Chlorine。
说好考完试要爆更,结果既没爆也没更,除了一篇成何体统的开发日志之外什么都没憋出来,连年终总结都没写(悲)。
所以,水一篇小小的文章吧,讲讲最近拿到的一个新玩具,一个对小氯来说用处不大不小的 self-hosted service。
[Forgejo](https://forgejo.org)。
{{< codeberg repo="forgejo/forgejo" >}}
## 从 Gitea 说起
大家应该都知道 [Gitea](https://gitea.com)Git with a cup of tea。小氯很喜欢这个名字有趣且闲适的 Git 服务。当然,因为喜欢名字就去部署一个服务听着像个憨憨,所幸 Gitea 还是很争气的,给了我们更加充足的理由去用它:资源占用少——随便找一台树莓派就足够运行了,爱来自 Golang功能齐全——GitHub 和 GitLab 有的它基本都有,不管是基本的仓库,还是 issue、PR、Wiki、Project 抑或是 CI/CD。截至小氯写这篇文章Gitea 已经有了超过 40 万次安装数据来源Gitea 官网),堪称最受个人和小型团队欢迎的开源自托管 Git 服务之一。
当然,根据园子第一定律,既然小氯在写这篇文章了,就肯定是 Gitea 的某些地方让小氯不满意了。能是哪里?总不可能是小氯觉得应该用~~高贵的~~ Rust 把 Gitea 重写一遍吧?
这就要讲一讲 Gitea 的历史了。
> [!WARNING]
> 以下的内容为小氯从各方收集的资料总结而成,可能存在疏漏或者不准确,欢迎批评指正。同时,以下内容不代表对任何开发者或项目的任何看法。
### 从 Gogs 到 Gitea
要说 Gitea就不得不说说它的前身——GogsGo Git Service。Gogs 算是半个互联网古董了——诞生于 2014 年。它的创始人是著名的中国开发者——Unknwon或者可以称为「无闻先生」。
2014 年……大概是什么时候呢?小氯还在上小学,家里唯一能称得上「计算机」的物件是一台如今已经打不开了的东芝笔记本电脑,内存估计都没有一个 G。而当时的小氯对计算机知识的了解呢就和山顶洞人对量子力学的了解一样博大精深。据史料记载当时的 GitHub 已经是 Forge 平台代码托管平台的巨头了但是其不开源私有仓库要收费也没法自托管。GitLab 倒是有开源社区版可以自托管但是很重不适合喜欢「Keep things light and fun」的个人和小型团队。
所以……程序员说,要有光,于是有了 Gogs。
Gogs 的口号是「painless self-hosted Git service」目标是打造一个轻量化的、易用的、功能丰富的开源自托管 Git 服务。而它也确实做到了,在短短的几年内吸引了大批的忠实拥趸。
不过,当时间来到 2016 年事情开始出现了一些变化。作为个人主导的项目Gogs 的开发节奏受无闻先生的个人风格的影响相当大。而无闻先生的开发风格呢……比较求稳,讲究慢工出细活,所以对社区的 issue 和 PR 的响应也就没那么快。这个事情让很多热心的社区成员很着急。同时,可能是对自己的水平太有自信(虽然说他也确实有底气自信),无闻先生对社区的贡献和参与比较谨慎,更倾向于独自掌控 Gogs 的开发路线。这也引发了对 Gogs 项目皿煮问题的担忧。
所以……Gogs 的重要贡献者之一Lunny Xiao带领一群社区的开发者分叉了 Gogs于是世界上有了 Gitea。
Gitea 继承了 Gogs「painless self-hosted Git service」的口号并且积极接受社区的贡献和意见进行活跃的开发活动非常地皿煮。什么多语言CI/CD只要社区喜欢全都安排上。于是 Gitea 的热度很快超过了 Gogs成为了自托管 Git 服务中最受欢迎的明星之一。
### Codeberg 的担忧
时间在「饮茶Gitea先啦」的欢笑声中如流水般逝去。一转眼时间来到了 2022 年。
这一年的 Gitea 社区发生了一件大事:**Lunny Xiao、techknowlogick 等维护者成立了 Gitea Limited 公司**,并且把 Gitea 的商标、域名等资产转移到了公司的名下。
平心而论,虽说不和社区充分协商就成立公司接管资产有点不皿煮,但这倒也无可厚非,至少不算是什么大错。甚至如果处理得当,还可以促进 Gitea 的维护和开发,例如,可以雇佣全职的维护者,或者是通过商业服务获得资金支持。
不过,我们也能想象到,社区对这件事会有多大的反应,尤其是坚定的 FOSSist 们。我们先不谈意识形态的问题,成立公司,就意味着 Gitea 的发展有被商业利益影响的风险(注意我说的是风险),同时 Gitea Ltd. 也可能利用自己的商标的权利去限制社区对 Gitea 的使用。退一步说,即使说 Gitea Ltd. 的创始人们都是初心不改的谦谦君子,谁又能保证后继者们也能做到呢?上一个口口声声说「不作恶」的公司现在是什么样,也用不着小氯多说了吧。
在社区众多的反对声音中,有一个组织扮演了至关重要的角色——
**Codeberg e. V.**[Codeberg](https://codeberg.org) 的运营者。
Codeberg e. V.,为了简单我们就叫它 Codeberg 好了,是个大名鼎鼎的非营利组织,总部位于德国柏林。它运营着基于 Gitea 的代码托管服务——Codeberg。这个平台别的优点没有就是紫柚皿煮开放共享大家一起开开心心地用爱发电因此在开源社区名声极好。
听说了 Gitea Ltd. 的事Codeberg 可不高兴了。毕竟身为 Gitea 的重要使用者和贡献者,一大早起来发现自家的地基被人起了,能高兴才怪。于是 Codeberg 开始和 Gitea Ltd. 友好交流(口头),包括提议将 Gitea 的控制权交给非营利组织等。不幸的是,最后双方并没有达成一致。
众所周知惹日耳曼人的后果是很可怕的。于是Codeberg 有了一个邪恶的主意——闪击 Gitea开个玩笑
### 从 Gitea 到 Forgejo
2022 年 12 月 15 日为了延续自托管代码平台自由、社区治理的传统Codeberg 公布了 Forgejo 项目。
Codeberg 的原话是:
> Luckily Codeberg is in a unique position to reconnect the Gitea community in one place, independent and out of control of Gitea Ltd. And so we did.
有时候不得不感叹,历史不会重复,却永远押着同样的韵脚。
> 彼时彼刻,恰如此时此刻。
后面的故事我们就不详细说了Forgejo 当然延续了下来,并且开始积极地开发新功能、修复旧问题。如今的 Forgejo 虽然还没办法取代 Gitea 的地位,但是也已经有了一批忠实的追随者和热闹的社区,也凭借自己「永远自由」的承诺,成为了 FOSS Forge 的扛旗者之一。
## 关于 Forgejo
故事讲完了,我们来说说 Forgejo 本身吧。
Forgejo 的名字应该是来自「forĝejo」也就是世界语的名词「forge」。虽说世界语暂时来看不太世界但是用在这里似乎还蛮有兼济天下的情怀的。
## 安装 Forgejo
### 安装
当然还是使用 `docker-compose` 一把梭。理论上来说这里应该选择自由的 Podman但是奈何小氯实在是太习惯于 docker-compose 了,红豆泥私密马赛。
```yaml
services:
server:
image: codeberg.org/forgejo/forgejo:10
container_name: forgejo
environment:
- USER_UID=1000
- USER_GID=1000
restart: unless-stopped
volumes:
- ./forgejo:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- '3000:3000' # 也可以只映射到 127.0.0.1 或者别的地址,看你的习惯
- '2222:22' # 端口改一个你喜欢的就好
```
下面使用 `docker-compose up -d` 即可。这个镜像在 Codeberg国内的机器能连上但是会有亿点点慢还请耐心等待。
当然,用 `podman-compose up -d` 也完全跑得起来。不需要怀疑,小氯已经帮您试过啦 (\*≧ω≦\*)
### 反代
略去。
### 初始化
访问 `https://git.yourdomain.tld`,会看到一个初始化的界面,按照其指示来配置即可。
不过友情提示一下:如果选择关闭注册,并在初始化界面创建管理员的话,容易卡住,可以先开放注册,注册管理员后编辑 `your-dir/forgejo/gitea/conf/app.ini`,把 `service` 节的 `DISABLE_REGISTRATION` 改为 `true` 即可。~~所以为什么不用 TOML 呢?~~
此外,如果您托管的是一个私人实例,最好把联邦功能关掉,编辑上面的 `app.ini`,加入下面的配置即可——所以这好像也是默认选项来着:
```ini
[federation]
ENABLED = false
SHARE_USER_STATISTICS=false
```
……等会?联邦?!
嗯呐就是联邦Federation。Forgejo 正在积极开发联邦的功能,让各个实例的用户们能够跨实例进行协作,虽然说这个功能还没实装,但是确实很吸引人。
真是个天才的想法呢,~~小氯为什么没想到~~
### 后续
后续没后续了。Forgejo 的操作相当简明,大家开开心心地用即可。
不过小氯倒是遇见了个问题,就是在 GPG 密钥生成加强签名时出现了警告:
```txt
gpg: WARNING: server 'gpg-agent' is older than us (2.2.44 < 2.4.7)
gpg: Note: Outdated servers may lack important security fixes.
gpg: Note: Use the command "gpgconf --kill all" to restart them.
gpg: using "XXXXX" as default secret key for signing
gpg: problem with fast path key listing: IPC parameter error - ignored
```
这个问题有点莫名其妙的,小氯试过 `gpgconf --kill all` 和重装 GPG Agent最后好像也没解决。不过至少是不耽误用了。
## 我应该切换到 Forgejo 吗?
~~小氯每日入机中文~~
简而言之:
- 如果您还没有自己的 Forge 平台,那我推荐 Forgejo。
- 如果您不是原教旨 FOSSer并且用 Gitea 用得很习惯那继续用着就好——二者的功能在现阶段的差异其实可以忽略不计使用体验没有大的区别。甚至呢Gitea 的社区和生态还要更成熟一点。
- 如果您用的是 GitLab……嗯哼
## 后话,以及碎碎念
本来呢,是想水一篇半教程半笔记性质的小盆栽的,结果不知不觉变成了开源历史 + 技术笔记 + 乱七八糟碎碎念混合体。~~同时也鸽了好几天,你这只鸽子精啊喂~~
小氯知道 Gitea 的时间蛮久的了,大概从接触博客的远古时期就从[孙哥那里](https://blog.clf3.org/server-03/)听过了 Gitea一直认为这就是最好的自托管 Git 服务了(虽然这个评价也不算过誉),接触 Codeberg 之后更加重了这一印象(我真傻,真的。我单知道 Codeberg 的界面长得像 Gitea却没看到页脚写了个 Forgejo API。所以后来小氯试图自托管一个 Git 服务时,毫不犹豫地选择了 Gitea于是有了 GitCl中文名小氯の鲜果茶这个小小的可爱的实例。
后来呢,嗯,由于用得太少,就被降本增效了(捂脸)。
直到最近小氯重新部署了 GitCl 从头开始,然后……我在[这里](https://social.anoxinon.de/@Codeberg/113928732561160352)看到了 Codeberg 官方的一条帖文。
……所以什么是 Forgejo 呢?于是,就有了这篇文章。
一如上面所说的Forgejo 的功能和 Gitea 非常接近。小氯切换到 Forgejo 的理由不过是因为,反正都要重新开始了,那为什么不试试新东西呢——以及,虽然小氯并不完全赞同 Forgejo 项目的观点,但是还是愿意支持一下理想主义的朋友们。
按理来说这篇文章应该在这里结束了,但是小氯忍不住想多说几句……
> [!WARNING]
> 请谨慎阅读以下内容。
### 「开源无限可分」?
小氯在读开源运动的历史时,总会不自觉地将它与另一个事物联系在一起——**国际共运**。同样是「When the world was young」的激情燃烧的岁月同样是对天下大同的理想世界的追求。如果写一句「FOSSers of all lands, MERGE!」的口号,估计也有不少的 FOSSer 会喜欢。不过,他们的问题甚至也是一样的,不得不让人感叹现实的奇妙。
有一个经典的笑话——「左翼无限可分」。不同的革命者们为了各种路线问题争吵不休分裂为各种各样的派系往往细枝末节的差异就可能导致彻底的分裂互相指责对方是「修正主义者」而开源社区呢FSF 和 OSI 到现在也没吵出个一二三四Copyleft 和 Permissive 许可证的圣战打得比十字军东征还带劲。项目的决策应该有 BDFL 还是完全的 DAO要不要和大公司合作Web3 是真正的开源吗至于各种产品的开源路线之争嗯……XEmacs 和 EmacsNode 和 ioOpenOffice 和 LibreOfficeMySQL 和 MariaDB要不要 systemd……MongoDB 的 SSPL你觉得是大局观他觉得是脑血栓……以及上面说的Gitea 分叉了 GogsForgejo 又分叉了 Gitea下一步也不知道会不会再有个后继者把 Forgejo 分叉了(~~三回啊三回~~)……凡此种种,小氯已经不想细数了。
此外还有一句话——异端比异教更可恶,对「自己人」的指责和攻击,往往比「敌人」更激烈。国际共运的例子这里不举了,熟悉历史的朋友自有决断;开源运动嘛,看看开源社区把所谓「伪开源」或者是「不纯粹的开源」骂成什么样子了吧。不过这样吵来吵去,好像也没有获得与投入的时间和精力相匹配的结果,有时甚至出现了绝对亏损(负收益),吵也吵累了,名声也丢了,社区裂得像分布式数据库,至于代码?哦,代码还在上个 commit 里躺着,动都没动。不管怎么样,我们得庆幸开源社区没有自己的慈父和 NKVD要不然估计 V 神或者 Linus 都要被当成「反开源分子」享受赛博冰镐了。或许这也算个幸运的事:争吵无果,但至少还允许争吵。
……**所以,为什么呢**
### 世上没有乌托邦
开源运动的社区宣言的本质,就是以技术这种人类的通用语言为媒介,建立一座跨越文化边界的巴别塔,进而通过共同的思想观念统合成员们的开发行动,在人间建立起「地上天国」的技术乌托邦。然而,这种愿景能否在实践中至少不打太多折扣地落地,恐怕是一件值得探讨的事情。
GPL 和斯托曼强调伦理和社会责任OSI 和 MIT License 则侧重实用和开发价值;有人喜欢 Python 的实用,有人偏爱 Lisp 的纯粹;有人认为 Unix 哲学是不可侵犯的边界有人却表示「只要能跑起来就行」……这些理念虽然差异巨大但要说完全不可通约倒也是过于悲观。可惜涉及人类的地方总归逃不过马斯洛需求理论的制约。很多时候尤其是涉及到「方法论」或者「开发路线」这种能和伦理挂上边的东西时争论就往往不再是单纯的信念之争而是涉及自我身份认同和群体归属的建构需求。人类总喜欢把一件符合自己偏好的东西图腾化如「GPL 是自由软件和自由精神的圣杯」,那么所有可能违逆图腾的事物,都是对自我主体性的威胁。直观点说,这种行为就是图腾化某一事物或者价值后的「上纲上线」。
而在现实实践中开源运动也面临着理念与实践的永恒裂隙。「用爱发电」是件值得尊敬的事但是如果你强制要求所有的开源开发者都要用爱发电那多少有些道德绑架。从自己的辛勤劳动中获得或多或少的物质报酬无可非议一个开源社群本身往往也需要资金维持其运转。然而如何平衡理想主义的志愿者们心中「纯粹」的开源与更加「实际」的项目运转如何处理开源社区和商业公司的关系则又是个三个鸡蛋跳舞的难题。Apache 基金会与科技巨头的微妙关系MongoDB 被迫修改许可证的巨大争议,抑或是 Amazon 打包开源项目用于盈利,以及「自主研发」的 CEC-IDE……究竟是「不食嗟来之食」地坚持反商业化的原教旨主义抑或是冒着「堕落」的风险尝试某种形式的商业化面对商业公司的吸血究竟是宁折不弯还是起身还击……像是一道目标函数无下界的非凸优化问题你永远没办法让所有人满意甚至「不不满意」但是可以轻松做到让所有人都不满意。而更糟糕的恐怕是开源社区不是什么「超越政治的纯粹技术空间」。俄乌冲突的 NPM 包投毒事件Linus 对 Linux 内核的俄罗斯维护者「重拳出击」的操作,再理想再浪漫的人也无法视而不见。
### 去中心化与无政府
维特根斯坦早已揭示:「私有语言不存在。」任何协作都需要共同规则,虽然因为种种原因,分歧不但存在而且巨大,但是我们能否维系一个共同,甚至可以接受一定模糊的规则?
很遗憾,这点很难。这里我们考虑的并不是如何求同存异,而是谁来定这个规则。
小氯前面说过,开源运动某种意义上很像国际共运。很明显,国际共运中的重要一员——无政府主义,也和开源社区很合得来。「去中心化」这个词,估计在区块链这类大众眼中的 Web3 技术兴起前就被开源社区开开心心地用上了。分散权力、社区决策听起来确实很美好而且在实践中很多时候也确实令人振奋。但是和无政府主义的困境一样如果我们稍加计算就能发现完全的去中心化社会是不可能在任何一个稍大的规模长久维系的——它的熵实在太高了。体现在实践中就是去中心化自治组织的治理成本指数级增长争议解决机制的缺失导致「代码共产主义」在实践中退化为议而不决的松散联盟。所以一定程度的中心化不可避免无论是为了更高效的协作、更明确的规章还是更好的可持续性与传承。成功的开源实践大都会走向制度化Linux 基金会如此Mozilla 亦如此。而在项目初期起到决定性作用的主要开发者们,也常常被加冕为项目的 BDFL他们的话可以在实质上主导项目的走向。然而这种制度本身就是对开源式民主理想的巨大讽刺如同拿破仑加冕为「革命的皇帝」一般。而从实践的角度BDFL 也难以完全成为诺顿皇帝式的仁慈、放权的领袖Linus 的「暴君式管理」就是一个例证。一旦权威缺失或失误,社区将立即陷入权力真空。而将权力的中心移交给一个组织,也并没有好到哪去,如同历史上布尔什维克主义的先锋党一般。我们大可以拿上面的 Gogs 三代人举个例子Gitea 将权力从 Unknwon 手中交到了社区,核心开发者们又将这份权力移交给了 Gitea Ltd.Codeberg 愤而另起炉灶,于是有了 Forgejo。那么我们还可以问Codeberg 会不会成为下一个绝对话事人?毕竟,非营利组织确实容易给人以不错的印象,但是这并不就是促进社区共同进步或者至少是「不作恶」的绝对保障。
另一个「去中心化的诅咒」是 Fork 机制。Fork 被视作开源民主和自由的终极体现,但是分叉权也导致生态碎片化。当 Node 分裂出 io 时,短期内确实激发活力,但长期来看是宝贵的社区注意力资源的消耗,也就是我上面说的,精力都用在内斗上了。
### 后记
……大放厥词了这么久,按照所谓的「批判性思维」的要求,我们似乎也应该说一点讨喜的话了。事实上我们也确实值得这样说。
自计算机科学的青铜时代,从 ENIAC 的真空管到量子比特的辉光间,软件的甲骨文和硬件的青铜器的相互交织就将自由、开放和共享刻进了计算机科学的灵魂。而客观上来说,无论是 DeepSeek-R1 在人工智能界掀起的惊涛骇浪,或者是新一届的 FOSDEM 大会,抑或是灿烂阳光下的新大陆开发者们,都在告诉我们:开源社区的脚步永远不会停下,即便分歧、争论抑或难题。而且,历史无法重构,但代码可以 fork。或许这就是开源比革命更幸运的地方在这里没有哪一种失败是终结每一次「不可调和的分歧」都可能孕育下一个版本更新或者是「再次出发」的宣言。或许是握手言和、合并回主分支或许是就此别过、成为两个不同的产品。没人能彻底移除项目的 `.git`,若是我们再难携手,那便卷起我的 repo大路朝天各走一边。或许在我们的眼中这些 fork 记录是分歧与裂痕,但实则是技术演化的年轮。
开源运动的终极浪漫,或许本就不在于消除分歧,而在于将每次争论都转化为新的 commit hash。此时此刻从东京到洛杉矶从上海到开普敦从雷克雅未克到布宜诺斯艾利斯总有人在终端中写下
```bash
git push origin new-horizon --force-with-lease
```
这或许就是数字文明最动人的地方:即便世界洪水滔天,每个 repo 都是自己的世界中不沉的诺亚方舟。
总而言之,我们还是留下一个光明的尾巴吧。依然心有火炬的人们还会歌唱「英特纳雄耐尔,就一定要实现」,小氯也相信,即使我们永远也达到不了我们理想的彼岸,但是我们至少可以用自己的一生,让我们离我们梦中的技术天国越来越近。
「**Que la info fluya como el viento**.」