SSD Nodes Learn 🎉 VPS ab $5.50/Monat
Anleitungen Matt ConnorVon Matt Connor

Self-hosted Git: Forgejo, Gitea oder cgit?

Vier Varianten im RAM-Vergleich: Bare-Repositories über SSH, cgit, Forgejo oder Gitea und GitLab. Erfahren Sie, was ein VPS mit 1 GB RAM schafft.

Welchen selbst gehosteten Git-Server sollten Sie betreiben

Ein selbst gehosteter Git-Server ist kein einzelnes Produkt. Der RAM (Arbeitsspeicher) Ihres VPS bestimmt, welche Variante Sie betreiben können. Git benötigt keinen eigenen Daemon: Ein Bare-Repository plus ein SSH-(Secure-Shell-)Konto ist auf dem kleinsten mietbaren Server bereits ein funktionierender Server. Alles darüber hinaus ist eine Webanwendung, die Sie zusätzlich betreiben. Jeder weitere Schritt benötigt Arbeitsspeicher, den ein kleiner VPS möglicherweise nicht bereitstellt.

Es gibt vier Stufen. Ein Bare-Repository über SSH, ohne dass ein Dienst auf einem zusätzlichen Port lauscht. cgit, eine schnelle schreibgeschützte Webansicht ohne Datenbank. Forgejo oder Gitea, eine vollständige Forge mit Konten, Issues und Pull Requests in wenigen hundert Megabytes. GitLab, das einen Server erwartet, der ein Vielfaches der Größe der anderen Varianten hat.

Entscheiden Sie anhand der Aufgaben, die Sie erledigen müssen. Vergleichen Sie anschließend den Speicherbedarf mit dem Tarif, den Sie bezahlen.

Wie viel RAM die einzelnen Optionen tatsächlich benötigen

Nur zwei dieser Projekte veröffentlichen eine konkrete Hardwareangabe. Betrachten Sie eine veröffentlichte Angabe als Mindestwert, nicht als Garantie. Messen Sie die tatsächliche Belegung Ihrer eigenen Instanz nach dem Start mit systemd-cgtop oder ps -o rss= -C forgejo.

ChartRAM the projects document, official docs, August 2026
The data behind this chart
[
  {
    "label": "Gitea, small team",
    "ram_gb": 1
  },
  {
    "label": "GitLab, memory constrained",
    "ram_gb": 8
  },
  {
    "label": "GitLab, single node baseline",
    "ram_gb": 16
  }
]

Gitea gibt 1 GB RAM mit 2 CPU-Kernen als normalerweise ausreichend für kleine Teams und Projekte an. Außerdem wird ein Raspberry Pi 3 als ausreichend für kleine Workloads genannt. GitLab dokumentiert 16 GB als Basiswert für eine Installation auf einem einzelnen Knoten und 8 GB als unteren Wert für eine Umgebung mit begrenztem Arbeitsspeicher, wie es auf der eigenen Seite genannt wird. Forgejo veröffentlicht überhaupt keine Hardwareanforderungen. Es ist ein Fork von Gitea und verhält sich entsprechend. Daher ist die Gitea-Angabe der beste veröffentlichte Richtwert, den Sie haben.

Was das auf einem 1-GB-VPS bedeutet: Bare Repositories und cgit passen problemlos, weil beide keinen dauerhaft laufenden Dienst benötigen. Forgejo oder Gitea starten und können ein kleines Team mit SQLite versorgen. Sie befinden sich damit jedoch genau am dokumentierten Mindestwert. Lassen Sie PostgreSQL und den CI-Runner (Continuous Integration) daher auf diesem System deaktiviert. Wenn die Weboberfläche ohne Fehlermeldung verschwindet, führen Sie sudo dmesg -T | grep -i oom aus und suchen Sie nach einer Zeile wie Out of memory: Killed process 1181 (forgejo). Das bedeutet, dass der Out-of-Memory-Killer des Kernels den Prozess beendet hat. GitLab auf einem System mit 1 GB RAM ist kein Tuning-Problem. Es wird nicht ausgeführt.

Tier 0: Ein Bare-Repository über SSH

