Je eigen Git-forge hosten: wat een overstap naar Forgejo betekent voor je .NET-pipelines

Een veelbesproken pleidooi om GitHub te verlaten voor zelf-gehoste Forgejo wakkert het soevereiniteitsdebat weer aan. Maar wat kost die migratie écht zodra je CI/CD .NET bouwt?

Jean-Pierre Broeders

Freelance .NET Developer

29 mei 20269 min. leestijd
Je eigen Git-forge hosten: wat een overstap naar Forgejo betekent voor je .NET-pipelines

Je eigen Git-forge hosten: wat Forgejo betekent voor je .NET-pipelines

Een blogpost met de titel "Why I'm leaving GitHub for Forgejo" stond deze week bovenaan op Hacker News en haalde honderden reacties op. De auteur, Jorijn Schrijvershof, verplaatste zijn canonieke Git-host naar een zelf-gehoste Forgejo-instantie op één enkele NUC, en bouwde zijn argument rond eigenaarschap in plaats van uptime. De timing is veelzeggend: diezelfde week was er ook een trending verhaal over een kwaadaardige VS Code-extensie die duizenden GitHub-repositories compromitteerde. Die twee draadjes rijmen op elkaar.

Ik ga je niet vertellen dat je GitHub er morgen uit moet trekken. Ik ben .NET-freelancer; de meeste van mijn klanten zitten op GitHub of Azure DevOps en blijven daar. Maar het migratieargument verdient een serieuze blik, juist omdat het niet langer iets voor de marge is — en omdat het onderdeel dat iedereen onderschat is wat er met je CI/CD gebeurt zodra de forge van jou is. Dit is dus de praktijkversie: wat de overstap werkelijk drijft, en wat het kost wanneer je pipelines C#-code bouwen en testen.

Het argument, kort samengevat

Haal je de emotie eruit, dan rust de zaak voor vertrek op drie structurele feiten, niet op storingen.

Ten eerste: GitHub heeft geen eigen CEO meer. Nadat Thomas Dohmke in augustus 2025 vertrok, werd GitHub opgenomen in Microsofts CoreAI-divisie. Het merk overleeft; de onafhankelijke leiding niet. Het oude argument "Microsoft houdt het op afstand" klopt niet meer.

Ten tweede: de standaard voor trainingsdata is omgedraaid. Sinds 24 april 2026 wordt interactiedata van Copilot Free, Pro en Pro+ gebruikt om modellen te trainen, tenzij je je afmeldt — en er is geen knop op repository-niveau. Als maintainer kun je niet zeggen "train niet op interacties binnen mijn repo"; elke contributor moet zich apart afmelden.

Ten derde: jurisdictie verhuist niet mee met je data. GitHub Inc. en Microsoft Corp. zijn Amerikaanse bedrijven, dus hun data valt onder FISA Section 702 en de CLOUD Act, ongeacht waar die fysiek staat. EU-dataresidentie lost de locatie op, niet de jurisdictie.

Waarom dit niet slechts de mening van één developer is: op 27 april 2026 lanceerde het ministerie van Binnenlandse Zaken in soft-launch code.overheid.nl, een zelf-gehoste Forgejo-instantie, met een bewuste keuze voor Forgejo boven GitLab juist omdat het volledig open source is zonder open-core-splitsing. Als een nationale overheid met serieuze juristen tot dezelfde conclusie komt — een week eerder dan een zelfstandige consultant — dan heeft die beslissing de marge verlaten.

Waarom Forgejo en niet GitLab

Twee dingen geven de doorslag. Licentie: GitLab is open core — de Community Edition is gratis, maar veel van wat je in productie wilt zit achter de Enterprise-licentie. Forgejo deed het omgekeerde en herlicenseerde in v9.0 (augustus 2024) naar GPLv3+ om copyleft te blijven en commerciële overname te weerstaan. Governance: Forgejo valt onder Codeberg e.V., een door leden bestuurde non-profit, geregistreerd in Berlijn. Het project splitste in december 2022 van Gitea af, precies omdat een bedrijf de controle over de handelsmerken naar zich toetrok; de licentiewijziging is de geleerde les. Forgejo v15.0 LTS verscheen op 16 april 2026, met ondersteuning tot midden 2027.

