Eine Git-Plattform in einer einzigen Rust-Binary.

Repositories, Merge Requests mit Inline-Review, Tickets, Wikis, Releases, signierte Webhooks und eine CI/CD-Engine. Ein Prozess, ein PostgreSQL, auf deinem eigenen Server.

FerrisGit öffnen
$docker compose up -d --build

Eine einzige Binary und eine Datenbank. Kein Konto bei einem Drittanbieter, keine Telemetrie an irgendjemanden. Sieh dir an, wie es gebaut ist.

Darstellung eines Merge Requests in FerrisGit, vom Push bis zum Merge: ein Push über HTTPS erzeugt den Request, eine Reviewerin schlägt eine Änderung an einer Zeile vor, der Autor übernimmt sie mit einem Klick, die Reviewerin gibt frei, der Request wird gemergt. Der Merge startet die Pipeline des Repositorys: format und clippy laufen, dann test, und alle drei sind erfolgreich.

In Zahlen

1
Rust-Binary liefert die REST-API, Git über HTTP und die Weboberfläche
1
PostgreSQL 18 hält jeden Datensatz; die Repositories liegen auf der Festplatte
5
Cargo-Crates, hexagonal aufgebaut
173
REST-Routen unter /api, jede dokumentiert
3
Anmeldefaktoren (TOTP, Passkeys, Wiederherstellungscodes); MFA ist Pflicht
2
Job-Engines: Docker-Runner oder Kubernetes-Pods

Was du bekommst, wie die Oberfläche es zeigt

Jede Kachel ist ein Stück des echten Produkts. Die Oberfläche ist vorerst auf Französisch; fünf Sprachen sind für 0.2 geplant.

src/webhooks/dispatch.rs:48 Offen

CA

camille · 2 min

Exponentielles Backoff, damit ein flatternder Endpunkt nicht länger bombardiert wird.

Vorgeschlagene Änderung

Review direkt am Diff

Ein Kommentar bleibt an seiner Zeile. Wer reviewt, kann einen Vorschlag schreiben, den der Autor mit einem Klick als Commit übernimmt. Freigaben werden gezählt, Konflikte erkannt.

Eine Pipeline bei jedem Push

Nach jedem Push liest FerrisGit die Datei auf dem Standard-Branch und erstellt eine Pipeline. Stages sind Barrieren, needs sind Abhängigkeiten; Jobs laufen in Docker-Containern über einen kleinen Runner oder als Kubernetes-Pods.

Tickets, als Liste oder Board

Labels, Meilensteine, Zuständige und vier Zustände. Ziehe eine Karte, um ihren Zustand zu ändern, oder nutze das Kartenmenü per Tastatur.

Aktion Leser Mitw. Maint.
Stöbern, klonen, lesen
Pushen, Tickets und Requests öffnen, reviewen
Mergen, Releases, Einstellungen, Mitwirkende

Drei Rollen, pro Repository oder pro Gruppe

Eine Rolle auf einer Gruppe gilt für alles darunter. Die höchste Rolle gewinnt.

Signierte Webhooks

Zwölf Ereignisse zu Merge Requests, Tickets, Pipelines und Mitwirkenden. Jede Zustellung trägt eine HMAC-SHA256-Signatur ihres rohen Bodys; das Secret ist verschlüsselt gespeichert.

Öffentliche Seiten, ohne Konto

Besucher stöbern in Katalog, README, Dateien, Commits und Releases öffentlicher Repositories und klonen sie. Ein Admin-Schalter schaltet die öffentlichen Seiten ab.

Mehr-Faktor-Anmeldung, für alle

Kein Konto kommt daran vorbei. Authenticator-Apps (TOTP), Passkeys (WebAuthn) und zehn einmalige Wiederherstellungscodes.

Die vollständige Funktionsliste

Aus einem Push wird eine Pipeline

Beschreibe die Jobs in .ferrisgit-ci.yml im Wurzelverzeichnis des Repositorys. Nach jedem erfolgreichen Push liest FerrisGit die Datei auf dem Standard-Branch und erstellt eine Pipeline. Lege den Schalter um, um zu sehen, was der Scheduler tut, wenn ein Job fehlschlägt.

.ferrisgit-ci.yml
stages: [lint, test]

