Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Linux 16.06.2026 · 10 min Lesezeit

Forgejo nativ auf Ubuntu installieren: Binary, systemd, Nginx und MariaDB

Forgejo – den community-getriebenen Gitea-Fork – als einzelnes Go-Binary direkt auf Ubuntu deployen: ohne Docker-Overhead, mit dediziertem Systemuser, MariaDB als Produktionsdatenbank, systemd-Service und Nginx als Reverse Proxy mit SSL.

Moderne IT-Grafik zur Anleitung für die native Installation von Forgejo auf Ubuntu mit Binary, systemd, Nginx und MariaDB, inklusive Server, Terminal, Weboberfläche und wichtiger Konfigurationspfade.

Wer einen eigenen Git-Server betreiben will, stößt früher oder später auf Forgejo – den community-getriebenen Fork von Gitea, der seit 2022 unter dem Dach von Codeberg.org entwickelt wird. Anders als GitLab CE kommt Forgejo als einzelnes statisches Go-Binary daher: keine Runtime-Abhängigkeiten, kein aufgeblähter Container-Stack, kein Kubernetes. Diese Anleitung zeigt dir, wie du Forgejo 15.0.3 direkt auf einem Ubuntu-Server deployest – mit systemd-Unit, Nginx-Reverse-Proxy, MariaDB als Produktionsdatenbank und optionalem Let's-Encrypt-SSL. Der Ansatz eignet sich besonders für KMU-Admins und Selfhoster, die volle Kontrolle über jeden Layer behalten wollen und auf den Docker-Overhead verzichten möchten.

Voraussetzungen

  1. Ubuntu-Server 20.04, 22.04 oder 24.04 LTS (amd64 oder arm64)
  2. Root- oder sudo-Zugriff auf den Server
  3. Domain oder Subdomain (z. B. git.example.com) mit DNS-A-Record auf die Server-IP
  4. Offene Ports: 22 (SSH), 80 (HTTP), 443 (HTTPS) – Port 22 muss vor dem Aktivieren der Firewall freigeschaltet sein
  5. Mindestens 1 GB RAM (empfohlen: 2 GB+), 10 GB freier Speicher für Repositories
  6. Forgejo-Binary 15.0.3 von codeberg.org/forgejo/forgejo/releases
KomponenteVersion / PaketZweck
Forgejo Binary15.0.3 (Go, statisch)Anwendungsserver auf Port 3000
MariaDB11.4 LTS (apt)Produktionsdatenbank mit utf8mb4_bin
Nginxapt (stable)Reverse Proxy, TLS-Terminierung
Certbotpython3-certbot-nginxLet's Encrypt SSL automatisch
systemdUbuntu built-inService-Management, Autostart
git + git-lfsaptPflichtabhängigkeit von Forgejo

Schritt 1: System vorbereiten und Abhängigkeiten installieren

Aktualisiere zunächst das System und installiere alle notwendigen Pakete. git und git-lfs müssen vor dem ersten Forgejo-Start vorhanden sein – der Dienst prüft die Verfügbarkeit beim Start und schlägt andernfalls stumm fehl.

sudo apt update && sudo apt upgrade -y
sudo apt install -y git git-lfs wget curl ufw ca-certificates nginx mariadb-server

Verifizieren: git --version und git-lfs --version müssen jeweils eine Versionsnummer ausgeben.

Schritt 2: Forgejo-Binary herunterladen und installieren

Forgejo wird als einzelnes statisches Binary ausgeliefert – keine Go-Runtime, keine zusätzlichen Bibliotheken nötig. Lade die aktuelle Version herunter und prüfe die SHA256-Prüfsumme, bevor du das Binary produktiv einsetzt.

cd /tmp
wget -O forgejo \
  https://codeberg.org/forgejo/forgejo/releases/download/v15.0.3/forgejo-15.0.3-linux-amd64

# SHA256-Prüfsumme verifizieren (empfohlen)
wget https://codeberg.org/forgejo/forgejo/releases/download/v15.0.3/forgejo-15.0.3-linux-amd64.sha256
sha256sum -c forgejo-15.0.3-linux-amd64.sha256

sudo cp forgejo /usr/local/bin/forgejo
sudo chmod 755 /usr/local/bin/forgejo