Voor een .NET-omgeving is de praktische kop dat Forgejo Forgejo Actions levert, dat mikt op vertrouwdheid met GitHub Actions. "Vertrouwdheid", niet "compatibiliteit" — en dat onderscheid is hét hele verhaal voor je pipelines.

Wat er werkelijk met een .NET-pipeline gebeurt

Hier is een normale GitHub Actions-workflow voor een .NET-service: restore, build, test, publish. Op Forgejo Actions draait het meeste gewoon. Onderstaande YAML werkt vrijwel ongewijzigd op een zelf-gehoste Forgejo-runner:

name: build-test
on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v5          # pin op v5, zie hieronder
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '9.0.x'
      - name: Cache NuGet
        uses: actions/cache@v4
        with:
          path: ~/.nuget/packages
          key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
          restore-keys: |
            ${{ runner.os }}-nuget-
      - run: dotnet restore
      - run: dotnet build --no-restore -c Release
      - run: dotnet test --no-build -c Release --logger trx

De NuGet-cachestrategie is identiek aan die van GitHub — de actions/cache-API is aan de Forgejo-kant opnieuw geïmplementeerd. Maar er zijn scherpe randjes die je pas vindt door erin te trappen:

  • permissions:-blokken op workflow-niveau worden stilzwijgend genegeerd. Leunt je beveiligingsmodel op het per job inperken van de GITHUB_TOKEN, dan verdampt die aanname. Je moet least-privilege dan afdwingen op het niveau van de runner en de tokenregistratie.
  • actions/checkout@v6 brak authenticated checkout op niet-GitHub-runners begin 2026. De fix is weinig spannend: pin alles op @v5.
  • actions/upload-artifact@v4 vereist de door Forgejo gehoste fork, niet de upstream-versie. Artifact-zware pipelines hebben een audit nodig.
  • OIDC werkt, maar de sleutel is anders. GitHub gebruikt permissions: id-token: write; Forgejo gebruikt enable-openid-connect: true. Federeer je naar Azure om te deployen zonder langlevende secrets, dan is dit de regel die je herschrijft.

Dat laatste punt is het belangrijkst voor .NET-teams, want het nette patroon om vanuit CI naar Azure te deployen is OIDC-federatie — geen AZURE_CREDENTIALS-secret in de repo. Het werkt nog steeds op Forgejo, maar zowel de workflow-sleutel als de trust-configuratie aan de Azure-kant moeten worden aangepast. Reken op een middag, niet vijf minuten.

En Dependabot bestaat niet op Forgejo. De standaardvervanger is Renovate, zelf-gehost op dezelfde runner. Het doet hetzelfde werk met meer configuratie — wat voor een NuGet-zware solution eerder een upgrade is, omdat je fijnmazige controle krijgt over grouping- en automerge-regels.

De runner is het echte project

Als je een forge zelf host, is de forge zelf het makkelijke deel. Forgejo plus Postgres plus een reverse proxy is een saai, opgelost probleem. Het lastige deel — en het deel dat je 's nachts wakker zou moeten houden — is de CI-runner, want dat is het ding dat onvertrouwde code uitvoert.

Bedenk wat je runner werkelijk doet. Hij draait dotnet restore, npm install, composer install tegen lockfiles, volgens een schema, vaak getriggerd door een dependency-bot. Dat betekent dat hij lifecycle-scripts van derden uitvoert. De trending VS Code-extensie-breach van deze week is precies dezelfde vorm van aanval: kwaadaardige code die meelift op de developer-supplychain. Een zelf-gehoste runner die Renovate-PR's binnen het uur automergt is exact het soort zacht doelwit waar zulke aanvallen naar op zoek zijn.

