GitHub ist kein Backup. Ein gesperrter Account bewies es diese Woche.
Ein Entwickler verlor diese Woche 104 Repos. Ich hatte längst aufgehört, GitHub mit meinen zu vertrauen.
Diese Woche stellte ein Entwickler um 9 Uhr morgens fest, dass seine 104 GitHub-Repos nicht mehr existierten. Kein Hack. Kein Bug. Keine kaputte Festplatte. Nur eine automatisierte E-Mail: Account gesperrt, wir haben dein Student Pack von 2019 neu bewertet, wir denken jetzt, du warst nie berechtigt. Sechs Jahre später. 24 dieser Repos hatten nirgendwo sonst ein Backup. Verschwunden durch eine algorithmische Entscheidung an einem Dienstagmorgen.
TLDR: Falls du in derselben Situation steckst (alles auf GitHub, kein Mirror, kein Plan B), bist du einen Klassifizierer von derselben E-Mail um 9 Uhr morgens entfernt. Es gibt eine Lösung. Kostet nichts, läuft auf einem Server, den du wahrscheinlich eh schon mietest, und fast niemand macht sich die Mühe. Die Frage ist warum.

Die Antworten unter diesem Post sind die andere Geschichte. Hunderte von Devs, die in Echtzeit realisieren, dass sie in exakt derselben Situation sind. Alles auf GitHub. Kein Mirror. Kein Plan B. Und dieselbe Frage kommt in jedem Thread zurück: ok aber konkret, was mache ich jetzt?
Ich habe nicht gewartet. Nicht aus Paranoia, nicht weil ich eine Glaskugel hatte. Einfach weil du irgendwann in deiner Karriere als Dev aufhörst, "woanders gehostet" mit "gesichert" zu verwechseln. GitHub ist ein großartiges Tool. Es ist eine großartige Forge. Es ist ein großartiges soziales Netzwerk für Code. Es ist kein Backup, das war nie ihr Job, und das steht schwarz auf weiß in ihren Nutzungsbedingungen.
104 Repos. Eine Automatisierte Entscheidung. Keine Warnung.
Die Geschichte, die diese Woche die Runde machte, lässt sich in zwei Sätzen erzählen. Ein Entwickler meldete sich 2019 für ein kostenloses Student Pack an. Sechs Jahre später bewertete eine automatisierte Überprüfung die ursprüngliche Berechtigung neu, entschied rückwirkend, dass sie nie legitim war, und sperrte den Account. 104 Repos versteckt. 24 davon nie woanders gepusht.
Es ist egal, ob der ursprüngliche Student Pack-Antrag legitim war oder nicht. Was zählt ist, dass Jahre von Arbeit hinter einem Prozess verschwinden können, auf den du keinen Einfluss hast, zu einem Zeitpunkt, den du nicht vorhersagen kannst, ausgelöst von einem 2026er Klassifizierer, der ein Formular neu bewertet, das ein 19-Jähriger 2019 ausgefüllt hat.
Die Threads unter dem Post sind voller Leute, die öffentlich rechnen. Ich habe 60 Repos. Ich bin seit 2014 auf GitHub. Ich habe nie an einen Mirror gedacht. Die, die entspannt sind, sind die mit selbst-gehostetem Git irgendwo. Davon gibt es nicht viele.
Du bekommst keine Warnung, bevor dir das passiert.
Was GitHub Dir Tatsächlich Verspricht (Es Ist Weniger Als Du Denkst)
GitHub verspricht nicht, deine Repos zu behalten. Sie versprechen, eine Plattform zu betreiben.
Lies die Nutzungsbedingungen nüchtern (ist mühsam, mach es einmal). Die relevanten Klauseln sind nicht versteckt. GitHub kann Accounts nach eigenem Ermessen sperren oder kündigen. Deine Inhalte können entfernt werden, wenn sie gegen Richtlinien verstoßen, einschließlich Richtlinien, die nicht existierten, als du den Account erstellt hast. Und deine Verpflichtung als Nutzer ist es, eigene Kopien von allem zu führen, was du dir nicht leisten kannst zu verlieren.
Dafür gibt es sogar einen Namen. Die Cloud-Industrie nutzt ihn seit über einem Jahrzehnt und jeder große Anbieter hat eine Seite dazu: das Shared Responsibility Model. Der Anbieter betreibt die Plattform. Der Kunde besitzt die Daten. GitHub schreibt es nicht auf die Homepage, weil sich niemand anmelden würde, wenn da stünde "deine Daten sind dein Problem", aber der Vertrag ist derselbe.
Der Fehler, den fast alle machen, ist einer der Kategorie. Wir behandeln GitHub wie ein Dateisystem. Es sieht so aus (Ordner, Dateien, Historie). Es fühlt sich so an (immer da, immer synchron). Aber es ist ein verwalteter Service mit AGB, und verwaltete Services haben einen Ausgang, der vom Anbieter bedient wird.
Ich argumentiere nicht gegen den Vertrag. Ich lese ihn nur. Wenn du ihn einmal gelesen hast, kannst du es nicht mehr ungeschehen machen.
Ich Warte Nicht auf Vorfälle. Das Ist ein Design-Prinzip.
Ich habe eine Regel für jeden Third-Party, von dem ich abhänge: wenn ihn zu verlieren wehtun würde, bekommt er eine lokale Kopie. Nicht weil ich erwarte, dass der Anbieter versagt. Weil die Kosten, damit falsch zu liegen, zu hoch sind.
Das ist Standard-Infra-Hygiene, keine Paranoia. Du diskutierst nicht mit dem DBA darüber, ob die Primary "vielleicht" ausfallen könnte. Du richtest die Replica ein, weil so baust du Infra, die einen Dienstag überlebt.
Dasselbe Prinzip ist der Grund, warum ich mein gesamtes AI-Agent-Setup in der Woche umgebaut habe, als Anthropic mein $200/Monat OpenClaw-Setup killete und mich zwang, es für $15 neu zu bauen. Ich habe nicht gewartet, bis mich die Ankündigung ein zweites Mal beißt. In dem Moment, wo ein Vendor einseitig die Regeln ändert, ist die richtige Reaktion nicht zu verhandeln. Es ist, die nächste Version zu besitzen.
Security-Leute nennen das Security by Design. Die Entscheidungen, die du zur Architektur-Zeit triffst, sind Entscheidungen, die du nicht unter Stress treffen musst. Du entwirfst keinen Notausgang während des Brandes. Du schreibst keine Backup-Strategie um 9 Uhr morgens, während du auf eine Sperrungsmail und einen kalt gewordenen Kaffee starrst.
Also hatte ich einen Mirror. Schon vorher. Aus einem Grund: mein Code ist das einzige Deliverable, das ich nicht neu erstellen kann. Server kann ich neu bauen. Configs kann ich neu schreiben. Sechs Jahre Commits in 39 privaten Repos, das kann ich nicht.
Der Mirror existiert, damit ich nie einen Sonntagabend-Blogpost mit dem Titel Wie Ich Mich Von Einer GitHub-Sperre Erholte schreiben muss.
Mein Setup: Forgejo Mirror Hinter einem NetBird Mesh

