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:
| Backend | Ideal für | Hinweise |
|---|---|---|
| SQLite | Einzelbenutzer / kleine Teams | Keine Konfiguration; nicht für hohe Parallelität geeignet |
| PostgreSQL | Teams und Produktion | Empfohlen; beste Leistung |
| MySQL / MariaDB | Bestehende MySQL-Infrastruktur | Unterstützt; PostgreSQL bevorzugt |
Gitea vs Forgejo vs Alternativen
| Forge | Sprache | RAM (Leerlauf) | Actions CI | Paketregister | Lizenz |
|---|---|---|---|---|---|
| Gitea | Go | ~120 MB | Ja (act_runner) | Ja (11 Typen) | MIT |
| Forgejo | Go | ~120 MB | Ja (act_runner) | Ja | MIT |
| GitLab CE | Ruby/Go | ~2–4 GB | Ja (nativ) | Ja | MIT |
| Gogs | Go | ~50 MB | Nein | Nein | MIT |
| OneDev | Java | ~500 MB | Ja | Begrenzt | MIT |
| Sourcehut | Python/Go | ~100 MB | Ja (builds.sr.ht) | Nein | AGPL |
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(oder636fü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
| Anbieter | Client-ID-Quelle | Umfang |
|---|---|---|
| GitHub | github.com/settings/developers | read:user,user:email |
| GitLab | gitlab.com/-/profile/applications | read_user |
| console.cloud.google.com | openid 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
| Rolle | Repositories | Admin-Panel | Repos erstellen |
|---|---|---|---|
| Eigentümer | Alle in der Org | Ja | Ja |
| Admin (Team) | Team-Repos | Nein | Team-Bereich |
| Schreiben (Team) | Team-Repos | Nein | Nein |
| Lesen (Team) | Team-Repos | Nein | Nein |
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
| Problem | Lösung |
|---|---|
| Web-Oberfläche gibt 502 zurück | docker logs gitea prüfen; Datenbankverbindungs-Umgebungsvariablen verifizieren |
| SSH-Klon schlägt fehl | Sicherstellen, dass SSH_PORT dem Port-Mapping des Hosts entspricht |
| Actions-Workflow wartet endlos | Prüfen ob act_runner läuft und registriert ist; Runner-Labels überprüfen |
| Paket-Push mit Fehler 401 | Token mit package-Bereich generieren; als Registry-Passwort verwenden |
| Mirror synchronisiert nicht | Prü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.inisteuert jeden Aspekt: Sicherheit, Mailer, LFS, Pakete und SSH- Gitea Actions verwendet GitHub Actions YAML-Syntax;
act_runnerfü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