Git verfügt über keinen Netzwerk-Daemon, den Sie starten müssen. git push führt git-receive-pack auf der Gegenseite als gewöhnlichen Unix-Prozess über SSH aus. Daher ist jedes Konto, das Sie mit einem Schlüssel erreichen können, bereits ein Git-Remote. Richten Sie ein Konto für die Repositories ein. Bewahren Sie die Repositories außerhalb des Home-Verzeichnisses auf, weil ein neues Home-Verzeichnis unter Ubuntu 24.04 den Modus 0750 hat und eine später hinzugefügte Webansicht darauf nicht zugreifen kann.

sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' \
  --group --disabled-password --home /home/git git
sudo install -d -m 0755 -o git -g git /srv/git
sudo -u git git init --bare /srv/git/project.git

--bare erstellt ein Repository ohne Arbeitskopie. Genau das hält ein Server. Das Pushen in ein Repository mit Arbeitskopie wird mit refusing to update checked out branch: refs/heads/main abgelehnt. Dies ist der häufigste Fehler auf dieser Stufe.

Geben Sie dem Konto nun einen Schlüssel und klonen Sie das Repository.

sudo -u git install -d -m 700 /home/git/.ssh
sudo -u git tee -a /home/git/.ssh/authorized_keys <<'EOF'
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexamplekeyhere alice@laptop
EOF
sudo -u git chmod 600 /home/git/.ssh/authorized_keys
git remote add origin git@vps.example.com:/srv/git/project.git
git push -u origin main

Ein erfolgreicher erster Push endet mit * [new branch] main -> main. Ein Push, der mit git@vps.example.com: Permission denied (publickey) endet, wurde nicht authentifiziert. Lesen Sie in diesem Fall das Server-Log mit sudo journalctl -u ssh -n 20. Eine Zeile mit Authentication refused: bad ownership or modes for file /home/git/.ssh/authorized_keys bedeutet, dass der Dateimodus falsch ist, weil sshd eine Schlüsseldatei ignoriert, die andere Benutzer beschreiben können.

Entfernen Sie anschließend die Shell des Kontos.

command -v git-shell | sudo tee -a /etc/shells
sudo chsh -s "$(command -v git-shell)" git

git-shell akzeptiert nur die wenigen Befehle, die Git über SSH sendet. Eine interaktive Anmeldung endet daher jetzt mit einer Meldung statt mit einer Eingabeaufforderung:

fatal: Interactive git shell is not enabled.
hint: ~/git-shell-commands should exist and have read and execute access.

Das ist der gesamte Server. Es gibt keine Datenbank und keinen Webprozess, den Sie aktualisieren müssen. Sie verzichten damit auf alle Funktionen einer Forge: keine Anzeige der Repositories, keine Aufgabenverwaltung, keine Pull-Requests und keine benutzerbezogenen Berechtigungen. Jeder Schlüssel in dieser Datei kann jedes Repository lesen und beschreiben, das dem Benutzer git gehört.

Stufe 1: cgit stellt eine Webansicht ohne Datenbank bereit

cgit ist ein in C geschriebenes CGI-Programm (Common Gateway Interface). Der Webserver startet es für jede Anfrage, liest die Repositories direkt von der Festplatte und speichert keinen eigenen Zustand. Ubuntu 24.04 enthält es in der Komponente universe.

sudo apt update
sudo apt install -y cgit fcgiwrap nginx
sudo install -d -o www-data -g www-data /var/cache/cgit

Verweisen Sie es in /etc/cgitrc auf das Repository-Verzeichnis:

root-title=Git on example.com
css=/cgit.css
logo=/cgit.png
cache-size=1000
cache-root=/var/cache/cgit
snapshots=tar.gz zip
scan-path=/srv/git

scan-path durchsucht dieses Verzeichnis und listet jedes gefundene Repository auf. Ein neues Bare-Repository erscheint daher ohne zusätzliche Konfiguration. cache-size gibt die Anzahl der zwischengespeicherten Seiten an. Bei dem Wert null bleibt das Caching deaktiviert. Lesen Sie den Inhalt von /etc/cgitrc, den Ihr Paket bereits installiert hat, bevor Sie Zeilen hinzufügen. Die Debian- und Ubuntu-Pakete bringen eigene Standardwerte mit.

Jeder Eintrag zeigt die erste Zeile der Datei description des Repositorys. Ein neues Bare-Repository wird daher als Unnamed repository; edit this file 'description' to name the repository. angezeigt. Korrigieren Sie das einmal pro Repository:

