Gitea oder Gogs statt Github und Gitlab


Ich habe mir den Github-Klon Gogs und dessen Fork Gitea näher angeschaut und bin hellauf begeistert. Weiter unten erkläre ich noch, wie ich Gogs bzw. Gitea TLS-verschlüsselt hinter Nginx laufen lasse. Nun aber erst mal zu Gogs und warum ich es brauche.

Github ist über die Jahre zum defacto-Standard für Opensource-Entwicklung geworden. Das liegt zum einen an den Features, die Github bietet (Pull-Requests, Issues, Wiki). Die Popularität rührt aber auch daher, dass diese Features sehr einfach gehalten sind. Das Issue-Tracking ist extrem rudimentär, alles andere ist aber für viele Overkill. Github hat das Mitmachen einfach gemacht.

Es gibt allerdings auch Gründe, die gegen die Nutzung von Github sprechen. Github selbst ist z.B. keine Opensource Software. Möchte man auch private Repositories erstellen, braucht man ein kostenpflichtiges Konto. Das habe ich zwar, aber trotzdem möchte ich nicht zwangsläufig das Schicksal meines Codes einer Firma überlassen, über die ich keine Kontrolle habe. Dank der Dezentralität von Git schadet es auch nicht mehrgleisig zu fahren (z.B. Mirror auf Github für Pull-Requests und issues).

Die erste Alternative, die ich mir angeschaut habe, war Gitlab. Komplett open source, ähnliche Features wie Github und dazu noch eine integrierte Plattform für Continuous Integration. Nach einem halben Tag Installation und Konfiguration (alles eher komplex) hat sich gezeigt, dass meine Hardware nicht leistungsstark genug ist und ich einen extra Server für Gitlab bräuchte. Wo Web, Mail, Seafile (mit ~100 aktiven Usern), Minecraft und diverse andere Dinge klaglos parallel laufen, läuft Gitlab nicht mal allein flüssig. Wie das auf einem Raspberry Pi laufen soll ist mir schleierhaft.

Der nächste Kandidat war dann schon Gogs und es konnte sofort überzeugen. Auf den ersten Blick bietet Gogs die gleichen Features wie Github. Zum Teil nicht ganz so poliert, manchmal wirkt es aber auch schicker. Gogs ist in Go geschrieben (Gogs = Go Git Service) und so leichtgewichtig (~20MB RAM), dass es sogar auf einem Raspberry Pi ordentlich läuft.

Und Gitea?

Gogs wurde vor kurzem geforkt. Nachdem der zentrale Entwickler wiederholt für Monate nicht erreichbar war hatte die Community genug und hat Gitea erstellt. Die Entwicklung beim Fork läuft schneller und transparenter, als es bei Gogs je der Fall war. Meine Empfehlung lautet also, Gitea statt Gogs einzusetzen. An Features muss man im Vergleich zu Git kaum Abstriche machen. Hier mal eine kleine unvollständige Aufstellung:

  • interner Issue Tracker (extern möglich)
  • internes Wiki (ebenso extern möglich)
  • protected branches
  • Git hooks
  • webhooks
  • deploy keys
  • signierte Commits
  • Authentifizierung auch über LDAP, SMTP, OAuth2, OpenID und PAM
  • 2FA
  • Support für DroneCI und andere


Installation

Bevor es losgeht sollte man sich schon mal ein Letsencrypt-Zertifikat für die zu nutzende Domain besorgen und installieren. Wenn die Domain per https aufrufbar ist, geht die Installation auf dem Server im Terminal weiter. In dieser Anleitung benutze ich als Beispiel-Domain git.example.com.

Auf dem Server sollte mindestens git und supervisor installiert sein. Letzteres benutzen wir, um Gitea automatisiert zu starten. Gitea soll außerdem unter einem eigenen User laufen (git), der gleichzeitig auch für die SSH-Verbindungen genutzt werden kann.

sudo apt-get install git supervisor
sudo adduser --home /opt/git --shell /bin/bash --disabled-password git
sudo mkdir -p /var/log/gitea && sudo chown git: /var/log/gitea
sudo -u git -i

Das passende Binary von der Gitea Website herunterladen. Dort kann man auf der Downloadseite die aktuellste Version aufwählen (für stabilen Betrieb) oder master, wenn man gern gefährlich lebt, aber dafür die aktuellsten Features hat.

cd /opt/git
mkdir gitea
cd gitea
wget -O gitea https://dl.gitea.io/gitea/master/gitea-master-linux-amd64
chmod +x gitea

Ob Gitea läuft kann man mit folgendem Aufruf testen:

./gitea web

An dieser Stelle sollte Gitea über http://git.example.com:3000 erreichbar sein. Da wir die Konfiguration verschlüsselt erledigen wollen, schliessen wir an dieser Stelle Gitea wieder und kümmern uns zunächst um den Nginx Proxy.

Nginx

Ich zeige hier nur die für Gitea nötige Nginx-Konfiguration und gehe davon aus, dass die Einstellungen für vhost und SSL-Zertifikate bekannt sind.

Wir machen zunächst einen Rewrite auf https, damit die Seite nicht unverschlüsselt aufgerufen werden kann (dazu auch den Kommentar von benediktg beachten). Dann benutzen wir nginx als Proxy für Gitea. Falls 127.0.0.1 als IP nicht funktioniert, kann man auch die echte WAN-IP des Servers hinterlegen.