Für ARM64-Server (z. B. Hetzner CAX, Raspberry Pi 4/5) ersetzt du linux-amd64 durch linux-arm64 bzw. linux-arm-6 – offizielle Binaries existieren für alle gängigen Architekturen.

Verifizieren: forgejo --version gibt Forgejo version 15.0.3 aus.

Schritt 3: Systemuser und Verzeichnisstruktur anlegen

Forgejo läuft unter einem dedizierten Systemuser git. Der Name ist kein Zufall: SSH-Clone-URLs haben dann die vertraute Form git@git.example.com:Org/Repo.git – genauso wie bei GitHub oder Codeberg. Der User hat kein Passwort und keine interaktive Shell nach außen.

sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' \
  --group --disabled-password --home /home/git git

# Verzeichnisstruktur
sudo mkdir -p /var/lib/forgejo/{data,custom,log}
sudo mkdir -p /etc/forgejo

# Berechtigungen setzen
sudo chown git:git /var/lib/forgejo && sudo chmod 750 /var/lib/forgejo
sudo chown git:git /var/lib/forgejo/log

# /etc/forgejo: während des Web-Setups braucht git Schreibrecht (770)
sudo chown root:git /etc/forgejo && sudo chmod 770 /etc/forgejo
PfadEigentümerRechte (Setup)Rechte (nach Setup)
/usr/local/bin/forgejoroot:root755755
/var/lib/forgejogit:git750750
/etc/forgejoroot:git770750
/etc/forgejo/app.iniroot:git(vom Wizard angelegt)640
/etc/systemd/system/forgejo.serviceroot:root644644

Schritt 4: MariaDB vorbereiten

MariaDB ist die empfohlene Produktionsdatenbank für Forgejo. Entscheidend ist die Collation utf8mb4_bin – Forgejo erwartet case-sensitive String-Vergleiche und bricht die Ersteinrichtung ab, wenn die Datenbank mit utf8mb4_unicode_ci angelegt wurde. Dieser Fallstrick kostet Zeit; leg die Datenbank daher von Anfang an korrekt an.

sudo mysql_secure_installation
sudo mysql -u root -p
CREATE USER 'forgejo'@'localhost' IDENTIFIED BY 'StarkesPasswort!';
CREATE DATABASE forgejo CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_bin';
GRANT ALTER, CREATE, DELETE, DROP, INDEX, INSERT, REFERENCES, SELECT, UPDATE
  ON forgejo.* TO 'forgejo'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Verifizieren: sudo mysql -u forgejo -p forgejo -e "SHOW CREATE DATABASE forgejo\G" – in der Ausgabe muss utf8mb4_bin stehen.

DatenbankEmpfehlungBesonderheit
SQLite3Nur Entwicklung/TestKein Extra-Setup, aber kein Multi-User-Betrieb
MariaDB/MySQLProduktion (Standard)utf8mb4_bin Pflicht, unbegrenzte Nutzer
PostgreSQLProduktion (Alternative)Vollständig unterstützt, ebenfalls empfohlen

Schritt 5: systemd-Service einrichten

Der offizielle systemd-Service liegt auf Codeberg als Vorlage bereit. Für eine MariaDB-Abhängigkeit müssen die Wants=- und After=-Zeilen im [Unit]-Block aktiviert werden – sonst startet Forgejo beim Booten vor der Datenbank und schlägt fehl. Diesen Schritt vergessen viele, und dann wundert man sich über sporadische Start-Fehler nach Reboots.

sudo wget -O /etc/systemd/system/forgejo.service \
  https://codeberg.org/forgejo/forgejo/raw/branch/forgejo/contrib/systemd/forgejo.service

Öffne die Service-Datei und stelle sicher, dass im [Unit]-Block die MariaDB-Abhängigkeit aktiv ist (Kommentarzeichen entfernen):

[Unit]
Description=Forgejo Git Service
After=network.target mariadb.service
Wants=mariadb.service

Falls der Download fehlschlägt, kannst du die minimale Vorlage direkt anlegen:

[Unit]
Description=Forgejo Git Service
After=network.target mariadb.service
Wants=mariadb.service

