TL;DR — Kurzzusammenfassung

Gitea als selbst gehostete Git-Forge einrichten. Behandelt Docker Compose, Gitea Actions, LDAP, OAuth2, Paketregister, Mirroring und Caddy Reverse Proxy.

Gitea ist eine leichtgewichtige, selbst gehostete Git-Forge, die in Go geschrieben wurde und als einzelne Binärdatei ausgeliefert wird. Sie läuft problemlos auf Hardware, die so bescheiden ist wie ein Raspberry Pi. Wenn Sie jemals vollständige Kontrolle über Ihren Quellcode, CI/CD-Pipelines, Issue-Tracking und Paketregister haben wollten — ohne die Cloud-Preise von GitHub oder GitLab und ohne den Betriebsaufwand einer GitLab CE-Instanz — dann ist Gitea die Antwort. Dieser Leitfaden deckt alles ab, von einer produktionsreifen Docker Compose-Bereitstellung bis hin zu Gitea Actions CI, OAuth2 SSO, Paketregistern und Repository-Mirroring.

Voraussetzungen

  • Docker und Docker Compose v2 auf dem Host installiert
  • Ein Domainname, der auf den Server zeigt (für TLS mit Caddy)
  • Mindestens 512 MB RAM und 2 GB Festplattenspeicher (Gitea selbst benötigt ~150 MB)
  • Grundkenntnisse in Docker Volumes und YAML-Syntax
  • Port 3000 (oder 80/443 über Reverse Proxy) aus Ihrem Netzwerk erreichbar

Gitea-Architektur

Gitea ist eine Go-Anwendung, die in eine einzelne Binärdatei ohne Laufzeitabhängigkeiten kompiliert wird. Es enthält einen Webserver, Git-Hooks, einen SSH-Daemon und Hintergrundworker. Speicheroptionen:

BackendIdeal fürHinweise
SQLiteEinzelbenutzer / kleine TeamsKeine Konfiguration; nicht für hohe Parallelität geeignet
PostgreSQLTeams und ProduktionEmpfohlen; beste Leistung
MySQL / MariaDBBestehende MySQL-InfrastrukturUnterstützt; PostgreSQL bevorzugt

Gitea vs Forgejo vs Alternativen

ForgeSpracheRAM (Leerlauf)Actions CIPaketregisterLizenz
GiteaGo~120 MBJa (act_runner)Ja (11 Typen)MIT
ForgejoGo~120 MBJa (act_runner)JaMIT
GitLab CERuby/Go~2–4 GBJa (nativ)JaMIT
GogsGo~50 MBNeinNeinMIT
OneDevJava~500 MBJaBegrenztMIT
SourcehutPython/Go~100 MBJa (builds.sr.ht)NeinAGPL

Forgejo ist API-kompatibel mit Gitea und Runner sind austauschbar. GitLab CE ist funktional viel umfangreicher, benötigt aber 10–20 Mal mehr Ressourcen.


Schritt 1: Mit Docker Compose und PostgreSQL bereitstellen

Erstellen Sie ein Projektverzeichnis und eine docker-compose.yml:

services:
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    restart: unless-stopped
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=postgres
      - GITEA__database__HOST=db:5432
      - GITEA__database__NAME=gitea
      - GITEA__database__USER=gitea
      - GITEA__database__PASSWD=changeme
    volumes:
      - gitea-data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    container_name: gitea-db
    restart: unless-stopped
    environment:
      - POSTGRES_USER=gitea
      - POSTGRES_PASSWORD=changeme
      - POSTGRES_DB=gitea
    volumes:
      - postgres-data:/var/lib/postgresql/data

volumes:
  gitea-data:
  postgres-data:
docker compose up -d

Öffnen Sie http://ihr-server:3000 im Browser. Der Web-Installer füllt die Datenbankeinstellungen aus den Umgebungsvariablen vor. Konfigurieren Sie nur die Basis-URL, den Administrator-Benutzernamen, die Administrator-E-Mail und das Administrator-Passwort, klicken Sie dann auf Installieren.


Schritt 2: app.ini konfigurieren

Nach der Installation befindet sich app.ini im Docker-Volume unter gitea/conf/app.ini:

[server]
DOMAIN           = git.beispiel.de
ROOT_URL         = https://git.beispiel.de/
HTTP_PORT        = 3000
SSH_DOMAIN       = git.beispiel.de
SSH_PORT         = 22
SSH_LISTEN_PORT  = 22
DISABLE_SSH      = false
LFS_START_SERVER = true

[repository]
DEFAULT_BRANCH          = main
ENABLE_PUSH_CREATE_USER = false
DEFAULT_PRIVATE         = private

[security]
INSTALL_LOCK              = true
SECRET_KEY                = <generieren-mit-openssl-rand-hex-32>
INTERNAL_TOKEN            = <generieren-mit-gitea-generate-secret>
MIN_PASSWORD_LENGTH       = 12
PASSWORD_COMPLEXITY       = lower,upper,digit,spec

[service]
DISABLE_REGISTRATION              = false
REQUIRE_SIGNIN_VIEW               = false
REGISTER_EMAIL_CONFIRM            = true
ENABLE_NOTIFY_MAIL                = true

[mailer]
ENABLED   = true
SMTP_ADDR = smtp.beispiel.de
SMTP_PORT = 587
FROM      = "Gitea <gitea@beispiel.de>"
USER      = gitea@beispiel.de
PASSWD    = `ihr-smtp-passwort`

Neu starten zum Anwenden:

docker compose restart gitea

Schritt 3: Repository-Verwaltung

Git LFS

LFS wird mit LFS_START_SERVER = true in [server] aktiviert. Benutzer konfigurieren ihren lokalen Client einmalig:

git lfs install
git lfs track "*.psd" "*.zip" "*.tar.gz"

Repository-Mirroring

Pull-Mirrors ermöglichen es Gitea, periodisch von GitHub, GitLab oder einem beliebigen Git-Remote zu klonen und zu synchronisieren. In der Web-Oberfläche: Neues Repository → Migrieren. Wählen Sie die Quelle und aktivieren Sie Dieses Repository wird ein Mirror sein mit dem gewünschten Synchronisierungsintervall.

Push-Mirrors senden jeden Commit automatisch an einen Remote. Konfigurieren Sie diese unter Repository-Einstellungen → Mirror-Einstellungen → Push-Mirrors.

Geschützte Branches und Merge-Strategien

Unter Repository-Einstellungen → Branches → Branch-Schutzregel hinzufügen:

  • Pull-Request-Reviews erforderlich — minimale Genehmigungen festlegen
  • Statusprüfungen erforderlich — Merge blockieren wenn Actions-Workflow fehlschlägt
  • Push einschränken — Teams oder Benutzer auf Whitelist setzen
  • Merge-Strategien — Merge-Commit, Squash und Rebase pro Repository aktivieren/deaktivieren

Schritt 4: Gitea Actions CI

Gitea Actions ist das integrierte CI-System mit derselben YAML-Syntax wie GitHub Actions.

act_runner registrieren

Laden Sie die neueste act_runner-Binärdatei von https://gitea.com/gitea/act_runner/releases herunter. Im Admin-Panel unter Website-Administration → Actions → Runner → Neuen Runner-Token erstellen.

# Runner registrieren
act_runner register \
  --instance https://git.beispiel.de \
  --token <runner-token> \
  --name mein-runner \
  --labels ubuntu-latest:docker://node:20-bullseye

# Als Dienst starten
act_runner daemon

Beispiel-Workflow

# .gitea/workflows/build.yml
name: Bauen und Testen

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"
      - run: npm ci
      - run: npm test

  docker:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Docker-Image bauen
        run: docker build -t meineapp:${{ gitea.sha }} .
      - name: In Gitea-Registry veröffentlichen
        run: |
          docker login git.beispiel.de -u ${{ secrets.REGISTRY_USER }} -p ${{ secrets.REGISTRY_TOKEN }}
          docker push git.beispiel.de/meinorg/meineapp:${{ gitea.sha }}

Schritt 5: Benutzerverwaltung und Authentifizierung

Lokale Konten und 2FA

2FA über TOTP verfügbar unter Benutzereinstellungen → Sicherheit → Zwei-Faktor-Authentifizierung.

LDAP / Active Directory

Website-Administration → Identität und Zugang → Authentifizierungsquellen → LDAP (über BindDN):

  • Host: ldap.beispiel.de
  • Port: 389 (oder 636 für LDAPS)
  • Bind DN: cn=gitea,ou=dienstkonten,dc=beispiel,dc=de
  • Benutzer-Suchbasis: ou=benutzer,dc=beispiel,dc=de
  • Benutzerfilter: (&(objectClass=person)(sAMAccountName=%s))