echo 'Project X, internal tooling' | sudo -u git tee /srv/git/project.git/description
Die nginx-Sitedatei und ihre Prüfung
server {
    listen 80;
    server_name git.example.com;
    root /usr/share/cgit;

    try_files $uri @cgit;

    location @cgit {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi;
        fastcgi_param PATH_INFO $uri;
        fastcgi_param QUERY_STRING $args;
        fastcgi_param HTTP_HOST $server_name;
        fastcgi_pass unix:/run/fcgiwrap.socket;
    }
}
sudo systemctl enable --now fcgiwrap.socket
sudo nginx -t && sudo systemctl reload nginx
systemctl show fcgiwrap.socket -p Listen

root /usr/share/cgit stellt cgit.css und cgit.png als normale Dateien bereit. try_files leitet alle übrigen Anfragen an das CGI unter /usr/lib/cgit/cgit.cgi weiter. Eine 502-Seite mit connect() to unix:/run/fcgiwrap.socket failed (2: No such file or directory) in /var/log/nginx/error.log bedeutet, dass die Socket-Unit nicht läuft oder an einem anderen Pfad lauscht. Die Zeile systemctl show gibt den tatsächlich verwendeten Pfad aus.

Vor der weiteren Konfiguration sollten Sie zwei Einschränkungen kennen. cgit ist schreibgeschützt und bietet keine Anmeldung. Alles unter scan-path ist daher öffentlich. Halten Sie ein privates Repository aus diesem Verzeichnis heraus oder schalten Sie eine HTTP-Basisauthentifizierung vor die gesamte Site. Das CGI läuft außerdem unter dem Benutzer des Webservers. Dieser Benutzer muss /srv/git durchlaufen und jedes Repository lesen können. Ein Verzeichnis, das er nicht betreten kann, erscheint im Index als leer und nicht als Fehler.

Stufe 2: Forgejo oder Gitea für Issues und Pull Requests

Forgejo und Gitea verfolgen dasselbe Konzept: eine einzelne Go-Binärdatei, die eine Webforge mit Benutzern, Organisationen, Issues, Pull Requests, Releases, einer Paketregistrierung und einem integrierten CI-System bereitstellt. Für die Installation benötigen Sie nur die Binärdatei und SQLite. Deshalb laufen sie auch auf Hardware, auf der GitLab nicht sinnvoll eingesetzt werden kann. Die folgende Compose-Datei stammt aus der Forgejo-Dokumentation. Der verwendete Image-Tag entspricht dem dort im August 2026 angegebenen Stand.

networks:
  forgejo:
    external: false

services:
  server:
    image: codeberg.org/forgejo/forgejo:16
    container_name: forgejo
    environment:
      - USER_UID=1000
      - USER_GID=1000
    restart: always
    networks:
      - forgejo
    volumes:
      - ./forgejo:/data
      - /etc/localtime:/etc/localtime:ro
    ports:
      - '3000:3000'
      - '222:22'
docker compose up -d
docker compose ps
curl -sI http://127.0.0.1:3000 | head -1

Die Zeile curl sollte eine HTTP-Statuszeile ausgeben. Vor Abschluss der Ersteinrichtung kann es sich dabei um eine Weiterleitung zu /install handeln. Das bedeutet trotzdem, dass der Dienst läuft. Wenn der Container stattdessen beendet wird, ist die häufigste Ursache die Eigentümerschaft: Das Verzeichnis ./forgejo muss dem Benutzer mit der UID (Benutzer-ID) aus USER_UID gehören. Andernfalls kann der Prozess nicht in sein eigenes Datenverzeichnis schreiben. Docker Compose auf einem VPS beschreibt diesen Datei-Aufbau und die Regel für die Eigentümerschaft der Volumes vollständig.

Zwei Angaben auf der Einrichtungsseite bestimmen, ob Clone-URLs funktionieren. Der SSH-Port muss 222 lauten, weil die Compose-Datei den Host-Port 222 auf den Container-Port 22 abbildet. Außerdem muss die Domain dem Namen entsprechen, den die Benutzer tatsächlich eingeben. Ist eine der beiden Angaben falsch, zeigt jede Repository-Seite einen Clone-Befehl an, der für alle Benutzer fehlschlägt, die ihn kopieren. Beide Angaben befinden sich anschließend im Abschnitt [server] von app.ini, und zwar als SSH_PORT, SSH_DOMAIN und ROOT_URL.

