离开GitHub转而使用Forgejo

TL;DR · AI 摘要
作者因对代码所有权的担忧离开GitHub,转而使用Forgejo。
核心要点
- GitHub频繁宕机
- Forgejo更注重代码安全
- 荷兰政府也选择了Forgejo
结构提纲
按章节快速跳转。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- 作者离开GitHub转而使用Forgejo
- 原因
- 代码所有权控制
- 减少宕机风险
- 政府视角
- 荷兰政府选择Forgejo
金句 / Highlights
值得收藏与分享的关键句。
GitHub频繁宕机,导致用户数据丢失和系统中断。
Forgejo作为自托管平台,减少了宕机风险并提高了安全性。
荷兰政府选择Forgejo,强调了代码安全的重要性。
我将我的代码从 GitHub 移动到了自托管的 Forgejo。并非因为宕机问题,而是因为谁拥有这些平台上的运行内容。荷兰政府也在做出同样的决定。
2026年4月27日,荷兰内政部发布了 code.overheid.nl,这是一个由荷兰政府源代码构建的自托管的 Forgejo 实例。项目负责人 Boris Van Hoytema 表示该平台“是由内政部有法律义务将其源代码发布到一个它自己拥有的地方的要求催生的”,并且他们选择了 Forgejo 而不是 GitLab,因为 Forgejo 是完全开源的,并且提供了实现数字自主权所需的全部自由。
一周前,我悄悄地将自己的代码也移动到了相同的方向。我的主 Git 服务器现在位于 code.jorijn.com,运行着 Forgejo v15 LTS,在一台加固的 NUC 上。一些仓库已经在那里;其余的正在排队。迁移完成后,长期计划是将我的公共 GitHub 仓库归档,并指向新的家。
大多数关于离开 GitHub 的文章都会提到宕机问题。宕机确实存在,但这并不是我离开的原因。宕机、默认启用的 AI 选项以及 GitHub 再也找不到首席执行官的事实都是同一个根本事实的症状:我不再拥有这一切。荷兰政府也在四月份做出了同样的结论。因此,这是这种思考方式的完整版本,以及一旦你决定采取行动,实际迁移看起来是什么样子。
TL;DR
- GitHub 在 2025 年 5 月至 2026 年 4 月期间记录了 257 个事件,其中 48 个是重大事件。首席技术官公开道歉并表示容量需要扩大 30 倍以跟上基于 AI 的负载。
- 2025 年 8 月,GitHub 停止了其首席执行官职位。它现在是微软核心 AI 部门的一个组成部分,该部门正在构建 Copilot 和更广泛的 AI 堆栈。
- 2026 年 4 月 24 日,GitHub 将 Copilot 免费版、专业版和高级版用户的交互数据默认设置为启用 AI 训练,没有仓库级别的退出选项。
- 根据 FISA 第 702 条和 CLOUD 法案,美国司法管辖权下的风险尚未解决。微软的法律顾问在宣誓时表示无法保证欧盟的数据不会受到沉默中的美国政府访问的影响。
- 荷兰政府在 2026 年 4 月选择 Forgejo 作为 code.overheid.nl 的原因与我选择的理由相同。我正在为我的工作做同样的事情。
- code.jorijn.com 运行着 Forgejo v15 LTS,在一台 NUC 上使用 KVM 隔离,每周重建一次 Actions 作业。公共 GitHub 仓库将在迁移完成时被归档,并指向新的家。
出现宕机问题并不意味着真正的原因
2026 年 4 月的宕机问题让工程师们感到愤怒。2026 年 4 月 23 日,合并队列的合并代码路径在推出不完整的功能标志后,默默地撤销了 658 个仓库和 2,092 个拉取请求中的先前合并提交。包括 Modal 和 Zipline 在内的公司进行了手动数据恢复。四天后,一个过载的 Elasticsearch 集群导致 Pull Requests、Issues 和 Packages 下线超过六个小时。
但每个月的情况都是一样的糟糕。2026 年 2 月仅记录了 37 个事件,其中包括一次持续 3 小时 40 分钟的宕机事件,导致 Actions、Copilot 编码代理、代码审查、CodeQL、Dependabot 和 Pages 下线。2025 年 10 月 1 日发生了一个十小时的 macOS 作业宕机。IncidentHub 的汇总显示 2025 年 5 月至 2026 年 4 月的总事件数为 257 个事件和 48 个重大宕机,总计约 112 小时的停机时间。
正确解读这个列表的方式不是“GitHub 不可靠。”大型系统会出问题。正确解读的方式是 GitHub 自己所提出的框架。首席技术官 Vlad Fedorov 在 4 月 28 日道歉,表示容量需要增长 30 倍才能跟上负载。他将这种负载直接归因于“代理 AI 工作流增长”自 2025 年 12 月以来。可靠性故事源于 AI 故事。GitHub 没有减缓 AI 功能的步伐。相反,它正在加倍投入。宕机就是生产环境中加倍投入的样子。
Pragmatic Engineer 指出 GitLab、Bitbucket、Vercel、Linear 和 Sentry 在这一年中都没有出现这种情况(https://newsletter.pragmaticengineer.com/p/the-pulse-ai-load-breaks-github-why)。它们同样面临着相同的总体需求压力。GitHub 正在处理的问题是特定于 GitHub 的。
GitHub 再也找不到首席执行官
更大的事实比道歉还要古老,并且得到了更少的关注。2025 年 8 月 11 日,Thomas Dohmke 作为 GitHub 的首席执行官辞职。微软并没有任命他的继任者。相反,GitHub 被吸收进了微软的核心 AI 部门,该部门在 2025 年 1 月由 Satya Nadella 引入,其使命是“为第一方和第三方客户提供端到端的 Copilot 和 AI 堆栈”。
GitHub 的收入、工程和支持现在报告给微软的开发者部门,由 Julia Liuson 负责。GitHub 的首席产品官向微软的 AI 平台副总裁汇报。品牌仍然存在。独立领导层不再存在。
This matters because the older argument for staying on GitHub was that Microsoft kept it at arm's length. From 2018 through 2024 that was substantively true. Dohmke had a real seat. Product decisions were visibly GitHub's, not Microsoft's. After August 2025 that argument no longer holds. When you push code to github.com today, you are pushing it to a unit of Microsoft's AI organization. Whether that bothers you depends on how much you trust Microsoft's AI organization to make the same decisions about your repository that the older GitHub would have made. I no longer do, and the reason for that distrust shows up in the next section.
## The training-data default flipped
On March 25, 2026 GitHub [announced a privacy-statement change](https://github.blog/changelog/2026-03-25-updates-to-our-privacy-statement-and-terms-of-service-how-we-use-your-data/) effective April 24. From that date, _interaction data, specifically inputs, outputs, code snippets, and associated context, from Copilot Free, Pro, and Pro+ users will be used to train and improve our AI models unless they opt out_.
Three things about that statement matter, in order.
First: opt-out, not opt-in. The default flipped. Anyone using Copilot for free, on Pro, or on Pro+ is now contributing to model training unless they go to the Copilot settings page and turn it off.
Second: there is no repository-level switch. As a maintainer, I cannot tell GitHub _don't train on interactions inside my repository_. The opt-out is per user account, so each contributor has to make their own choice. In effect, my codebase becomes training material whenever anyone using Copilot Free/Pro/Pro+ touches it, no matter how I license it.
Third: the carve-out for private repositories is narrower than it sounds. GitHub says it does not use private-repo content "at rest" for training, but it does collect "code snippets and interaction context" generated _while_ Copilot is being used inside a private repo. The line between _the code at rest_ and _the snippets generated while editing it_ is, charitably, blurry.
Copilot Business and Copilot Enterprise customers are exempt because they are governed by separate Data Protection Agreements. The split is clean: pay enough and your interactions are not training data. Otherwise they are.
I [wrote about agentic GitHub Actions](https://jorijn.com/en/blog/github-actions-agentic-workflows-natural-language-cicd/) a few weeks ago, and at the time the security model was the headline. The training-data flip is the second half of the same story: GitHub's strategic interest in your interaction data is structural now, not optional. I am not interested in arguing about the merits of that strategy on someone else's platform. I would rather not be on the platform.
## Then there's the jurisdiction
Underneath all of this is a layer that doesn't shift when the privacy statement does. GitHub Inc. and Microsoft Corp. are US companies. Anything they hold sits in scope of US law, including [FISA Section 702](https://www.congress.gov/crs-product/R48592) and the [CLOUD Act of 2018](https://natlawreview.com/article/beyond-server-location-why-new-fight-over-fisa-702-and-cloud-act-matters-corporate). Both apply regardless of where data physically sits.
Section 702 was reauthorised in April 2024 for two years and is currently running on a [45-day extension](https://www.cnbc.com/2026/04/30/fisa-section-702-congress-extension.html) signed at the end of April 2026 while Congress argues over a longer renewal. It authorises US intelligence collection against non-US persons through electronic communications service providers domiciled in the US. The CLOUD Act lets US law enforcement compel a US-headquartered company to produce data stored anywhere in the world.
GitHub announced [EU data residency for Enterprise Cloud](https://github.blog/changelog/2024-10-29-github-enterprise-cloud-data-residency-in-the-eu-is-generally-available/) in October 2024. That solves data location. It does not solve jurisdiction. CLOUD Act exposure follows corporate control, not geography.
The most honest articulation of this came not from a regulator but from Microsoft's own attorney, who told a French Senate hearing in June 2025, under oath, that he [could not guarantee French data stored in European Microsoft datacentres was safe from silent US government access](https://techcrunch.com/2026/04/27/whats-behind-europes-efforts-to-ditch-u-s-software-in-favor-of-sovereign-tech/).
I covered the broader legal picture in my earlier piece on [why "hosted in Frankfurt" doesn't mean GDPR-compliant](https://jorijn.com/en/blog/eu-data-sovereignty-hosted-in-frankfurt-not-gdpr-compliant/), and the operational implications for hosting providers in [my piece on NIS2](https://jorijn.com/en/blog/nis2-directive-for-hosting-providers-and-their-clients/), so I'll keep the detail there. The point that matters here is narrow. As long as your code lives at github.com, your code lives in US legal territory. EU data residency is a comfort, not a fix.
## The Dutch government's call: code.overheid.nl
This is where the Dutch government's choice deserves more attention than it got. The legal driver is the Netherlands' "[Open, tenzij](https://fsfe.org/news/2020/news-20200424-01.en.html)" policy, in force since 2020: software developed with public funds is open source by default unless security or confidentiality requires otherwise. To comply, the ministry needed somewhere to publish code that it actually controlled. Code.overheid.nl is the answer.请注意,由于代码块和图片链接保持原样,因此未进行翻译。
The piece worth pausing on is which forge they chose. The European Commission runs code.europa.eu on self-hosted GitLab, live since September 2022. Germany's openCode is also GitLab. France's code.gouv.fr is an aggregator that indexes repos hosted elsewhere, not a forge in itself.
The Dutch government's choice of Forgejo, not GitLab, was deliberate. As the OSOR article put it, the rationale was that Forgejo is fully open source, with no open-core split, and offers all the freedoms needed for digital autonomy. Van Hoytema added that Forgejo's roadmap was "way more aligned" with theirs than the alternatives. The government did not just want a sovereign forge. They wanted a sovereign forge that wasn't gated behind a commercial vendor's premium tier.
So the institutional pattern matters: a national government with serious lawyers and a long memory looked at the same picture I was looking at, made the same decision, and shipped it the week before I did. That isn't proof that the decision is right. It is, at minimum, proof that the decision is no longer fringe.
Why Forgejo, and not GitLab
I weighed GitLab seriously. Self-hosted GitLab CE is a known quantity, with a much larger commercial ecosystem and, frankly, a more polished UI. Two things tipped the choice.
First: licensing. GitLab is open core. The Community Edition is MIT-licensed, but many of the features I'd actually want in production live in the Enterprise tiers under a non-free license. Forgejo went the other way. As of v9.0 in August 2024 the project relicensed from MIT to GPLv3+, with the explicit goal of staying copyleft and resisting future commercial capture of the codebase. The fork from Gitea in December 2022 happened precisely because Gitea Ltd took control of the trademarks and domains in a way the community had not consented to. The lesson learned shows up in the license.
Second: governance. Forgejo lives under Codeberg e.V., a non-profit registered in Berlin since September 2018, with a member-elected board, public budgets, and 300,000+ repositories on its hosted instance. Members vote on the budget annually; the 2025 plan was accepted with 88 in favour, zero against, one abstention. That is not a marketing claim about community governance. That is a German _Verein_ doing what _Vereine_ do.
Forgejo v15.0 LTS shipped on April 16, 2026. It is the project's 100th release. Long-term support runs through July 15, 2027. Forgejo Actions reached the maturity I needed (ephemeral runners, OpenID Connect, reusable workflow expansion) in v15. Releases since the fork have been steady, with active monthly reports.
The honest caveat: the commercial Forgejo ecosystem is real but thin. The cleanest commercial offering today is Codey by VSHN, a Swiss-hosted managed Forgejo from 19 CHF per month, launched on Servala in March 2025. There is no Red-Hat-style enterprise support subscription. If you need 24/7 phone support and a vendor to point at, you will need to build that yourself, or wait. I am willing to wait, because I would rather own the platform.
What I built, and why it looks the way it does
Code.jorijn.com runs on a single Intel NUC with 64 GB of RAM in my home office. Forgejo v15 LTS, Postgres 17, and Traefik live inside Docker. An Incus-managed KVM virtual machine sits beside them and runs my Forgejo Actions runner. That is the whole platform.

The interesting decision is not in the Forgejo deployment. Forgejo plus Postgres plus a reverse proxy is not interesting. The decision that took the most thought is the runner.
Where the danger actually is
If you self-host a forge, the forge itself is the easy part. The hard part is whatever runs the CI jobs. My runner has to execute npm install, composer install, and pip install on a daily Renovate schedule, against lockfiles generated by my own repositories. That means it executes lifecycle scripts. It means every job potentially runs untrusted code, of the same general shape that recent npm-worm and axios supply-chain attacks used to ride dependency bots that auto-merged within an hour.
The runner's job, in other words, is not to run code. The runner's job is to _contain_ the code while it runs. Everything in the runner architecture exists for that reason. The same logic I described in my piece on unmaintained dependencies applies here: assume any single layer can fail, and design so the next one absorbs the failure.
The defenses, weakest to strongest
The runner uses five layers, in order from softest to hardest.

- 一个持久的KVM虚拟机。 运行者生活在自己的VM中,而不是宿主机上的容器中。宿主机的内核不会与作业环境共享。如果运行者的Linux内核CVE要接触NUC,必须突破KVM边界。
- gVisor作为默认的Docker运行时在该VM中。 作业容器在
runsc中运行,runsc拦截用户空间中的系统调用,而不是将其传递给宿主机内核。容器逃逸必须突破gVisor以及周围的KVM。 - 每周一次的破坏性重建。 每周一凌晨02:00 UTC,整个VM都会被销毁并从一个新鲜烘焙的Ubuntu基础镜像重新创建,新的持久运行者注册表在Forgejo上生成。基础镜像本身在周日重建,因此新VM会消耗那周的apt和内核补丁。持久状态不能超过七天。
- 运行者的桥接上的nftables出口过滤器。 运行者可以到达公共目的地的
:443、:80、:22和:53(npm、pypi、ghcr、我的Forgejo通过路由器的反向NAT访问)。它无法到达192.168.0.0/16、10.0.0.0/8或172.16.0.0/12。被挟持的作业无法扫描我的局域网,无法访问路由器管理界面,也无法访问主机的其他服务。 - 范围绑定的运行者令牌,永远不是全局绑定的。 两个持久运行者注册分别绑定到单一用户范围和单一组织范围,具有
write:user,write:organizationPAT范围用于管理。泄露的令牌无法注册超出其范围的运行者,而且绝对无法执行任何全局绑定的操作。
这种组合故意重叠。每一层都是栅栏。它们一起形成了一道有深度的围墙。这些都不是新颖的东西,在意义上说,所有基本元素都来自上游并且非常详细地文档化了。不同之处在于将它们组合在一起,以一个单用户的家庭实验室为目标,整个平台可以在一个NUC上运行,并且在出现问题时能够干净地回滚。
底层的基本元素,KVM隔离、gVisor、每周重建和范围绑定的运行者注册,都是Forgejo和Incus支持的原生功能。我只是需要将它们结合起来。
我放弃的
这是我要写的部分,因为每一篇文章我都尊重的文章都有一个。所以:将迁移给Forgejo的成本,诚实地告诉我。
发现和社会图谱。 GitHub是我贡献者的发现地点。当有人在一个公开仓库中推送一个小修复时,他们期望在github.com上完成,而不是在一个从未听说过的域名上。我计划的工作方向是在迁移完成后归档每个公开的GitHub仓库,并指向code.jorijn.com的README。发现路径保持不变:人们仍然通过GitHub找到我,看到归档通知,然后跟随链接到Canonical Home。我还没有做到——一些仓库已经在code.jorijn.com上存在,其余的排队等待。直到那时,这个差距是真实的,我接受这一点。
GitHub Actions生态系统脆弱性。 Forgejo Actions故意追求熟悉度,而不是兼容性。大多数事情都能正常工作。有些不能。工作流级别上的permissions:块会被静默忽略。actions/checkout@v6在2026年初破坏了非GitHub运行者的认证检出,所以我将所有内容都锁定在v5。actions/upload-artifact@v4需要使用Forgejo托管的分支。OIDC可以工作,但使用不同的工作流密钥(enable-openid-connect: true),而不是GitHub的permissions: id-token: write。这些都不是障碍。这些都是摩擦。如果你的工作流程依赖于GitHub特定的功能,迁移是一个项目,而不是一个晚上就能搞定的事情。
Dependabot。 Forgejo没有它。我在同一个自托管运行器上运行Renovate,每隔3小时运行一次。它做同样的工作。它有更多的配置。设置花了我一天时间。
全天候供应商支持。 GitHub Enterprise给你一个电话号码和SLA。Forgejo给你一个问题跟踪器和聊天室。对于一个人运营来说,这很好。对于一个拥有200名工程师的组织来说,这可能不行,这也是等待的一个真实原因。
当这不是值得做的时候
如果以下任何一个条件为真,我不会迁移到自托管的Forgejo。
- 团队对运行基础设施没有胃口或能力。托管的Forgejo(Codey或Codeberg针对开源)关闭了大部分这一缺口,但你仍然承担迁移成本。
- 你高度投资于GitHub特定的功能:GitHub Apps市场、Codespaces、Copilot Workspace、高级安全。Forgejo是一个铸币厂,而不是开发平台即服务。
- 你的贡献者基础是GitHub社会图谱。如果可发现性比所有权更重要,留在贡献者所在的地方。或者接受摩擦,一旦迁移完成,将你的公共仓库指向你的新家,并稍后重新考虑这个决定。
- 你没有可信的运营答案来处理运行者。运行者是这里变得严肃的部分。如果你没有准备好思考KVM隔离、gVisor、nftables和每周重建,运行你的CI作业在托管运行器主机上,或者留在GitHub。
荷兰政府的模式在这里也是正确的。他们没有一次性迁移一切。Code.overheid.nl是一个软启动平台,让部门分享开源代码,而不是对其他一切进行整批发放。我的设置也是如此:Forgejo是我的工作标准,GitHub是一个镜像,我愿意在迁移完成后稍后重新考虑这个镜像。
关键启示
- GitHub 已不再是拥有独立首席执行官的公司了。自 2025 年 8 月起,它已成为微软核心 AI 部门的一部分。
- 2026 年 4 月的宕机事件和 Copilot 训练数据默认翻转都是同一转变的结果。两者都可以从结构上预测到。
- 根据《FISA 702》和《CLOUD 法案》的司法管辖风险是真实存在的且无法解决。欧盟的数据居留权是一种安慰而非解决方案。
- 荷兰政府于 2026 年 4 月选择了 Forgejo 为其 code.overheid.nl 的部署,原因相同。这种机构模式正在形成。
- 在单个 NUC 上实现一个可辩护的自托管 Forgejo 部署是可行的,但跑马机关键在于真正细心照料:KVM 隔离、gVisor、每周重建、受范围限制的令牌以及一条阻止您局域网的出口过滤器。
- 迁移摩擦是真实的。通过指向新家的指针归档您的公共 GitHub 存储库可以保持发现路径完整,直到完成迁移。
重复出现的服务器或部署问题?
我帮助团队使生产环境可靠,采用 CI/CD、Kubernetes 和云技术——这样修复才能持久,部署才能不再令人焦虑。