De taak van de runner is dus niet om code te draaien. Het is om code te omsluiten terwijl die draait. De opzet in het bronartikel stapelt vijf verdedigingslagen, en het principe generaliseert prima buiten één homelab:

  1. Een aparte KVM-virtuele machine voor de runner, zodat de host-kernel niet wordt gedeeld met job-containers. Een kernel-CVE binnen een job moet eerst uit de VM ontsnappen voordat hij de host raakt.
  2. gVisor (runsc) als standaard container-runtime binnen die VM, die syscalls in user space onderschept. Een escape moet nu zowel gVisor als KVM breken.
  3. Een wekelijkse destructieve herbouw — de hele runner-VM wordt vernietigd en opnieuw opgebouwd vanuit een vers base-image, zodat geen enkele persistente staat langer dan zeven dagen overleeft, en elke herbouw de patches van die week meeneemt.
  4. Een nftables-egressfilter dat de runner bij package-registries en de forge laat, maar de lokale netwerkranges volledig blokkeert. Een gecompromitteerde job kan niet doorpivoten naar je LAN of de router-admin.
  5. Scope-gebonden runner-tokens, nooit admin-scoped, zodat een gelekt token geen runners buiten zijn scope kan registreren.

Geen van deze primitieven is nieuw. Wat het kopiëren waard is, is de mindset: ga ervan uit dat elke afzonderlijke laag kan falen en ontwerp zo dat de volgende het opvangt. Heb je ooit mijn kijk op secret rotation of webhook-HMAC-verificatie gelezen, dan is dit dezelfde defense-in-depth-redenering, toegepast op de build-host in plaats van het request-pad. De runner is waar self-hosting ophoudt een weekendproject te zijn en echt engineering wordt.

Wanneer het de moeite waard is — en wanneer niet

Ik ben eerlijk over de afwegingen, want de migratiekosten zijn reëel.

Het is het overwegen waard als digitale soevereiniteit een echte eis is — je verwerkt data waarbij Amerikaanse jurisdictie een contractueel of wettelijk probleem vormt, of je wilt simpelweg eigenaar zijn van het platform waarop je code draait. Het past ook als je de bereidheid hebt om infrastructuur te draaien en CI wilt zonder verrassingen op de minutenfactuur.

Het is niet de moeite waard als je team geen enkele capaciteit voor ops heeft, als je zwaar leunt op GitHub-specifieke features (Codespaces, de Apps-marketplace, Advanced Security), of als je contributor-basis de GitHub-social-graph ís en vindbaarheid wint van eigenaarschap. Een managed Forgejo-host dicht een deel van het ops-gat, maar de migratie blijft van jou.

Het pragmatische middenpad — en dat wat de Nederlandse overheid koos — is geen complete rip-and-replace. Maak Forgejo canoniek voor het werk dat soevereiniteit nodig heeft, houd GitHub als mirror voor vindbaarheid, en heroverweeg later. Voor de meeste van mijn klanten is dat het realistische antwoord: een hybride waarbij de forge die jij beheert bevat wat ertoe doet, en de publieke mirror het contributor-pad intact houdt.

De conclusie voor .NET-teams

Het soevereiniteitsargument is niet langer hypothetisch, en Forgejo is inmiddels volwassen genoeg om een geloofwaardige canonieke forge te zijn. Maar beoordeel het met open ogen op het deel dat echt bijt: je pipelines. Forgejo Actions geeft je vertrouwdheid, geen compatibiliteit — pin je actions, herschrijf je OIDC-federatie, ruil Dependabot in voor Renovate, en behandel de runner als een beveiligingsproject op zich. Doe je dat, dan is self-hosting haalbaar op hardware die op een bureau past. Sla je de runner-hardening over, dan heb je net een prachtig soevereine manier gebouwd om gehackt te worden.


Bron: "Why I'm leaving GitHub for Forgejo" door Jorijn Schrijvershofdiscussie op Hacker News. De analyse en aanbevelingen voor .NET-pipelines zijn van mijzelf.

Wil je op de hoogte blijven?

Schrijf je in voor mijn nieuwsbrief of neem contact op voor freelance projecten.

Neem Contact Op