Veröffentlichen Sie bei einer öffentlichen Instanz den Web-Port nur an der Loopback-Adresse ('127.0.0.1:3000:3000'), und schalten Sie für TLS (Transport Layer Security) nginx davor. Gitea lässt sich auf dieselbe Weise aus dem Image gitea/gitea installieren. Alternativ können Sie es als einzelne Binärdatei mit einer systemd-Unit und einem app.ini betreiben. Die aktuelle stabile Version ist im August 2026 1.27.1.

Verwenden Sie SQLite, solange dies möglich ist. Die Instanz benötigt dann nur einen Prozess und eine Datei. Nach einem Reboot läuft sie ohne zusätzlichen zu überwachenden Dienst weiter. PostgreSQL lohnt sich, wenn mehrere Personen gleichzeitig schreiben. SQLite serialisiert Schreibvorgänge, und lange CI-Läufe führen ständig zu Schreibvorgängen. Beide Projekte können eine vorhandene Instanz später zu PostgreSQL migrieren. Sie sind daher nicht dauerhaft an diese Entscheidung gebunden.

Forgejo oder Gitea: Was unterscheidet sie tatsächlich?

Die gemeinsame Herkunft bleibt bestehen. Gitea wurde 2016 von Gogs geforkt. Ende 2022 gingen die Kontrolle über die Gitea-Domain und die Marke an ein Unternehmen, Gitea Ltd, über. Mehrere Maintainer starteten daraufhin gemeinsam mit Codeberg Forgejo. Forgejo wird von Codeberg e.V. veröffentlicht, einem in Deutschland eingetragenen gemeinnützigen Verein. 2024 wechselte das Projekt von der MIT-Lizenz zu GPLv3 (GNU General Public License Version 3). Gitea bleibt unter der MIT-Lizenz und wird mit kommerzieller Unterstützung entwickelt.

Im täglichen Betrieb sind die Funktionsumfänge ähnlich. Der Migrationspfad zwischen beiden Projekten ist es nicht. Forgejo v10.0 vom Januar 2025 war die letzte Version, die eine Gitea-Datenbank direkt übernehmen konnte, und zwar nur ab Gitea v1.22 oder älter. Gitea steht im August 2026 bei 1.27.1. Daher gibt es für eine aktuelle Gitea-Instanz keinen unterstützten direkten Wechsel zu Forgejo. Entscheiden Sie sich, bevor Sie Daten einpflegen. Behandeln Sie einen späteren Wechsel als Export und anschließenden Re-Import.

Eine kurze Entscheidungshilfe: Wenn Ihnen die Governance wichtig ist oder das Projekt bei einem gemeinnützigen Träger bleiben soll, betreiben Sie Forgejo. Wenn Sie die größere Installationsbasis und eine kommerzielle Supportoption bevorzugen, betreiben Sie Gitea. Beide Projekte werden offen entwickelt und veröffentlichen regelmäßig neue Versionen. Forgejo veröffentlicht alle drei Monate eine stabile Version und jedes Jahr eine LTS-Version (Long Term Support). Im August 2026 ist v16.0.2 aktuell; v15.0.6 ist die LTS-Version.

Tier 3: Die Kosten von GitLab, bevor es überhaupt etwas tut

GitLab CE gehört zu einer anderen Softwareklasse. Eine Instanz besteht aus mehreren zusammenarbeitenden Diensten: Puma für die Webanwendung, Sidekiq für Hintergrundaufgaben, PostgreSQL, Redis, Gitaly für den Repository-Zugriff und nginx als vorgeschalteter Server. Das Omnibus-Paket installiert diese Komponenten gemeinsam. Dadurch wird die Installation einfach, aber der erforderliche Mindestspeicher hoch.

Auf der Anforderungsseite von GitLab werden 16 GB RAM und 8 vCPU als Basis für eine Installation auf einem einzelnen Knoten dokumentiert. Für Umgebungen mit knappem Arbeitsspeicher werden dort 8 GB als untere Grenze genannt. Auf derselben Seite wird empfohlen, Swap zu deaktivieren, weil das Auslagern unter Last die Instanz stark beeinträchtigt. Dies sind die veröffentlichten Werte mit Stand August 2026. Sie sind im Laufe der Jahre gestiegen. Lesen Sie die Seite daher erneut, bevor Sie einen Server dimensionieren.