[Service]
User=git
Group=git
WorkingDirectory=/var/lib/forgejo
Environment=FORGEJO_WORK_DIR=/var/lib/forgejo
ExecStart=/usr/local/bin/forgejo web --config /etc/forgejo/app.ini
Restart=on-failure
RestartSec=2s
WatchdogSec=30s

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable forgejo.service
sudo systemctl start forgejo.service
sudo systemctl status forgejo.service

Verifizieren: sudo systemctl status forgejo.service zeigt active (running). Mit sudo journalctl -n 50 --unit forgejo.service kannst du die letzten Log-Zeilen prüfen – nach dem ersten Start ohne app.ini erscheint eine Meldung über den Web-Setup-Wizard.

Schritt 6: Nginx als Reverse Proxy konfigurieren

Forgejo lauscht intern auf 127.0.0.1:3000 – Nginx übernimmt die öffentliche Erreichbarkeit auf Port 80/443. Zwei Details sind hier wichtig: merge_slashes off verhindert, dass URL-kodierte Schrägstriche in Repository-Pfaden zusammengefasst werden (ohne diese Direktive gibt es API-404-Fehler). Die WebSocket-Header Upgrade und Connection sind für die Live-Aktualisierungen im Web-Interface nötig.

sudo nano /etc/nginx/sites-available/forgejo
server {
    listen 80;
    listen [::]:80;
    server_name git.example.com;
    merge_slashes off;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Connection $http_connection;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        client_max_body_size 512M;
    }
}
sudo ln -s /etc/nginx/sites-available/forgejo /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Der client_max_body_size 512M-Wert ist keine Empfehlung für kleine Projekte, sondern eine Notwendigkeit: Nginx verwirft große Git-Pushes und LFS-Uploads standardmäßig mit HTTP 413. Für sehr große Repositories kannst du den Wert noch weiter erhöhen.

Verifizieren: sudo nginx -t gibt syntax is ok und test is successful aus.

Schritt 7: SSL mit Let's Encrypt (Certbot)

Certbot konfiguriert Nginx automatisch für HTTPS und richtet die Zertifikatserneuerung per Cronjob ein. Stelle sicher, dass der DNS-A-Record für git.example.com bereits auf die Server-IP zeigt – Certbot validiert per HTTP-Challenge.

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d git.example.com

Alternativ kannst du SSL auch in Forgejo selbst konfigurieren (integrierter ACME-Client) – für die meisten Setups ist Certbot via Nginx jedoch die flexiblere Lösung, da Nginx bereits als Reverse Proxy läuft. Wer lieber Caddy als automatischen Reverse Proxy nutzt, findet die entsprechende Anleitung weiter unten verlinkt.

Verifizieren: sudo certbot certificates zeigt das Zertifikat mit Ablaufdatum. Ein Aufruf von https://git.example.com im Browser sollte das grüne Schloss zeigen.

Schritt 8: Firewall konfigurieren

Wichtig: Port 22 (SSH) muss vor dem Aktivieren von UFW freigeschaltet sein – sonst sperrst du dich vom Server aus.

sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
sudo ufw enable

SSH-Port 22 läuft direkt am git-User und wird nicht über Nginx geleitet. Forgejo verwaltet ~/.ssh/authorized_keys des git-Users automatisch, wenn Nutzer ihren öffentlichen Schlüssel im Web-Interface hinterlegen.

Schritt 9: Web-Setup abschließen

Rufe http://git.example.com (oder bereits https:// nach Certbot) im Browser auf. Die Ersteinrichtungsseite erscheint nur beim allerersten Aufruf und speichert die Konfiguration in /etc/forgejo/app.ini.

Fülle das Formular wie folgt aus:

  1. Datenbanktyp: MySQL/MariaDB
  2. Host: 127.0.0.1:3306
  3. Datenbankname: forgejo, User: forgejo, Passwort: wie in Schritt 4 gesetzt
  4. Domain: git.example.com
  5. Base URL: https://git.example.com/ (mit abschließendem Slash!)
  6. Admin-Konto anlegen

Nach dem Abschicken startet Forgejo ggf. kurz neu und leitet auf das Dashboard weiter.

Schritt 10: Post-Install-Härtung und Produktions-app.ini