OAuth2-Anbieter

AnbieterClient-ID-QuelleUmfang
GitHubgithub.com/settings/developersread:user,user:email
GitLabgitlab.com/-/profile/applicationsread_user
Googleconsole.cloud.google.comopenid email profile

Schritt 6: Caddy Reverse Proxy mit TLS

Fügen Sie dies in Ihre Caddyfile ein:

git.beispiel.de {
    reverse_proxy gitea:3000

    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Frame-Options "SAMEORIGIN"
        X-Content-Type-Options "nosniff"
    }
}

Caddy holt automatisch Let’s Encrypt-Zertifikate bei der ersten Anfrage an die Domain.


Organisationen, Teams und Berechtigungen

RolleRepositoriesAdmin-PanelRepos erstellen
EigentümerAlle in der OrgJaJa
Admin (Team)Team-ReposNeinTeam-Bereich
Schreiben (Team)Team-ReposNeinNein
Lesen (Team)Team-ReposNeinNein

Gitea-Paketregister

Aktivieren Sie das Paketregister in app.ini:

[packages]
ENABLED = true

Unterstützte Pakettypen: npm, PyPI, Maven, NuGet, Docker/OCI, Composer, Cargo, Conan, Helm, RubyGems und Alpine/Debian APT.

Sicherung und Wiederherstellung

# Im Container
docker exec -u git gitea gitea dump -c /data/gitea/conf/app.ini \
  -t /tmp --type tar.gz

# Archiv auf den Host kopieren
docker cp gitea:/tmp/gitea-dump-*.tar.gz ./sicherungen/

Migration von GitHub, GitLab oder Gogs

Website-Administration → Migrationen unterstützt vollständigen Import unter Beibehaltung von Issues, Pull Requests, Labels, Meilensteinen, Releases und Wiki-Seiten. Die Migration von Gogs zu Gitea ist nahtlos — Gitea liest die Gogs-Datenbank direkt.

Fallstricke und Sonderfälle

SSH-Port-Konflikt — Wenn Port 22 bereits vom SSH-Daemon des Hosts verwendet wird, mappen Sie Giteas SSH auf einen anderen Port (z.B. 222:22) und aktualisieren Sie SSH_PORT in app.ini.

Docker-in-Docker mit act_runner — Für Workflows, die Docker-Images bauen, benötigt der Runner Zugriff auf den Docker-Socket. Mounten Sie /var/run/docker.sock in den Runner-Container.

LFS-Speicherwachstum — LFS-Objekte werden nicht automatisch bereinigt. Planen Sie gitea admin repo-lfs-prune regelmäßig ein.

Fehlerbehebung

ProblemLösung
Web-Oberfläche gibt 502 zurückdocker logs gitea prüfen; Datenbankverbindungs-Umgebungsvariablen verifizieren
SSH-Klon schlägt fehlSicherstellen, dass SSH_PORT dem Port-Mapping des Hosts entspricht
Actions-Workflow wartet endlosPrüfen ob act_runner läuft und registriert ist; Runner-Labels überprüfen
Paket-Push mit Fehler 401Token mit package-Bereich generieren; als Registry-Passwort verwenden
Mirror synchronisiert nichtPrüfen ob Mirror-URL vom Container erreichbar ist

Zusammenfassung

  • Gitea läuft mit ~120 MB RAM als einzelne Go-Binärdatei — viel leichter als GitLab CE
  • Docker Compose mit PostgreSQL ist das empfohlene Produktions-Deployment
  • app.ini steuert jeden Aspekt: Sicherheit, Mailer, LFS, Pakete und SSH
  • Gitea Actions verwendet GitHub Actions YAML-Syntax; act_runner führt Jobs in Docker-Containern aus
  • LDAP, OAuth2 (GitHub/GitLab/Google) und TOTP 2FA sind integriert
  • Paketregister unterstützen npm, PyPI, Maven, NuGet, Docker/OCI und mehr
  • Repository-Mirroring (Push und Pull) hält externe Repos automatisch synchronisiert
  • Forgejo ist eine Drop-in-API-kompatible Alternative mit gemeinschaftsorientierter Governance

Verwandte Artikel