Für diesen Ressourcenbedarf erhalten Sie tatsächlich relevante Funktionen: eine Container-Registry, eine Paket-Registry, differenzierte Berechtigungen, Compliance- und Audit-Funktionen sowie eine CI-Lösung, die im großen Maßstab getestet wurde. Wenn niemand in Ihrem Team eine Funktion aus dieser Liste nennen kann, die in diesem Quartal benötigt wird, bezahlen Sie für einen größeren VPS, ohne dafür einen Nutzen zu erhalten.

Das SSH-Zugriffsmodell: ein Git-Benutzer und viele Schlüssel

Jede Stufe authentifiziert sich auf dieselbe Weise. Es gibt ein Unix-Konto namens git, und jeder öffentliche Schlüssel wird in ~/.ssh/authorized_keys dieses Kontos eingetragen. Der Schlüssel dient zur Authentifizierung. Die Autorisierung wird durch die Optionen festgelegt, die in derselben Zeile vor dem Schlüssel stehen.

Eine einfache Schlüsselzeile gewährt dem Inhaber alle Aktionen, die dieses Konto ausführen kann. Ein erzwungener Befehl beschränkt den Zugriff auf Git:

restrict,command="git-shell -c \"$SSH_ORIGINAL_COMMAND\"" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexamplekeyhere alice@laptop

restrict, seit OpenSSH 7.2 verfügbar, deaktiviert Portweiterleitung, Agent-Weiterleitung, X11 und die Zuweisung eines PTY (Pseudo-Terminals) mit einem einzigen Schlüsselwort. command= ersetzt die Anfrage des Clients durch den angegebenen Befehl. Git funktioniert weiterhin, weil Git seine Anfrage in $SSH_ORIGINAL_COMMAND sendet.

Eine Forge schreibt diese Datei für Sie. Das ist der wesentliche Unterschied zwischen Stufe 0 und Stufe 2. Forgejo und Gitea schreiben authorized_keys mit einer Zeile pro registriertem Schlüssel neu. Jede Zeile enthält einen erzwungenen Befehl, der den Schlüssel anhand seiner Datenbank-ID identifiziert:

command="/usr/local/bin/forgejo --config=/etc/forgejo/app.ini serv key-3",no-port-forwarding,no-x11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexamplekeyhere alice

Dieser erzwungene Befehl macht aus einem gemeinsamen Unix-Konto eine benutzerbezogene Berechtigungsprüfung: key-3 teilt der Forge mit, welcher Benutzer die Verbindung herstellt. Die Forge prüft diesen Benutzer gegen das Repository, bevor Objekte übertragen werden. Bearbeiten Sie diese Datei auf einem von einer Forge verwalteten System nicht manuell. Sie wird aus der Datenbank neu erzeugt, und Ihre Zeile verschwindet. Deploy Keys verwenden denselben Mechanismus. Ein Deploy Key ist ein gewöhnlicher SSH-Schlüssel, der für ein einzelnes Repository registriert ist. Er ist normalerweise schreibgeschützt. Die Prüfung erfolgt in der Forge und nicht in sshd.

Zwei Gewohnheiten sind wichtiger als alle oben genannten Konfigurationen. Verwenden Sie einen Schlüssel pro Person oder pro System und niemals einen gemeinsam genutzten Schlüssel. Beim Sperren eines gemeinsam genutzten Schlüssels müssten Sie ihn für alle gleichzeitig ersetzen. Entfernen Sie Schlüssel am Tag des Ausscheidens einer Person. Ein alter Schlüssel in dieser Datei ermöglicht dauerhaft eine Anmeldung, die niemand überwacht. Gute Verwaltung von SSH-Schlüsseln auf einem Server behandelt Schlüsseltypen und Passphrasen. Alle dort beschriebenen Regeln gelten hier unverändert. Wenn das System neu ist, sollten Sie vor dem Ablegen von Repositorys zunächst die ersten zehn Minuten auf einem neuen VPS durchführen.

Kann ich GitHub Actions auf meinem eigenen Git-Server ausführen?

Sie können Workflows ausführen, die in der GitHub-Actions-Syntax geschrieben sind. GitHub selbst können Sie nicht ausführen. Forgejo Actions ist seit Forgejo v1.21 standardmäßig aktiviert und liest Workflow-Dateien in jedem Repository aus .forgejo/workflows. Gitea Actions funktioniert auf dieselbe Weise und liest .gitea/workflows. Für beide benötigen Sie ein zweites Programm, den Runner. Sie müssen ihn installieren und mit einem Token aus den Administratoreinstellungen bei Ihrer Instanz registrieren. Viele veröffentlichte Actions laufen unverändert. Actions, die die GitHub API aufrufen oder eine von GitHub bereitgestellte Infrastruktur voraussetzen, funktionieren dagegen nicht.