Nach dem Web-Setup sind zwei Maßnahmen zwingend: Erstens müssen /etc/forgejo und app.ini auf sichere Berechtigungen gesetzt werden (der Wizard hat temporär Schreibrecht benötigt). Zweitens muss INSTALL_LOCK = true gesetzt sein – sonst kann jeder mit Zugriff auf die URL die Instanz neu konfigurieren oder übernehmen.

sudo systemctl stop forgejo.service
sudo chmod 750 /etc/forgejo
sudo chmod 640 /etc/forgejo/app.ini
sudo systemctl start forgejo.service

Empfohlene Produktions-Einstellungen für /etc/forgejo/app.ini (Auszug, ergänze oder passe an was der Web-Wizard bereits gesetzt hat):

[security]
INSTALL_LOCK = true
SECRET_KEY = <generiert via: sudo -u git forgejo generate secret SECRET_KEY>
INTERNAL_TOKEN = <generiert via: sudo -u git forgejo generate secret INTERNAL_TOKEN>
MIN_PASSWORD_LENGTH = 12
PASSWORD_COMPLEXITY = lower,upper,digit,spec

[server]
DOMAIN = git.example.com
ROOT_URL = https://git.example.com/
HTTP_ADDR = 127.0.0.1
HTTP_PORT = 3000
APP_DATA_PATH = /var/lib/forgejo/data
OFFLINE_MODE = true

[database]
DB_TYPE = mysql
HOST = 127.0.0.1:3306
NAME = forgejo
USER = forgejo
PASSWD = StarkesPasswort!
CHARSET_COLLATION = utf8mb4_bin

[repository]
ROOT = /var/lib/forgejo/repositories

[log]
MODE = file
LEVEL = info
ROOT_PATH = /var/lib/forgejo/log

[service]
DISABLE_REGISTRATION = true

[repository.upload]
FILE_MAX_SIZE = 4095
MAX_FILES = 20

Wichtig: SECRET_KEY und INTERNAL_TOKEN niemals manuell erfinden oder leer lassen – immer über sudo -u git forgejo generate secret SECRET_KEY erzeugen. Der Web-Wizard setzt diese Werte normalerweise automatisch; prüfe dennoch, ob sie vorhanden sind.

Für Admin-Befehle auf der Kommandozeile ist ein kleiner CLI-Wrapper praktisch:

sudo tee /usr/local/bin/forgejo-cli << 'EOF'
#!/bin/sh
sudo -u git forgejo -w /var/lib/forgejo -c /etc/forgejo/app.ini "$@"
EOF
sudo chmod 755 /usr/local/bin/forgejo-cli
# Beispiel: forgejo-cli admin user list

Verifizieren: forgejo-cli admin user list listet alle vorhandenen Benutzer auf.

Troubleshooting / Typische Fehler

Ersteinrichtung schlägt mit Datenbankfehler fehl

Ursache: Datenbank mit falscher Collation angelegt (utf8mb4_unicode_ci statt utf8mb4_bin). Lösung: Datenbank droppen und mit korrekter Collation neu anlegen. Ein späterer Wechsel ist aufwändig – von Anfang an richtig machen.

Forgejo startet nach Reboot nicht

Ursache: Wants=mariadb.service und After=mariadb.service fehlen im systemd-Unit. Forgejo versucht, sich vor MariaDB zu verbinden. Lösung: Service-Datei anpassen (Schritt 5), dann sudo systemctl daemon-reload.

HTTP 413 bei großen Git-Pushes

Ursache: client_max_body_size in Nginx ist zu klein (Standard: 1 MB). Lösung: in der Nginx-Konfiguration auf mindestens 512M erhöhen und Nginx neu starten.

404-Fehler bei bestimmten API-Requests

Ursache: merge_slashes off fehlt in der Nginx-Konfiguration. URL-kodierte Schrägstriche in Repository-Pfaden werden zusammengefasst. Lösung: Direktive zum server {}-Block hinzufügen.

Web-Setup-Wizard erzeugt keine app.ini

Ursache: /etc/forgejo hat chmod 750 statt 770, der git-User kann nicht schreiben. Lösung: sudo chmod 770 /etc/forgejo während des Setups, danach auf 750 zurücksetzen.

Binary startet nicht

Ursache: chmod 755 vergessen. Das Binary muss ausführbar sein. Prüfen mit ls -la /usr/local/bin/forgejo.

