Reverse Proxy für Gitea konfigurieren

Ein Reverse Proxy liefert eine Ressource, welche er von einem oder mehreren Servern holt, an einen Client aus. Bei Gitea kann es durchaus sinnvoll sein, dieses hinter einem Reverse Proxy zu betreiben. Standardmäßig läuft der Dienst auf dem Port 3000. Möchte der Nutzer ihn über die normalen Ports für HTTP (80) bzw. HTTPS (443) erreichbar machen, könnte das Ganze durchaus über die Konfiguration von Gitea in Verbindung mit der systemd-Unit geschehen.

Allerdings ist ein weiterer Vorteil bei einem Reverse Proxy, das die angefragte Infrastruktur aus der Sicht der Clients versteckt wird. Mittels Nginx kann es solcher Reverse Proxy realisiert werden. Dazu muss die Nginx-Konfiguration für die Domain angepasst werden:

nano /etc/nginx/sites-available/example

In diesem Fall befasst sich die Konfiguration mit der verschlüsselten Kommunikation per HTTPS und der Weiterleitung von unverschlüsselten Verbindung in Richtung der verschlüsselten Verbindung.

server {
  listen 80;
  listen [::]:80;

  server_name example.org;

  return 301 https://$host$request_uri$is_args$args;
}

server {
  listen 443;
  listen [::]:443 default_server;

  ssl on;
  ssl_certificate        /etc/letsencrypt/live/example.org/fullchain.pem;
  ssl_certificate_key    /etc/letsencrypt/live/example.org/privkey.pem;

    server_name org;

    location / {
        proxy_pass http://localhost:3000;
    }
}

Anhand der Konfiguration wird ersichtlich das Gitea auf dem Server unverschlüsselt betrieben werden kann, da die eigentliche Verschlüsselung über HTTPS vom Reverse Proxy, in diesem Fall Nginx, übernommen wird. Nachdem die Konfiguration gespeichert wurde, muss Nginx neugestartet werden:

service nginx restart

Anschließend muss die Gitea-Konfiguration nochmals angepasst werden:

nano /home/git/gitea/custom/conf/app.ini

Dort muss die ROOT_URL nun so definiert werden, wie der Client sie nun sieht. Die ROOT_URL kann von:

ROOT_URL         = https://example.org:3000/

zu:

ROOT_URL         = http://example.org/

geändert werden. Die Werte PROTOCOL, CERT_FILE und KEY_FILE können entfernt werden, da die Verschlüsslung nun von Nginx übernommen wird. Nach der Änderung der Konfiguration muss Gitea ebenfalls neugestartet werden:

service gitea restart

Nachdem die Konfiguration durch geführt wurde, ist Gitea unter zwei URLs erreichbar:

http://example.org:3000/
https://example.org/

Intern läuft Gitea auf dem Port 3000. Damit dieser nicht von außen erreichbar ist, sollte eine entsprechende Firewall-Regel konfiguriert werden.

Gitea installieren

Vor ein paar Jahren schrieb ich eine Anleitung, in der es darum ging Gogs zu installieren. Schon damals hatte sich eine Abspaltung unter dem Namen Gitea herausgelöst, welche einen Community zentrierten Ansatz bei der Entwicklung fuhr. Gitea ist eine vollwertige Lösung, welche einen Git-Server, eine Weboberfläche und weitere Entwicklerwerkzeuge, wie einen Bugtracker und eine Wiki bereitstellt.

Gitea

Zur Installation von Gitea muss im ersten Schritt Git installiert werden:

apt-get install git

Nachdem dies geschehen ist, wird ein Nutzer für Gitea angelegt und in dessen Kontext gewechselt:

adduser --disabled-password --gecos "" git
su git
cd

Nun kann Gitea heruntergeladen werden. Dazu muss der passende Download-Link über die Projektseite ermittelt werden:

wget https://dl.gitea.io/gitea/1.8.3/gitea-1.8.3-linux-amd64

Im Normalfall sollte hierbei die Linux-AMD64-Version genutzt werden. Nach dem Download kann Gitea für den ersten Testlauf gestartet werden:

mkdir gitea
mv gitea-1.8.3-linux-amd64 gitea/gitea
cd gitea
chmod 755 gitea
./gitea

Nach dem Start kann Gitea im Browser unter der URL aufgerufen werden:

http://example.org:3000/

Sobald der erste Testlauf erfolgreich durchgeführt wurde, sollte Gitea wieder beendet werden. Im nächsten Schritt muss die systemd-Unit eingerichtet werden, welche dafür sorgt, dass der Service automatisch gestartet wird. Dazu wird im ersten Schritt die entsprechende Datei angelegt:

nano /etc/systemd/system/gitea.service

Diese Datei wird nun mit folgendem Inhalt befüllt:

[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target
#After=mysqld.service
#After=postgresql.service
#After=memcached.service
#After=redis.service

[Service]
# Modify these two values and uncomment them if you have
# repos with lots of files and get an HTTP error 500 because
# of that
###
#LimitMEMLOCK=infinity
#LimitNOFILE=65535

Type=simple
User=git
Group=git
WorkingDirectory=/home/git/gitea
ExecStart=/home/git/gitea/gitea web
Restart=always
Environment=USER=git HOME=/home/git

# If you want to bind Gitea to a port below 1024 uncomment
# the two values below
###
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
#AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

Nachdem die systemd-Unit angelegt wurde, kann sie aktiviert und gestartet werden:

systemctl enable gitea
systemctl start gitea

Damit wird Gitea automatisch gestartet und läuft als Service im Hintergrund. Im Browser kann Gitea nun aufgerufen werden und installiert werden. Dazu wird der Anmelden-Button in der Weboberfläche gedrückt oder alternativ die URL:

http://example.org:3000/install

aufgerufen. In der Installationsroutine wird unter anderem die Datenbank-Verbindung definiert und es besteht die Möglichkeit einen administrativen Nutzer anzulegen. Für kleinere Installation kann SQLite3 als Datenbank-Backend bedenkenlos genutzt werden.

Sollten Fehler bei der Installation des Services oder bei Gitea aufgetreten sein, so lohnt es sich in das systemd-Log mittels:

systemctl status gitea

hineinzuschauen. Das Gitea-eigenen Logs befindet sich bei dieser Installation unter /home/git/gitea/log/:

/home/git/gitea/log/gitea.log 
/home/git/gitea/log/http.log 
/home/git/gitea/log/xorm.log

Minecraft Server aufsetzen

Das Spielprinzip von Minecraft, welches mittlerweile von Microsoft aufgekauft wurde, lässt sich am besten als LEGO für Erwachsene beschreiben. In einer Welt, die nur aus Blöcken besteht, kann sich der Spieler ausleben und seiner Kreativität freien Lauf lassen.

Vor einigen Jahren schrieb ich einen Artikel, wie ein Minecraft-Server unter Ubuntu aufgesetzt wird. Da der Artikel mittlerweile etwas veraltet ist, wird die Anleitung mit diesem Artikel aktualisiert.

Um einen Minecraft-Server aufzusetzen, muss im ersten Schritt Java mittels:

apt install openjdk-11-jre

installiert werden. Nun kann die Version des installierten Javas mittels des Befehls:

java --version

bestimmt werden. Für die Ausführung von Minecraft wird hierbei Java 7 oder höher benötigt. In der Ausgabe des Befehls finden sich die notwendigen Informationen:

openjdk 11.0.3 2019-04-16
OpenJDK Runtime Environment (build 11.0.3+7-Ubuntu-1ubuntu218.04.1)
OpenJDK 64-Bit Server VM (build 11.0.3+7-Ubuntu-1ubuntu218.04.1, mixed mode, sharing)

Nachdem damit die Grundvoraussetzungen erfüllt sind, wird mittels:

adduser --disabled-login --gecos "" minecraft
su minecraft

ein Nutzer für den Server angelegt und in diesen Nutzer gewechselt. Im Kontext des Nutzer muss nun der Server heruntergeladen werden. Die aktuelle URL des Server ist über die Minecraft-Webseite in Erfahrung zu bringen:

wget https://launcher.mojang.com/v1/objects/d0d0fe2b1dc6ab4c65554cb734270872b72dadd6/server.jar

Nachdem der Server heruntergeladen wurde, kann er für einen ersten Tests gestartet werden:

java -Xmx1024M -Xms1024M -jar server.jar nogui

Beim ersten Start wird folgende Meldung erscheinen:

[13:36:13] [main/ERROR]: Failed to load properties from file: server.properties
[13:36:14] [main/WARN]: Failed to load eula.txt
[13:36:14] [main/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.

Im Home-Verzeichnis des Nutzers findet sich nun eine Datei mit dem Namen eula.txt. Diese Datei muss bearbeitet werden:

nano eula.txt

Der Wert:

eula=false

muss hierbei auf den Wert true gesetzt werden. Anschließend kann die Datei gespeichert werden und der Editor verlassen werden. Nach dem abermaligen Start des Servers mittels:

java -Xmx1024M -Xms1024M -jar server.jar nogui

sollte derselbe nun hochfahren. Nachdem der Server erfolgreich hochgefahren wurde, sollte er wieder beendet werden. Damit der Service automatisch hochfährt, muss eine sogenannte systemd-Unit angelegt werden. Dazu wird der Nutzer minecraft verlassen und die systemd-Unit angelegt:

exit
nano /etc/systemd/system/minecraft.service

Die neu angelegte Datei wird nun mit folgendem Inhalt befüllt:

[Unit]
Description=Minecraft Server
After=network.target

[Service]
Type=simple
WorkingDirectory=/home/minecraft
User=minecraft
Group=minecraft

Restart=always

ExecStart=/usr/bin/screen -DmS minecraft-server java -Xmx4096M -Xms2048M -jar server.jar nogui

ExecStop=/usr/bin/screen -p 0 -S minecraft-server -X eval 'stuff "save-all"15'
ExecStop=/usr/bin/screen -p 0 -S minecraft-server -X eval 'stuff "stop"15'
ExecStop=/bin/sleep 2

[Install]
WantedBy=multi-user.target

Nachdem die Datei gespeichert wurde, kann die systemd-Unit aktiviert werden:

systemctl enable minecraft
systemctl start minecraft

Damit ist der Minecraft-Server eingerichtet und startet automatisch und läuft anschließend im Hintergrund.

Im Home-Verzeichnis des Nutzers minecraft finden sich einige Dateien, welche der Konfiguration des Servers dienen. In der Datei ops.json werden die Operatoren für den Server hinterlegt. Die Datei server.properties enthält die grundlegenden Einstellungen des Servers. Wurde die Option white-list auf den Wert true gesetzt, so können die berechtigten Nutzer in der Datei whitelist.json hinterlegt werden.

Services unter systemd einrichten

Das Init-System systemd ist mittlerweile in vielen Linux-Distributionen angekommen. Auch unter Ubuntu ist es seit Version 15.04 integriert. Ein Vorteil des neuen Systems ist, das Services, im Gegensatz zum alten Init-System, relativ unkompliziert erstellt werden können. Dazu muss eine sogenannte Unit erstellt werden. Bei einer Unit handelt es sich um eine Textdatei mit einer entsprechenden Konfiguration. Neben den Units für die Konfiguration eines Services existieren weitere Unit-Typen wie z.B. die Typen mit der Endung .path oder .network. In diesem Artikel soll es allerdings nur um die Units vom Typ Service gehen.

Die Units liegen in unterschiedlichen Orten im Dateisystem. Die vom System vorinstallierten Units sind im Ordner /lib/systemd/system/ zu finden. Eigene Services werden im Ordner /etc/systemd/system/ hinterlegt. Hier können allerdings nur Nutzer mit administrativen Rechten entsprechende Service hinterlegen. Soll ein nicht privilegierter Nutzer eine Unit angelegen, so muss er diese im Verzeichnis ~/.config/systemd/user/ hinterlegen. In den meisten Fällen werden Units für Services im Dateisystem unter dem Pfad /etc/systemd/system/ angelegt. In diesem Ordner soll nun eine Datei für die Unit angelegt werden:

nano languagetool.service

Beispielhaft könnte eine solche Unit wie folgt aussehen:

[Unit]
Description=LanguageTool
After=syslog.target
After=network.target

[Service]
Type=simple
User=languagetool
Group=languagetool
WorkingDirectory=/home/languagetool/server
ExecStart=/usr/bin/java -cp /home/languagetool/server/languagetool-server.jar org.languagetool.server.HTTPServer --config languagetool.cfg --port 3001 --allow-origin "*"
Restart=always
Environment=USER=git HOME=/home/languagetool

[Install]
WantedBy=multi-user.target

Die Unit unterteilt sich in unterschiedliche Bereiche, in diesem Beispiel sind dies Unit, Service und Install. Der Bereich Service ist hierbei nur in Units vom Typ Service zu finden. Im Bereich Unit sind eine kurze Beschreibung des Services und die Abhängigkeiten der Unit hinterlegt. Dabei wird definiert, welche Systeme bereits gestartet sein müssen, bevor der Service gestartet wird. Ein Target entspricht dabei einer Gruppe von Diensten, meist mit einer bestimmten Bedeutung, wie z.B. das Target für die Herstellung der Netzwerkkonnektivität (network-online.target).

In der Service-Gruppe wird der Typ des Services und der Nutzer und die Gruppe definiert, mit welchem bzw. welcher er starten soll. Daneben wird das Arbeitsverzeichnis und die Kommandozeile zur Ausführung des Services definiert. Weiterhin kann das Verhalten des Service, über den Parameter Restart, weiter definiert werden. So kann angegeben werden, dass der Service nach seiner Beendigung wieder neugestartet wird.

In der Install-Sektion wird angeben, wann der Service gestartet werden soll. Das multi-user.target entspricht dem klassischen Start eines normalen Linux-Systems. Ist die Unit definiert, kann sie aktiviert und der Service gestartet werden:

systemctl enable languagetool
systemctl start languagetool

Die Option enable sorgt dafür das die entsprechende Unit aktiviert wird. Dies führt dazu das sie je nach Konfiguration z.B. automatisch beim Systemstart oder bei dem Anschluss bestimmter Hardware gestartet wird. Unter bestimmten Systemen wie Ubuntu, kann der Service auch über das service-Kommando gestartet werden:

service languagetool start

Neben den Optionen enable und start für systemctl, existieren weitere Optionen zur Steuerung der Units. Dies sind unter anderem stop, zum Stoppen des Services und disable zur Deaktivierung der Unit. Mit der Option status, kann der Status eines Service erfragt werden:

systemctl status languagetool

Anschließend erhält der Nutzer den aktuellen Status des Service. Eine weitere wichtige Option ist restart um einen Service manuell neuzustarten. Mithilfe der systemd-Units lassen sich somit schnell Services in ein Linux-System einbinden.

LanguageTool-Server unter Ubuntu aufsetzen

Für die freie Grammatik- und Rechtschreibprüfung LanguageTool existieren eine Reihe von Add-ons, unter anderem für den Browser Firefox.

Standardmäßig nutzen diese Add-ons den vom Projekt bereitgestellten Server unter languagetool.org. Nicht jeder möchte seine Daten zur Korrektur an Dritte schicken und so besteht die Möglichkeit einen eigenen Server aufzusetzen. Dieser kann lokal betrieben oder auf einem eigenen Server installiert werden. In diesem Artikel soll die Installation unter Ubuntu beschrieben werden. Im ersten Schritt muss sich auf dem Server eingeloggt und dort ein neuer Nutzer angelegt werden:

adduser languagetool
su languagetool
cd

Nachdem der Nutzer angelegt wurde und in das entsprechende Home-Verzeichnis des Nutzers gewechselt wurde, kann das LanguageTool heruntergeladen und entpackt werden:

wget https://languagetool.org/download/LanguageTool-4.5.zip
unzip LanguageTool-4.5.zip
mv LanguageTool-4.5 server
rm LanguageTool-4.5.zip

Neben dem LanguageTool, werden noch sogenannte N-Gramme heruntergeladen. Diese dienen der Verbesserung der Erkennungsleistung des LanguageTool. Sie belegen knapp 27 GiB auf der Festplatte, müssen aber nicht zwingend installiert werden:

mkdir ngrams

wget https://languagetool.org/download/ngram-data/ngrams-de-20150819.zip
wget https://languagetool.org/download/ngram-data/ngrams-en-20150817.zip
wget https://languagetool.org/download/ngram-data/ngrams-es-20150915.zip
wget https://languagetool.org/download/ngram-data/ngrams-fr-20150913.zip
wget https://languagetool.org/download/ngram-data/ngrams-nl-20181229.zip

unzip ngrams-de-20150819.zip
unzip ngrams-en-20150817.zip
unzip ngrams-es-20150915.zip
unzip ngrams-fr-20150913.zip
unzip ngrams-nl-20181229.zip

rm ngrams-de-20150819.zip
rm ngrams-en-20150817.zip
rm ngrams-es-20150915.zip
rm ngrams-fr-20150913.zip
rm ngrams-nl-20181229.zip

Damit ist das LanguageTool installiert. Ein erster Test kann erfolgen, indem der Server mittels:

java -cp languagetool-server.jar org.languagetool.server.HTTPServer --port 8081

gestartet wird. Über Curl können erste Testdaten an den Server gesendet werden:

curl --data "language=en-US&text=a first test" http://localhost:8081/v2/check

In meinem Setup wird der Server auf dem Port 8081 (oder einem beliebigen anderen Port betrieben) und ist über einen Reverse Proxy, in diesem Fall Nginx, erreichbar. Dazu muss die Konfiguration angepasst werden:

nano /etc/nginx/sites-available/example

In der Nginx-Konfigurationsdatei wird nun folgende Konfiguration hinterlegt:

server {
        listen   443 ssl;
        listen [::]:443 ssl;

        ssl_certificate /etc/letsencrypt/live/api.example.org/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/api.example.org/privkey.pem;

        root /var/www/example/api;
        index index.php index.html index.htm;

        server_name api.example.org;

        # proxy for languagetool
        location /languagetool/ {
                proxy_pass http://localhost:8081/v2/;
        }
}

Nachdem die Konfiguration für Nginx hinterlegt wurde, wird Nginx neugestartet:

nginx restart

Über den Browser kann die API nun getestet werden:

https://api.example.org/languagetool/check?language=en-US&text=Wong wong wong

Damit ist die Konfiguration des LanguageTool allerdings noch nicht abgeschlossen. Für den produktiven Betrieb wird eine Konfigurationsdatei unter /home/languagetool/server/ erstellt:

nano languagetool.cfg

Diese Datei wird mit folgendem Inhalt befüllt:

languageModel=/home/languagetool/ngrams

Damit der Service automatisch startet, wird eine systemd-Unit angelegt:

nano /etc/systemd/system/languagetool.service

Diese Datei wird mit folgendem Inhalt befüllt:

[Unit]
Description=LanguageTool
After=syslog.target
After=network.target

[Service]
Type=simple
User=languagetool
Group=languagetool
WorkingDirectory=/home/languagetool/server
ExecStart=/usr/bin/java -cp /home/languagetool/server/languagetool-server.jar org.languagetool.server.HTTPServer --config languagetool.cfg --port 3001 --allow-origin "*"
Restart=always
Environment=USER=git HOME=/home/languagetool

[Install]
WantedBy=multi-user.target

Nachdem die Datei angelegt wurde, wird sie aktiviert und anschließend der Service gestartet:

systemctl enable languagetool
service languagetool start

Zum Test der N-Gramme kann folgende URL aufgerufen:

https://api.example.org/languagetool/check?language=en-US&text=I%20want%20to%20go%20their.

werden. Wenn keine N-Gramme installiert oder konfiguriert sind, kommt ein relativ kurzes JSON als Antwort zurück:

{„software“:{„name“:“LanguageTool“,“version“:“4.5″,“buildDate“:“2019-03-26 11:37″,“apiVersion“:1,“premium“:false,“premiumHint“:“You might be missing errors only the Premium version can find. Contact us at supportlanguagetoolplus.com.“,“status“:““},“warnings“:{„incompleteResults“:false},“language“:{„name“:“English (US)“,“code“:“en-US“,“detectedLanguage“:{„name“:“English (US)“,“code“:“en-US“,“confidence“:0.9999997}},“matches“:[]}

Sind die N-Gramme erfolgreich installiert und konfiguriert, wird das LanguageTool mit einem längeren Response antworten:

{„software“:{„name“:“LanguageTool“,“version“:“4.5″,“buildDate“:“2019-03-26 11:37″,“apiVersion“:1,“premium“:false,“premiumHint“:“You might be missing errors only the Premium version can find. Contact us at supportlanguagetoolplus.com.“,“status“:““},“warnings“:{„incompleteResults“:false},“language“:{„name“:“English (US)“,“code“:“en-US“,“detectedLanguage“:{„name“:“English (US)“,“code“:“en-US“,“confidence“:0.9999997}},“matches“:[{„message“:“Statistics suggests that ‚there‘ (as in ‚Is there an answer?‘) might be the correct word here, not ‚their‘ (as in ‚It’s not their fault.‘). Please check.“,“shortMessage“:““,“replacements“:[{„value“:“there“,“shortDescription“:“as in ‚Is there an answer?'“}],“offset“:13,“length“:5,“context“:{„text“:“I want to go their.“,“offset“:13,“length“:5},“sentence“:“I want to go their.“,“type“:{„typeName“:“Other“},“rule“:{„id“:“CONFUSION_RULE“,“description“:“Statistically detect wrong use of words that are easily confused“,“issueType“:“non-conformance“,“category“:{„id“:“TYPOS“,“name“:“Possible Typo“}},“ignoreForIncompleteSentence“:false,“contextForSureMatch“:3}]}

Damit ist der Server komplett eingerichtet. Nun kann der eigene Server bei entsprechenden Add-ons eingerichtet und genutzt werden.

Nachdem der Server aufgesetzt wurde, können entsprechende Add-ons umgestellt werden

Das gleiche Setup kann natürlich genutzt werden, einen solchen Server lokal auf dem eigenen Ubuntu-Rechner zu installieren.