Planen Sie zwei Konsequenzen ein. Der Runner startet für jeden Job einen Container. Deshalb benötigt er eine Container-Engine und ein eigenes Speicherbudget. Aus diesem Grund gehört er nicht auf denselben Rechner mit 1 GB wie die Forge. Außerdem führt der Runner alles aus, was in einer Workflow-Datei angegeben ist. In der Dokumentation von Forgejo steht das ausdrücklich: Der Runner führt Remote-Code-Ausführung durch. Verwenden Sie nach Möglichkeit einen eigenen Host. Mindestens sollten Sie einen eigenen Benutzer ohne privilegierte Rechte und ein Registrierungstoken verwenden, das auf ein Repository begrenzt ist.

Wenn Ihre Repositories bei GitHub bleiben und Sie die Ausführung nur auf Hardware verlagern möchten, die Sie kontrollieren, handelt es sich um eine andere Konfiguration mit anderen Schritten: ein selbst gehosteter GitHub-Actions-Runner wird mit einem GitHub-Repository verbunden und benötigt nichts davon. Wenn Sie noch abwägen, welche Kosten ein Wechsel verursacht, trennt was GitHub tatsächlich bietet das Git-Hosting vom Netzwerk darum herum.

Backups: Repositories enthalten nur die halbe Zustandsinformation

Ein Bare-Repository ist ein Verzeichnis. Beim Kopieren werden daher alle darin enthaltenen Daten kopiert. Ein Mirror-Klon von einem anderen Rechner ist ein echtes Backup und wird direkt am vorhandenen Ziel aktualisiert:

git clone --mirror git@vps.example.com:/srv/git/project.git
cd project.git && git remote update

Dabei werden alle Refs und alle Objekte abgerufen. Serverseitige Hooks und die Datei description werden nicht abgerufen. Wenn Sie Hooks verwenden, erstellen Sie daher zusätzlich eine Kopie des Verzeichnisses auf Dateiebene.

Eine Forge speichert Issues, Pull Requests, Benutzer, Schlüssel und Berechtigungen in ihrer Datenbank. Eine reine Kopie der Repositories verwirft all diese Daten. Beide Projekte stellen einen Dump-Befehl bereit. Dieser schreibt die Datenbank, die Repositories, die Konfiguration und die Anhänge in ein gemeinsames Archiv:

sudo -u git forgejo dump -c /etc/forgejo/app.ini -f /var/backups/forgejo-dump.zip

Unter Docker wird derselbe Befehl innerhalb des Containers ausgeführt. Der Konfigurationspfad hängt vom Image ab. Prüfen Sie ihn daher, bevor Sie den Befehl eingeben:

docker compose exec server ls /data/gitea/conf
docker compose exec -u git server forgejo dump -c /data/gitea/conf/app.ini

Führen Sie den Befehl als Benutzer aus, dem die Daten gehören. Schreiben Sie das Archiv in ein Verzeichnis, in das dieser Benutzer schreiben darf. Kopieren Sie das Archiv anschließend vom Server weg. Ein Backup, das nur auf dem gesicherten Rechner vorhanden ist, ist kein Backup. Das Wiederherstellen wird häufig übersprungen. Entpacken Sie jetzt einen Dump auf einem Ersatzrechner. So lernen Sie den Ablauf in Ruhe kennen und nicht erst während eines Ausfalls.

Nach Szenario auswählen

Eine Person mit einem Laptop und einem VPS, ohne Bedarf für das Browsen im Repository: Bare-Repositories über SSH. Es läuft kein zusätzlicher Dienst, und nichts muss aktualisiert werden.

Dasselbe, aber Sie möchten den Code im Browser lesen und Links darauf teilen: Fügen Sie cgit hinzu. Es gibt weiterhin keine Datenbank, und kein zusätzlicher Dienst läuft dauerhaft.

Ein Team, das den Code der anderen Teammitglieder prüft und Issues verfolgt: Forgejo oder Gitea auf einem System mit mindestens 2 GB RAM. Verschieben Sie den CI-Runner auf einen zweiten Rechner, sobald die Jobs umfangreicher werden.