jobs:
  format:
    stage: lint
    image: rust:1
    script:
      - rustup component add rustfmt
      - cargo fmt --all -- --check

  clippy:
    stage: lint
    image: rust:1
    script:
      - rustup component add clippy
      - cargo clippy --all-targets -- -D warnings

  test:
    stage: test
    image: rust:1
    needs: [format, clippy]
    script:
      - cargo test --all-targets

Pipeline bestanden

lint

formaterfolgreich
clippyerfolgreich

test

testerfolgreich

format und clippy starten gemeinsam; test deklariert needs: [format, clippy] und startet, sobald beide erfolgreich waren.

Zwei Wege, einen Job auszuführen
Docker-Runner: eine kleine Binary ferrisgit-runner fragt den Server ab und führt jeden Job in einem Container aus. Oder Kubernetes: der Server erzeugt pro Job einen Pod in deinem Cluster.
Fehler werden gezeigt
Eine vorhandene, aber ungültige Datei erzeugt eine fehlgeschlagene Pipeline mit der Meldung des Parsers, sichtbar in der Oberfläche.
Variablen und Caches
CI-Variablen pro Repository, mit AES-256-GCM verschlüsselt gespeichert (Docker-Runner). Caches pro Job mit Kubernetes.

Die Referenz zu .ferrisgit-ci.yml (auf Französisch)

Zwei Minuten bis zum Self-Hosting

FerrisGit ist ein Container-Image mit PostgreSQL daneben. Probiere es mit Docker Compose, installiere das Helm-Chart auf Kubernetes oder starte es aus dem Quellcode.

Docker Compose

Den Stack mit Docker Compose starten
git clone https://github.com/Masmarino/FerrisGit.git
cd FerrisGit
cp .env.example .env
# set POSTGRES_PASSWORD, JWT_SECRET, SETTINGS_ENCRYPTION_KEY and the admin password in .env
docker compose up -d --build

Compose baut das Image aus dem Quellcode. Um stattdessen das veröffentlichte Image zu verwenden, ersetze build: . durch image: masmarino/ferrisgit:0.1.1 in docker-compose.yml.

Installationsanleitung (auf Französisch)

Helm-Chart

Das Chart auf Kubernetes installieren
git clone https://github.com/Masmarino/FerrisGit.git
cd FerrisGit
helm upgrade --install ferrisgit ./helm/ferrisgit \
  --namespace ferrisgit --create-namespace \
  --set image.tag=0.1.1 \
  --set ingress.host=git.example.com \
  --set-string ferrisgit.trustedProxyCidrs=10.42.0.0/16
kubectl -n ferrisgit rollout status deployment/ferrisgit

Bleiben sie leer, erzeugt das Chart das Datenbankpasswort, JWT_SECRET, SETTINGS_ENCRYPTION_KEY und das Passwort des ersten Administrators im Secret ferrisgit-secrets. Das Release muss ferrisgit heißen.

Deployment auf Kubernetes (auf Französisch)

Aus dem Quellcode

Backend und Webanwendung lokal starten
git clone https://github.com/Masmarino/FerrisGit.git
cd FerrisGit
cp .env.example .env          # then set real secrets
./scripts/dev.sh              # PostgreSQL via Compose, cargo run on :8080, ng serve on :4201

Benötigt rustup, Node.js 26, Docker mit Compose und git im PATH. Das Skript startet PostgreSQL, wendet die Migrationen an und startet das Backend auf Port 8080 und den Angular-Entwicklungsserver auf Port 4201.

Installationsanleitung (auf Französisch)

Wie es gebaut ist

Ein Prozess, fünf Crates, eine hexagonale Architektur: die Domäne weiß nichts von der Datenbank, die Adapter wissen nichts von den Anwendungsfällen.