Da ab dieser Stelle Gitea als Webserver fungiert müssen wir noch eine Ausnahme für die Bestätigung der Letsencrypt-Zertifikate hinterlegen. Hier sollte /var/www/git.example.com/httpdocs/ durch den tatsächlichen (bzw. ursprünglichen) public HTML-Ordner der Domain ersetzt werden.

if ($scheme !~* ^https ){
rewrite ^ https://$server_name$request_uri? permanent;
}

location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass http://127.0.0.1:3000/;
}

location /.well-known/acme-challenge/ {
    alias /var/www/git.example.com/httpdocs/.well-known/acme-challenge/;
}

Zuletzt sorgen wir noch dafür, dass Gitea automatisch startet. Dazu reicht es eine Datei namens /etc/supervisor/conf.d/gitea.conf anzulegen mit folgendem Inhalt:

[program:gitea]
directory=/opt/git/gitea/
command=/opt/git/gitea/gitea web
autostart=true
autorestart=true
startsecs=10
stdout_logfile=/var/log/gitea/stdout.log
stdout_logfile_maxbytes=1MB
stdout_logfile_backups=10
stdout_capture_maxbytes=1MB
stderr_logfile=/var/log/gitea/stderr.log
stderr_logfile_maxbytes=1MB
stderr_logfile_backups=10
stderr_capture_maxbytes=1MB
environment = HOME="/opt/git", USER="git"
user = git

Konfiguration

Nach einem Neustart von Supervisor sollte Gitea nun laufen und die Seite müsste ohne Angabe des Ports über https://git.example.com erreichbar sein. Beim ersten Aufruf gelangt man auf die Installationsseite. Hier würde ich folgende Minimal-Konfiguration empfehlen:

  • eine MySQL-Datenbank
  • Repository: /opt/git/gitea/gitea-repositories
  • Benutzer: git
  • Domain: example.com (nicht git.example.com, es geht hier um die Domain für die SSH clone URLs)
  • Anwendungs-URL: https://git.example.com
  • Log-Pfad: /var/log/gitea
  • E-Mail-Service: Ich empfehle einen externen Dienst wie Sparkpost oder Mailgun
  • Diensteinstellungen: Nach Bedarf. Bei einem privaten Server würde ich die Registrierung deaktivieren und Seiten nur für angemeldete Benutzer zugänglich machen
  • Admin: Hier kann man direkt das Admin-Konto anlegen

Gratulation. Jetzt sollte Gitea laufen. Viel Spaß beim nutzen!

6 Gedanken zu „Gitea oder Gogs statt Github und Gitlab

  1. Nico

    Vor einigen Wochen habe ich mir Gogs auch schon angesehen. Leider hat es nicht ganz mit einem node-Service geklappt, so dass Gogs dauerhaft läuft. Aus diesem Grund habe ich dann auf Bitbucket zurück gegriffen. Bitbucket kostet zwar 10$ im Jahr und läuft mit Java (buuuuh!), doch damit bin ich zufrieden.

    Antworten
    1. dakira Beitragsautor

      Die Geschichte mit dem node service verstehe ich nicht. Gibt es eine Art service runner von nodejs? Warum sollte man den benutzen für ein Go-Projekt? Oder verstehe ich das hier ganz falsch.

      Ich setze jetzt ja schon eine Weile auf Gitea, daher möchte ich für Gogs nicht mehr die Hand ins Feuer legen. Das läuft nun aber seit gut zwei Jahren stabil bei mir. Wenn man supervisor nicht mag kann man den Service auch mit systemd, init oder upstart laufen lassen. Macht keinen Unterschied,

      Bitbucket finde ich tatsächlich nicht so schön übersichtlich wie Gitea. Dazu kommt leider noch recht häufig schlechte Performance.

      Antworten
  2. benediktg

    Zu

    if ($scheme !~* ^https ){
    rewrite ^ https://$server_name$request_uri? permanent;
    }
    

    Sowohl das if als auch das rewrite sind hier unnötig. (Siehe auch
    https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
    https://www.nginx.com/blog/converting-apache-to-nginx-rewrite-rules/
    und https://www.nginx.com/blog/creating-nginx-rewrite-rules/)

    Eleganter wäre:

    server {
      listen 80;
      server_name git.example.com;
      location /.well-known/acme-challenge {
        alias /var/www/git.example.com/httpdocs/.well-known/acme-challenge/;
      }
      location / {
        return 301 https://$host$request_uri;
      }
    }
    server {
      listen 443 ssl http2;
      server_name git.example.com;
      location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://127.0.0.1:3000/;
      }
      # und so weiter und so fort
    }
    

    Kurze Erklärung: das if muss sonst bei jedem Request ausgewertet werden – indem man deklarativ separate server-Blöcke schreibt, kann nginx effizienter arbeiten. Und für die Umleitung genügt return 301. ;)

    Antworten
    1. dakira Beitragsautor

      Du hast absolut recht. Der Server auf dem das bei mir läuft ist leider mit Plesk verwaltet. Da lässt sich das nicht so einfach machen. Ist also eher ein Workaround.

      Antworten
  3. ToeiRei

    Ich habe inzwischen meinen Gitlab (VM mit 8 GB RAM) durch Gitea (Docker Container, 5MB RAM) ersetzt und bin echt erstaunt dass das kleine Teil das kann was ich brauche. Kann’s also nur bestätigen wie du so schwärmst,

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.