Eine Organisation, die eine Container-Registry und Audit-Trails benötigt und dem Server 16 GB RAM zur Verfügung stellen kann: GitLab. Wenn dieses Budget nicht vorhanden ist, sollten Sie GitLab nicht einsetzen.

Der Wechsel in die ersten drei Stufen ist kostengünstig, weil die Repositories in allen drei Fällen gewöhnliche Git-Verzeichnisse auf der Festplatte sind. Beginnen Sie mit der niedrigsten Stufe, die Ihre Anforderungen erfüllt. Wenn Sie ermitteln, welche anderen Dienste auf demselben Server noch Speicher erhalten sollen, stellt die Übersicht der lohnenswerten Self-Hosting-Dienste einen Git-Server neben die anderen Diensten, die um diesen RAM konkurrieren.

FAQ

Kann ein 1-GB-VPS Forgejo oder Gitea ausführen?

Ja, für ein kleines Team mit SQLite, sofern auf dem System keine weiteren rechenintensiven Dienste laufen. Die Gitea-Dokumentation nennt 1 GB RAM und 2 CPU-Kerne als normalerweise ausreichend für kleine Teams und Projekte. Forgejo ist ein Fork von Gitea und hat ähnliche Anforderungen. Installieren Sie PostgreSQL oder einen CI-Runner nicht auf diesem System. Wenn der Dienst ohne Fehlermeldung im eigenen Log beendet wird, führen Sie sudo dmesg -T | grep -i oom aus: Eine Zeile mit dem Namen des beendeten Prozesses bedeutet, dass der Out-of-Memory-Killer des Kernels den Prozess beendet hat. Die Lösung ist dann ein größeres Paket und kein Tuning-Flag.

Was ist der Unterschied zwischen Forgejo und Gitea?

Beide haben eine gemeinsame Codebasis und bieten größtenteils dieselben Funktionen. Gitea wurde 2016 von Gogs geforkt. Forgejo wurde Ende 2022 von Gitea geforkt, nachdem die Kontrolle über die Marke Gitea auf ein Unternehmen übergegangen war. Forgejo wird von Codeberg e.V., einer gemeinnützigen Organisation in Deutschland, unter der GPLv3 veröffentlicht. Gitea bleibt unter der MIT-Lizenz und wird kommerziell unterstützt. Der praktische Unterschied betrifft den Migrationspfad. Forgejo v10.0 vom Januar 2025 war die letzte Version, die eine Gitea-Datenbank direkt übernehmen konnte, und zwar nur von Gitea v1.22 oder älter. Für eine aktuelle Gitea-Instanz gibt es daher keinen unterstützten direkten Wechsel.

Kann ich GitHub-Actions-Workflows auf einem selbst gehosteten Git-Server ausführen?

Forgejo Actions und Gitea Actions führen beide Workflows aus, die in der YAML-Syntax von GitHub Actions geschrieben sind und aus .forgejo/workflows und .gitea/workflows gelesen werden. Sie installieren ein separates Runner-Programm und registrieren es bei Ihrer Instanz. Viele veröffentlichte Actions funktionieren unverändert. Alles, was die GitHub-API aufruft, funktioniert jedoch nicht. Der Runner führt beliebigen Code aus Ihren Repositorys aus und startet für jeden Job einen Container. Geben Sie ihm daher einen eigenen Host oder zumindest einen eigenen Benutzer ohne privilegierte Rechte. Betreiben Sie ihn nicht auf einem 1-GB-Server, auf dem bereits die Forge-Instanz läuft.

Wie sichere ich einen selbst gehosteten Git-Server?

Bei Bare-Repositorys kopiert git clone --mirror von einem anderen System jeden Ref und jedes Objekt. git remote update innerhalb dieses Mirror-Repositorys aktualisiert es. Bei Forgejo oder Gitea sind die Repositorys nur ein Teil des Zustands, da Issues, Pull Requests, Benutzer und Schlüssel in der Datenbank gespeichert werden. Verwenden Sie den integrierten Dump mit sudo -u git forgejo dump -c /etc/forgejo/app.ini oder bei einer Docker-Installation denselben Befehl innerhalb des Containers. Kopieren Sie das Archiv vom Server weg. Stellen Sie es anschließend einmal auf einem Ersatzsystem wieder her, damit Sie wissen, dass das Verfahren funktioniert.

#git#self-hosting#forgejo#gitea#ssh