Architektur einer FerrisGit-InstanzIsometrische Zeichnung. Ein Git-Client und ein Browser sprechen mit einer einzigen Rust-Binary, ferrisgit-api, bestehend aus den Crates api, application, domain und infrastructure. Die Binary legt ihre Daten in PostgreSQL und in Git-Repositories auf der Festplatte ab und führt Pipeline-Jobs entweder über einen ferrisgit-runner auf einem Docker-Host oder als Pods in einem Kubernetes-Cluster aus. Eine orange Linie folgt einem Push bis zu seinen Jobs. Sieben nummerierte Kreise führen zu den Kacheln der Seite.api application domain infrastructure ferrisgit-runner ferrisgit-api: eine einzige Binary ferrisgit-runner Git-Client HTTPS, Benutzername + Token noch kein SSH Browser angemeldet oder anonym auf öffentlichen Seiten api REST-API, Git über HTTP, Weboberfläche domain Entitäten und Ports, ohne I/O application Anwendungsfälle infrastructure Adapter: PostgreSQL, git, Docker, Kubernetes, SMTP, Webhooks PostgreSQL Konten, Issues, Pipelines; Migrationen laufen beim Start Git-Repositories auf Platte, inkl. Wikis Docker-Host der Runner fragt standard- mäßig alle 5 s ab, ein Job nach dem anderen, im Container Kubernetes-Cluster ein Pod pro Job, vom Server erzeugt git push Pipeline angelegt Jobs fragt Jobs ab

Abb. 1 Eine Instanz. Die orange Linie folgt einem Push vom Client bis zu den Jobs, die er auslöst.

  • Anfrage oder Speicherung
  • ein Push, bis zu seinen Jobs
  • der Runner fragt ab
  • eine nummerierte Kachel dieser Seite
  1. ferrisgit-domainEntitäten, Wertobjekte und die Ports, von denen der Rest abhängt. Keine Ein-/Ausgabe.
  2. ferrisgit-applicationDie Anwendungsfälle. Hängt nur von der Domäne ab, getestet gegen In-Memory-Attrappen.
  3. ferrisgit-infrastructureAdapter: PostgreSQL (sqlx), Git (gix und die git-Binary), SMTP, Kubernetes, Argon2, AES-GCM, JWT.
  4. ferrisgit-apiDer axum-Server: REST-API unter /api, Git Smart HTTP, das Angular-Bundle. Das ist die Binary.
  5. ferrisgit-runnerDer eigenständige Docker-Job-Runner.

Der Quellcode auf GitHub

Sicherheit und deine Daten

Was eine Instanz schützt, genau benannt. Die Daten verlassen deinen Server nie.

Mehr-Faktor-Authentifizierung ist Pflicht
Ein Konto ohne eingerichteten Faktor muss die Einrichtung durchlaufen, bevor es irgendetwas anderes tun kann. TOTP, Passkeys und Wiederherstellungscodes.
Passwörter mit Argon2 gehasht
Ein Salt pro Passwort. Ein unbekannter Benutzername kostet so viel Rechenzeit wie ein falsches Passwort und bekommt dieselbe Antwort.
Secrets mit AES-256-GCM verschlüsselt
CI-Variablen, Webhook-Secrets, das SMTP-Passwort und TOTP-Secrets, unter SETTINGS_ENCRYPTION_KEY.
Tokens für Git, nie Passwörter
Git über HTTPS authentifiziert sich mit einem persönlichen Zugriffstoken, gehasht gespeichert: der Server kann es nicht zurücklesen.
Ein Audit-Log
Fehlgeschlagene Anmeldungen, verweigerte Git-Zugriffe, Passwort-Resets, Beförderungen und MFA-Resets durch einen Administrator werden als Ereignisse aufgezeichnet.
Keine Cookies, strikte Header
Sitzungen sind JWTs. Jede Antwort trägt eine Content-Security-Policy, X-Frame-Options: DENY, und die Anmelderouten sind pro IP ratenbegrenzt.
Deine Daten, auf deinem Server
PostgreSQL und ein Verzeichnis mit Repositories, beide von dir zu sichern. Das Image läuft als unprivilegierter Benutzer auf einem schreibgeschützten Dateisystem.

Die Sicherheitsseite der Dokumentation (auf Französisch)

Wohin es geht

Fünf Versionen, keine ausgeliefert. Ein Punkt wird erst abgehakt, wenn er ausgeliefert ist.

  1. 0.2Geschützte Branches, Checks, fünf SprachenGeplant
  2. 0.3Eine Analyse-Engine: Secrets und AbhängigkeitenGeplant
  3. 0.4Quality Gates und DashboardGeplant
  4. 0.5Codequalität: Metriken, Regeln, AbdeckungGeplant
  5. 0.6Sicherheitsanalyse und ArtiFerrisGeplant

Ausprobieren, dann selbst betreiben.

Die öffentliche Instanz zeigt das Produkt. Deine Instanz behält deinen Code.