app.ini ROOT_URL falsch

Ursache: ROOT_URL enthält http:// statt https:// oder fehlt der abschließende Slash. Alle generierten Links (z. B. Clone-URLs, E-Mail-Links) sind dann falsch. Lösung: app.ini anpassen und Forgejo neu starten.

Häufige Fragen

Kann ich später von SQLite auf MariaDB migrieren?

Ja, Forgejo bietet ein integriertes Migrations-Tool (forgejo convert) sowie den Export über das Admin-Panel. Der Aufwand ist aber nicht gering – die Empfehlung lautet: gleich mit MariaDB starten, wenn der Produktivbetrieb geplant ist.

Wie update ich Forgejo auf eine neue Version?

Service stoppen, das alte Binary als Backup sichern (sudo cp /usr/local/bin/forgejo /usr/local/bin/forgejo.bak), neues Binary herunterladen, nach /usr/local/bin/forgejo kopieren, chmod 755 setzen, Service starten. Datenbank-Migrationen laufen automatisch beim ersten Start der neuen Version. Immer vorher ein MariaDB-Backup erstellen.

Läuft Forgejo auch auf ARM-Servern (z. B. Hetzner CAX, Raspberry Pi)?

Ja, offizielle Binaries gibt es für linux-arm64 und linux-arm-6 auf der Release-Seite bei Codeberg. Dieselbe Anleitung funktioniert; nur den Binary-Download-Link anpassen.

Wie richte ich SSH-Key-Authentifizierung ein?

SSH läuft direkt über den git-User auf Port 22 – vollständig außerhalb von Nginx. Nutzer laden ihren öffentlichen SSH-Schlüssel einfach im Forgejo-Web-Interface unter „Einstellungen → SSH-Schlüssel" hoch. Forgejo verwaltet /home/git/.ssh/authorized_keys automatisch.

Wie konfiguriere ich E-Mail-Versand?

Im app.ini unter [mailer]: ENABLED = true, PROTOCOL = smtp, SMTP_ADDR = mail.example.com, SMTP_PORT = 587, USER = ..., PASSWD = ..., FROM = forgejo@example.com. Anschließend Forgejo neu starten.

Wie sperre ich die öffentliche Registrierung?

In app.ini unter [service]: DISABLE_REGISTRATION = true. Danach können Nutzerkonten nur noch vom Admin über das Web-Interface oder via forgejo-cli admin user create angelegt werden.

Fazit

Forgejo als natives Binary zu betreiben hat gegenüber der Docker-Variante einen echten Charme: Die Ressourcen-Overhead fällt weg, das Debugging ist direkter, und systemd übernimmt das Service-Management genau so, wie man es von anderen Server-Diensten kennt. Der Einrichtungsaufwand ist überschaubar – die kritischen Punkte sind die korrekte MariaDB-Collation, die temporären Schreibrechte auf /etc/forgejo während des Web-Setups und das abschließende Setzen von INSTALL_LOCK = true. Mit diesen Grundlagen hast du einen produktionstauglichen, eigenständigen Git-Server, der in 60 Minuten einsatzbereit ist.

Weiterführende Anleitungen und Quellen

  1. Nginx als Reverse Proxy mit TLS manuell einrichten – Grundlagen für erweiterte Nginx-Konfigurationen
  2. Caddy als Reverse-Proxy mit automatischem HTTPS – wann er Nginx und Traefik schlägt – Alternative zu Certbot/Nginx
  3. systemd-Service selbst erstellen und verwalten – Hintergrundwissen zu Unit-Dateien und Abhängigkeiten
  4. MariaDB / MySQL installieren und absichern – Vertiefte MariaDB-Konfiguration und Härtung
  5. Nextcloud nativ auf Ubuntu installieren (LEMP ohne Docker) – gleicher Stack-Ansatz für eine andere Plattform
  6. Gitea mit Docker: eigener Git-Server als GitHub-Alternative – Docker-Variante zum Vergleich

Offizielle Quellen:

  1. Forgejo Docs: Installation from binary
  2. Forgejo Docs: Database Preparation
  3. Forgejo Docs: Reverse Proxy / Nginx
  4. Forgejo Docs: Config Cheat Sheet