Ein eigener Git-Server ist schnell aufgesetzt und bringt mehr, als man denkt: Code, Tickets und Wiki liegen bei dir, private Repositorys sind nicht begrenzt, und automatische Abläufe (CI) laufen auf deiner eigenen Hardware. Forgejo ist dafür eine schlanke Wahl: eine einzelne Anwendung, wenig Speicherbedarf, eine Oberfläche, die jeder GitHub-Nutzer sofort versteht.
Forgejo oder Gitea?#
Forgejo ist 2022 als Abspaltung von Gitea entstanden, nachdem die Gitea-Markenrechte an ein Unternehmen gingen. Forgejo wird von einer gemeinnützigen Organisation getragen und betreibt unter anderem Codeberg. Beide sind sich im Alltag sehr ähnlich; die Konfiguration ist über weite Strecken dieselbe. MRMedia selbst betreibt Gitea, und das funktioniert gut. Für eine Neuinstallation spricht für Forgejo die Trägerschaft, für Gitea die längere Liste an Anleitungen im Netz. Die Schritte unten gelten mit kleinen Unterschieden für beide.
Aufbau mit Compose#
# /srv/forgejo/compose.yaml
services:
forgejo:
image: codeberg.org/forgejo/forgejo:<version>
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
- FORGEJO__database__DB_TYPE=postgres
- FORGEJO__database__HOST=db:5432
- FORGEJO__database__NAME=forgejo
- FORGEJO__database__USER=forgejo
- FORGEJO__database__PASSWD__FILE=/run/secrets/db_passwort
secrets: [db_passwort]
volumes:
- ./data:/data
ports:
- "127.0.0.1:3000:3000"
- "2222:22"
depends_on:
db:
condition: service_healthy
db:
image: postgres:17
restart: unless-stopped
environment:
- POSTGRES_USER=forgejo
- POSTGRES_DB=forgejo
- POSTGRES_PASSWORD_FILE=/run/secrets/db_passwort
secrets: [db_passwort]
volumes:
- ./postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U forgejo"]
interval: 10s
retries: 5
secrets:
db_passwort:
file: ./db_passwort.txt
Die Version nimmst du aus den Forgejo-Releases; Forgejo kennzeichnet einzelne Versionen als Langzeit-Version (LTS), die sich für einen Server eignen, den du nicht jeden Monat aktualisieren willst. Das Passwort liegt in einer Datei statt in der Compose-Datei, warum, steht in Passwörter in Containern.
cd /srv/forgejo
openssl rand -base64 32 > db_passwort.txt && chmod 600 db_passwort.txt
docker compose up -d
Die Weboberfläche bringt ein Reverse-Proxy mit TLS nach außen. Beim ersten Aufruf läuft ein Einrichtungsassistent; die meisten Werte sind durch die Umgebungsvariablen schon gesetzt. Dort legst du auch den Administrator an.
Git über SSH#
Port 22 gehört schon dem SSH-Dienst des Servers. Deshalb lauscht Forgejo im Beispiel auf Port 2222. Damit die Klon-Adressen in der Oberfläche stimmen:
# ./data/gitea/conf/app.ini, Abschnitt [server]
SSH_DOMAIN = git.example.com
SSH_PORT = 2222
ROOT_URL = https://git.example.com/
Deine Nutzer tragen den Port in ihre SSH-Konfiguration ein, dann sieht er für sie aus wie überall:
# ~/.ssh/config
Host git.example.com
Port 2222
Die Firewall muss 2222 durchlassen. Wer lieber keinen zweiten Port öffnet, klont über HTTPS mit einem Zugangstoken.
Die Einstellungen, die du sofort setzt#
# app.ini
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = true ; nur, wenn nichts öffentlich sein soll
[security]
INSTALL_LOCK = true
Ein Git-Server mit offener Registrierung wird gefunden und für Spam-Repositorys, Weiterleitungen und Schlimmeres genutzt, oft innerhalb von Tagen. Nutzer legst du als Administrator an oder lädst sie ein. Danach docker compose restart forgejo.
CI: der Runner gehört woanders hin#
Forgejo Actions führt Abläufe im Stil von GitHub Actions aus. Dafür braucht es einen Runner, einen eigenen Dienst, der die Aufträge abholt und in Containern ausführt.
Der Runner führt fremden Code aus, nämlich den aus deinen Repositorys und aus den eingebundenen Actions. Er braucht Docker-Zugriff, also faktisch root. Deshalb läuft er auf einer eigenen Maschine oder VM, nicht auf dem Git-Server. Sonst kann ein manipulierter Ablauf den Server übernehmen, auf dem dein gesamter Code liegt. Die Einrichtung beschreibt die Forgejo-Dokumentation unter „Forgejo Runner“.
Sichern und zurückspielen#
Forgejo bringt einen eigenen Export mit:
docker compose exec -u git forgejo forgejo dump -c /data/gitea/conf/app.ini -f /data/forgejo-dump.zip
Der Dump enthält Repositorys, Einstellungen und Anhänge. Die Datenbank sicherst du zusätzlich direkt, das ist bei PostgreSQL zuverlässiger:
docker compose exec db pg_dump -U forgejo -Fc forgejo > forgejo-db-$(date +%F).dump
Beides gehört vom Server weg, verschlüsselt, etwa mit Restic. Einmal im Jahr spielst du es auf einer Testmaschine zurück. Wie das bei Datenbanken geht, steht in Datenbank sichern und wirklich zurückspielen.
Aktualisieren#
Vor jedem Update: Release Notes lesen, Sicherung machen, dann den Tag in der Compose-Datei hochsetzen und docker compose up -d. Forgejo migriert die Datenbank beim Start selbst. Von einer Hauptversion nicht mehrere auf einmal überspringen, sondern den in den Release Notes beschriebenen Weg nehmen.
Häufige Fragen#
Wie viel Leistung braucht das?#
Für eine Handvoll Nutzer sehr wenig. Forgejo und PostgreSQL zusammen passen auf einen kleinen VPS. Was wächst, ist der Speicherplatz für Repositorys und Anhänge, und bei aktiver CI der Runner, der ohnehin woanders läuft.
Kann ich von GitHub umziehen?#
Ja. Forgejo hat eine Migration, die Repositorys samt Tickets, Pull Requests und Wiki übernimmt. Man braucht dafür ein Zugangstoken für das Quellkonto.
Kann Forgejo Repositorys spiegeln?#
Ja, in beide Richtungen: Fremde Repositorys lokal spiegeln oder eigene nach GitHub oder Codeberg weiterschieben. Das ist auch eine einfache zweite Kopie.
SQLite statt PostgreSQL?#
Für eine Person funktioniert SQLite gut und spart einen Container. Sobald mehrere gleichzeitig arbeiten oder CI läuft, ist PostgreSQL die robustere Wahl. Wann SQLite reicht, steht in SQLite im Betrieb.
Kurz gesagt#
- Forgejo ist schlank und GitHub-ähnlich; Gitea funktioniert fast gleich.
- Weboberfläche hinter einen Reverse-Proxy, Git-SSH auf einen eigenen Port.
- Registrierung sofort abschalten.
- Den CI-Runner auf eine eigene Maschine, nie auf den Git-Server.
forgejo dumppluspg_dump, verschlüsselt vom Server weg, einmal im Jahr zurückspielen.
Geschrieben aus dem laufenden Betrieb: MRMedia betreibt eigene Proxmox- Hosts, einen Backup-Server und Kundendienste in der EU. Fehler in einer Anleitung sind Fehler im eigenen Betrieb. Korrekturen bitte über Discord.