Zwei Teile. Das ist das ganze Setup.
Forgejo ist eine selbst-gehostete Git-Forge. Sie forkte 2022 von Gitea ab, als Gitea zu einer gewinnorientierten Unternehmensstruktur wechselte (ja, das ist die Art von Detail, die wichtig wird, sobald du dich dafür interessierst, wer deine Tools besitzt). Es läuft in einem einzigen Container mit SQLite. Kein PostgreSQL-Cluster, kein Redis, keine Microservices. Es spricht das Git-Protokoll nativ, keine Web-Layer-Abstraktion. Wenn du ein Repo von Forgejo klonst, würdest du nicht merken, dass du nicht auf GitHub bist. Dieselbe Logik, für die ich in warum CLIs MCP für AI-Agenten schlagen argumentiert habe: das Primitiv schlägt den Wrapper, jedes Mal.
NetBird ist ein WireGuard-basiertes Mesh. Mein Laptop, mein VPS und ein paar andere Geräte sind in einem privaten Netzwerk mit privaten IPs. Keine öffentliche Exposition. Kein Reverse Proxy. Kein TLS-Zertifikat zum Erneuern. Wenn du nicht im Mesh bist, antwortet der Port nicht mal.
Der Forgejo-Container sieht so aus:
services:
forgejo:
image: codeberg.org/forgejo/forgejo:11
container_name: forgejo
restart: unless-stopped
ports:
- "100.69.51.147:3000:3000"
volumes:
- forgejo_data:/data
environment:
- FORGEJO__server__ROOT_URL=http://forgejo.mesh:3000
- FORGEJO__server__DISABLE_SSH=true
- FORGEJO__service__DISABLE_REGISTRATION=true
- FORGEJO__mirror__DEFAULT_INTERVAL=8h
Vier Entscheidungen hervorzuheben:
Der Port bindet nur an die Mesh-IP (100.69.51.147). Nicht 0.0.0.0. Nicht dem öffentlichen Internet ausgesetzt. Der Mirror ist eine private Ressource, die hinter demselben Zaun lebt wie meine anderen internen Services.
SSH ist deaktiviert. Ich pushe nie zum Mirror. Er ist read-only. SSH zu deaktivieren entfernt eine ganze Angriffsfläche, die ich nicht brauche.
Registrierung ist deaktiviert. Single-User-Instanz. Kein Anmeldeformular für irgendeinen Bot, den er an einem Dienstag findet.
Das Mirror-Sync-Intervall ist 8 Stunden. Forgejo hat nativen Pull-Mirror-Support: du gibst ihm eine GitHub-URL und ein PAT, und es pullt alle 8 Stunden für immer. Kein Cron, kein Script, kein Webhook. Die Forge macht es selbst.
Dann registriert ein kleines Script alle meine GitHub-Repos als Mirrors über die Forgejo-API. Es ist idempotent: es listet die Repos auf, prüft, welche bereits einen Mirror haben, und erstellt nur die fehlenden. Einmal bei der Installation ausführen. Wieder ausführen, jedes Mal wenn du ein neues GitHub-Repo erstellst. Oder wöchentlich planen, deine Entscheidung. Der einzelne API-Call pro Repo sieht so aus:
curl -X POST "$FORGEJO_URL/api/v1/repos/migrate" \
-H "Authorization: token $FORGEJO_TOKEN" \
-d '{
"clone_addr": "https://github.com/myorg/repo.git",
"repo_name": "repo",
"mirror": true,
"private": true,
"auth_token": "'$GITHUB_PAT'",
"service": "github"
}'
Das in eine Schleife über gh repo list myorg packen, mit einer Prüfung ob der Mirror bereits existiert, und du bist fertig. Das PAT und der Forgejo-Token kommen zur Laufzeit aus einem selbst-gehosteten Secrets-Manager, nie auf die Festplatte.
Gesamter Ressourcen-Footprint: etwa 100MB RAM, 2GB Festplatte für 39 Repos. Der Container startet in zwei Sekunden neu. Das 8h-Sync läuft im Hintergrund und ich vergesse wochenlang, dass es existiert.
Was Das Abdeckt, und Was Nicht
Das ist der Teil, den die meisten "hoste dein Git selbst"-Artikel überspringen. Ein Pull-Mirror ist kein vollständiges GitHub-Backup.
Was der Mirror rettet ist die Git-Seite der Dinge: jeder Commit, jeder Branch, jeder Tag, vollständige Historie über alle Branches. Submodules und LFS funktionieren auch, wenn du den extra Schritt machst, sie zu konfigurieren, und das solltest du, wenn du sie nutzt.
Was der Mirror NICHT rettet ist alles, was außerhalb des Git-Protokolls lebt. Issues. Pull Requests und Review-Kommentare. Wiki-Seiten. Actions-Run-Logs (die YAML-Dateien ja, die Run-Historie nein). Repo-Einstellungen, Webhooks, Deploy-Keys, Collaborator-Zugriffslisten. All das sind GitHub-spezifische Metadaten, gespeichert in ihrer Datenbank, nicht in deinem .git-Verzeichnis. Wenn GitHub morgen verschwindet, sind meine 39 Repos intakt, bis zu 8 Stunden veraltet. Meine Issues und PRs sind es nicht.
Für meinen Use Case (private Repos, meist Solo-Arbeit, Infrastruktur-Code) ist das ein akzeptabler Trade. Für ein größeres Team, das die Hälfte ihres Workflows in GitHub Issues abwickelt, ist die Unterhaltung anders. Du würdest das offizielle GitHub-Repo-Backup-Tool wollen, oder einen Third-Party, der die API für Issues und PRs zusätzlich zum Git-Mirror anspricht.
Da ist auch der Fall, dass ich versehentlich ein Repo auf GitHub lösche. Der Pull-Mirror bemerkt, dass der Upstream weg ist, aber Forgejo löscht die lokale Kopie nicht automatisch. Der letzte synchronisierte Zustand bleibt. Das ist tatsächlich ein Feature: eine destruktive Aktion upstream propagiert nicht. (Ich werde nicht behaupten, dass ich das absichtlich so designed habe. Ich bemerkte es das erste Mal, als ich eine alte Org aufräumte und den Mirror einen Monat später immer noch da sitzen sah. Kostenloses Sicherheitsnetz, behalten.)
Wisse, was dein Filter macht und was nicht. Verkauf dir keine Backup-Story, die nicht zum Vertrag passt, den du tatsächlich mit deinen Tools hast.
Du Musst Nicht auf Deinen Eigenen Vorfall Warten
Die 104-Repos-Geschichte ist nicht außergewöhnlich. Sie ist nur sichtbar. Dasselbe passiert jede Woche Leuten, deren Publikum zu klein ist, damit der Post reist. Account-Sperren, falsche DMCA-Takedowns, Billing-Disputes, Klassifizierer-False-Positives, Zahlungsmethode abgelaufen in einem Land, das GitHubs Billing-System komisch handhabt. Die Liste ist lang. Der Fix ist in jedem Fall derselbe.
In sechs Monaten wird GitHub einen Blogpost zu "Verbesserung unserer Kommunikation von Account-Aktionen" veröffentlichen. Es wird ein neues Dashboard geben, eine aufgefrischte FAQ, eine hübschere Status-Seite. Niemand wird es vor der nächsten Welle lesen.
Währenddessen werden die Devs, die shippen, weiter shippen. Mit einem Mirror. Auf ihrer eigenen Infra. Erreichbar wenn GitHub down ist, wenn ein Klassifizierer daneben liegt, wenn ein 2019er Student Pack plötzlich ein 2026er Problem wird. Nicht viel. Nur ein docker-compose und drei Stunden Config an einem Sonntag.
Git ist von Design aus verteilt. Wir sind die, die beschlossen haben, das zu vergessen.
Quellen
- Forgejo-Dokumentation: https://forgejo.org/docs/latest/
- NetBird (WireGuard-Mesh): https://netbird.io/
- AWS Shared Responsibility Model (das ursprüngliche Framing von wer was besitzt): https://aws.amazon.com/compliance/shared-responsibility-model/
(*) Das Cover ist AI-generiert. Keine echten GitHub-Repos wurden bei der Erstellung dieses Bildes verletzt.