<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.hostsharing.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tim00</id>
	<title>Hostsharing Wiki - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.hostsharing.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tim00"/>
	<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Spezial:Beitr%C3%A4ge/Tim00"/>
	<updated>2026-09-11T00:16:33Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Container&amp;diff=7649</id>
		<title>Container</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Container&amp;diff=7649"/>
		<updated>2026-09-10T14:33:25Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* OnlyOffice Documentserver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Übersicht ==&lt;br /&gt;
&lt;br /&gt;
Es gibt die Möglichkeit, einen Container Server mit Docker oder mit Podman zu buchen.&lt;br /&gt;
&lt;br /&gt;
Dies ist eine Managed Umgebung, also ohne Root-Rechte, wo Docker bzw. Podman rootless ausgeführt werden.&lt;br /&gt;
&lt;br /&gt;
Falls vom Installationsskript einer Anwendung Root-Rechte erforderlich sind, kann entweder versucht werden, dies anzupassen, oder es kann ein Cloud Server gebucht werden, wo der Benutzer Root-Rechte hat.&lt;br /&gt;
&lt;br /&gt;
== Erste Schritte ==&lt;br /&gt;
&lt;br /&gt;
Bei der Bestellung des Container Servers sollte direkt der Public SSH Key mitgegeben werden, am besten bereits nach dem Ed25519-Standard, siehe auch [https://www.heise.de/tipps-tricks/SSH-Key-erstellen-so-geht-s-4400280.html].&lt;br /&gt;
&lt;br /&gt;
Der Zugriff erfolgt über den Benutzer tallyman über SSH auf den Container Server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
ssh tallyman@vm4xxx.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um einen &amp;quot;Hello World&amp;quot; Docker Container zu starten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
tallyman@vm4xxx:~$ docker run hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend sieht der Befehl für Podman aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
tallyman@vm4xxx:~$ podman run hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfreiche Befehle für Docker ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
# in einem Ordner ausführen, wo eine Datei mit dem Namen docker-compose.yml liegt, um die Umgebung zu bauen und zu starten:&lt;br /&gt;
docker compose up --detach&lt;br /&gt;
&lt;br /&gt;
# zeige alle laufenden Container&lt;br /&gt;
docker ps -a&lt;br /&gt;
&lt;br /&gt;
# zeige die Logs eines Containers&lt;br /&gt;
docker logs mein-container&lt;br /&gt;
&lt;br /&gt;
# wechsle in eine Shell im Container&lt;br /&gt;
docker exec -t -i mein-container /bin/sh&lt;br /&gt;
&lt;br /&gt;
# Images aktualisieren&lt;br /&gt;
docker compose pull&lt;br /&gt;
&lt;br /&gt;
# Containerumgebung stoppen und löschen&lt;br /&gt;
docker compose down&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfreiche Befehle für Podman ===&lt;br /&gt;
&lt;br /&gt;
Viele Befehle sind ähnlich wie bei Docker.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
# in einem Ordner ausführen, wo eine Datei mit dem Namen compose.yaml liegt, um die Umgebung zu bauen und zu starten:&lt;br /&gt;
podman-compose up -d&lt;br /&gt;
&lt;br /&gt;
# zeige alle laufenden Container&lt;br /&gt;
podman ps -a&lt;br /&gt;
&lt;br /&gt;
# zeige die Logs eines Containers&lt;br /&gt;
podman logs mein-container&lt;br /&gt;
&lt;br /&gt;
# wechsle in eine Shell im Container&lt;br /&gt;
podman exec -t -i mein-container /bin/sh&lt;br /&gt;
&lt;br /&gt;
# Images aktualisieren&lt;br /&gt;
podman-compose pull&lt;br /&gt;
&lt;br /&gt;
# Containerumgebung stoppen und löschen&lt;br /&gt;
docker-compose down&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist aber zu empfehlen, nicht mit compose zu arbeiten, sondern mit Quadlets. Dabei sind die Container direkt in systemd Userspace eingebettet, und werden mit den richtigen Abhängigkeiten definiert und dann auch bei einem Reboot gestartet.&lt;br /&gt;
&lt;br /&gt;
Siehe auch die Beispiele unten.&lt;br /&gt;
&lt;br /&gt;
Es müssen die container und network Dateien in ~/.config/containers/systemd hinterlegt werden, und dann können die Service Dateien erzeugt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
# eigentlich müsste dieser Befehl die service Dateien in ~/.config/systemd/user/ neu erzeugen, aber es geht irgendwie nicht.&lt;br /&gt;
systemctl --user daemon-reload&lt;br /&gt;
&lt;br /&gt;
# manuell:&lt;br /&gt;
/usr/lib/systemd/system-generators/podman-system-generator --user ~/.config/systemd/user&lt;br /&gt;
systemctl --user daemon-reload&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Integration in Hostsharing Managed Platform ==&lt;br /&gt;
&lt;br /&gt;
=== Subdomain einrichten ===&lt;br /&gt;
&lt;br /&gt;
Wir haben bereits die Hauptdomain bei Hostsharing gebucht.&lt;br /&gt;
&lt;br /&gt;
Nun soll unsere Anwendung auf dem Container Server auf einer Subdomain laufen.&lt;br /&gt;
&lt;br /&gt;
Wir benutzen einen Caddy Container, um Letsencrypt bereitszustellen (siehe in den Beispielen unten).&lt;br /&gt;
&lt;br /&gt;
Auf der Managed Umgebung müssen wir das Zonefile anpassen, um die Subdomain per A und AAAA Eintrag auf den Container Server zu verweisen.&lt;br /&gt;
&lt;br /&gt;
Mit dem Befehl &amp;lt;code&amp;gt;dig&amp;lt;/code&amp;gt; ermitteln wir die ipv4 und ipv6 Adressen unseres Container Servers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
dig -t A +short vm4xxx.hostsharing.net&lt;br /&gt;
dig -t AAAA +short vm4xxx.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf der Managed Umgebung, legen wir ein Zonefile an. Siehe auch die Anleitung im Handbuch: https://www.hostsharing.net/doc/managed-operations-platform/zonefile/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doms/meinedomain.de/etc/pri.meinedomain.de&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
{DEFAULT_ZONEFILE}&lt;br /&gt;
&lt;br /&gt;
meinesubdomain      IN A       83.223.xx.xxx&lt;br /&gt;
meinesubdomain      IN AAAA    2a01:xx:xxxx::xxxx:xxxx:0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tunnel zur Managed Datenbank einrichten ===&lt;br /&gt;
&lt;br /&gt;
Wir lassen die Anwendung auf dem Container Server laufen. Dort kann natürlich auch die Datenbank laufen, in einem eigenen Container.&lt;br /&gt;
&lt;br /&gt;
Wir haben aber auch Datenbanken in der Managed Umgebung von Hostsharing, mit allen Vorteilen (regelmäßiges Backup, usw.).&lt;br /&gt;
&lt;br /&gt;
Wenn wir eine managed Datenbank aus der Managed Umgebung auf dem Container Server einbinden wollen, sind folgende Schritte notwendig:&lt;br /&gt;
&lt;br /&gt;
* Es muss ein Tunnel eingerichtet werden, damit die Datenbank vom Container Server aus erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
Datei .config/systemd/user/sshtunnel.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=SSH Tunnel zu Managed Webspace&lt;br /&gt;
After=network.target&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Environment=&amp;quot;LOCAL_ADDR=localhost&amp;quot;&lt;br /&gt;
Environment=&amp;quot;LOCAL_PORT=5432&amp;quot;&lt;br /&gt;
Environment=&amp;quot;REMOTE_PORT=5432&amp;quot;&lt;br /&gt;
Environment=&amp;quot;TARGET=xyz00-myuser@xyz00.hostsharing.net&amp;quot;&lt;br /&gt;
ExecStart=/usr/bin/ssh -NT -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L ${LOCAL_ADDR}:${LOCAL_PORT}:localhost:${REMOTE_PORT} ${TARGET}&lt;br /&gt;
&lt;br /&gt;
RestartSec=5&lt;br /&gt;
Restart=always&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=multi-user.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Dienst entsprechend starten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user enable sshtunnel --now&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* TODO: Anpassungen an Docker Compose. Beispiel&lt;br /&gt;
&lt;br /&gt;
== Docker fernsteuern ==&lt;br /&gt;
Es besteht die Möglichkeit, über SSH den Docker Socket von außen zu erreichen. Damit wird es möglich, über eine IDE wie z.B. Intellij IDEA die Docker Container zu starten und zu stoppen.&lt;br /&gt;
&lt;br /&gt;
Um das auszuprobieren, können diese Befehle ausgeführt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -nNT -L $(pwd)/docker.sock:/var/run/docker.sock tallyman@vmxxxx.hostsharing.net&lt;br /&gt;
export DOCKER_HOST=unix://$(pwd)/docker.sock&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun sollten die aktuell laufenden Container gelistet werden.&lt;br /&gt;
&lt;br /&gt;
== Beispiel Anwendungen ==&lt;br /&gt;
=== Container Umgebung mit Nginx und Certbot ===&lt;br /&gt;
TODO siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/nginx-certbot&lt;br /&gt;
=== Container Umgebung mit Caddy und Python Anwendung ===&lt;br /&gt;
TODO siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/caddy-test&lt;br /&gt;
&lt;br /&gt;
=== Nextcloud High Performance Backend mit Caddy ===&lt;br /&gt;
* Docker Compose: siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/nextcloud-high_performance_backend&lt;br /&gt;
* Siehe auch dort die [https://codeberg.org/tpokorra/hs.compose/src/branch/main/nextcloud-high_performance_backend#readme README Datei], was für die Einrichtung erforderlich ist.&lt;br /&gt;
&lt;br /&gt;
=== OnlyOffice Documentserver ===&lt;br /&gt;
TODO siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/onlyoffice-document_server&lt;br /&gt;
&lt;br /&gt;
=== Caddy und Uptime-Kuma mit Quadlets für Podman ===&lt;br /&gt;
&lt;br /&gt;
* siehe https://codeberg.org/tpokorra/hs.quadlet.caddy&lt;br /&gt;
* siehe https://codeberg.org/tpokorra/hs.quadlet.uptimekuma&lt;br /&gt;
&lt;br /&gt;
In den Beispielen sind Makefiles enthalten, an denen ersichtlich wird, welche Verzeichnisse angelegt werden müssen, und welche Dateien wohin kopiert werden müssen.&lt;br /&gt;
&lt;br /&gt;
== Backups in Volumes einpflegen ==&lt;br /&gt;
&lt;br /&gt;
Auf Anfrage stellen wir einen read-only Snapshot bereit, der unter anderem Docker-Volumes, Container und Compose-Dateien enthält. &lt;br /&gt;
&lt;br /&gt;
Da Docker nicht direkt mit den User- und Gruppen-IDs des tallyman-Users arbeitet, sondern interne Sub-User- und Sub-Group-IDs verwendet, können diese Daten nicht unmittelbar zurückkopiert werden. Für die Wiederherstellung ist daher ein kurzer Zwischenschritt erforderlich.&lt;br /&gt;
&lt;br /&gt;
Hinweis: selbstverständlich helfen wir auf Anfrage auch dabei, die Dateien wieder in das laufende System zu migrieren.&lt;br /&gt;
&lt;br /&gt;
=== Beispiel: das pgdata Verzeichnis eines PostgreSQL Containers tauschen ===&lt;br /&gt;
&lt;br /&gt;
==== Wo liegt das Volume auf dem Dateisystem? ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
docker ps -a # wie lautet der Containername?&lt;br /&gt;
docker inspect --format &#039;{{ range .Mounts }}{{ if eq .Type &amp;quot;volume&amp;quot; }}{{ .Source }}{{ &amp;quot;\n&amp;quot; }}{{ end }}{{ end }}&#039; postgres-1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In unserem Fall sehen wir den Pfad: &amp;lt;code&amp;gt;/home/tallyman/.local/share/docker/volumes/8c73a862eaf1fc3dee55a2f29b6f3d3dd68e3049da58a21a5f73010e7233190c/_data&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Den betroffenen Container abschalten ====&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel entscheiden wir uns dafür, die Container vollständig zu stoppen.&lt;br /&gt;
Der Grund dafür ist, dass es je nach Image nicht immer eindeutig ist, wie der darin laufende Prozess korrekt gestoppt und wieder gestartet werden sollte.&lt;br /&gt;
&lt;br /&gt;
Alternativ könnten wir das Backup also auch direkt in das Volume kopieren und im bestehenden Container eine Shell öffnen, um die Dateien an die richtige Stelle zu verschieben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
docker ps -a # wie lautet der Containername?&lt;br /&gt;
docker stop app-1&lt;br /&gt;
docker stop postgres-1&lt;br /&gt;
&lt;br /&gt;
# oder über die Service-Namen aus der compose.yaml&lt;br /&gt;
docker compose stop app &lt;br /&gt;
docker compose stop postgres &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== In eine temporäre Subshell wechseln ====&lt;br /&gt;
Hier nutzen wir eine Abkürzung und lassen Docker einen temporären Container starten, der unseren Ordner als Volume einbindet.&lt;br /&gt;
So erhalten wir eine Shell im passenden Userid/Gruppenid-Kontext und können direkt mit den Dateien im Volume arbeiten, ohne den eigentlichen Service-Container starten, oder als root arbeiten zu müssen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
export VOL=&amp;quot;.local/share/docker/volumes&amp;quot;&lt;br /&gt;
docker run --rm -it -v &amp;quot;$VOL:/data&amp;quot; bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir wechseln nun in das oben definierte Volume. Das Beispiel geht davon aus, dass das bereitgestellte Backupverzeichnis &amp;quot;pgdata2&amp;quot; genannt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
cd data&lt;br /&gt;
mv pgdata pgdata.old&lt;br /&gt;
mv pgdata2 pgdata&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Falls wir zusätzliche Pakete brauchen, nutzt das – auf Alpine basierte – Bash image den Paketmanager `apk`. Beispiel: ncdu installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
~$ apk add ncdu&lt;br /&gt;
(1/1) Installing ncdu (1.22-r0)&lt;br /&gt;
Executing busybox-1.37.0-r30.trigger&lt;br /&gt;
OK: 8726 KiB in 20 packages&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Den Container wieder starten ====&lt;br /&gt;
&lt;br /&gt;
Wir verlassen den Container mittels &amp;lt;code&amp;gt;exit&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; oder über die Tastenkombination &amp;lt;code&amp;gt;STRG+D&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
docker start postgres-1&lt;br /&gt;
docker start app-1&lt;br /&gt;
&lt;br /&gt;
# oder über die Service-Namen aus der compose.yaml&lt;br /&gt;
docker compose start app &lt;br /&gt;
docker compose start postgres &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiel: eine Subshell mit Hilfe eine Containerprozesses starten ===&lt;br /&gt;
Für Debugging kann es nützlich sein, direkt mit allen vorinstallierten Tools im Containerserver mit Daten der Volumes zu agieren. Hier sind zwei Wege um eine Subshell ohne extra(!) Container zu starten:&lt;br /&gt;
&lt;br /&gt;
==== Mit Hilfe eines beliebigen laufenden Containers: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
docker ps&lt;br /&gt;
docker inspect --format &#039;{{.State.Pid}}&#039; app-1&lt;br /&gt;
nsenter -U -t 2586740 -- bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== TODO ====&lt;br /&gt;
Funktionierende subshell (mit nötigen Berechtigungen) mittels unshare oder nsenter&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Container&amp;diff=7648</id>
		<title>Container</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Container&amp;diff=7648"/>
		<updated>2026-09-10T14:29:01Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Hilfreiche Befehle für Podman */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Übersicht ==&lt;br /&gt;
&lt;br /&gt;
Es gibt die Möglichkeit, einen Container Server mit Docker oder mit Podman zu buchen.&lt;br /&gt;
&lt;br /&gt;
Dies ist eine Managed Umgebung, also ohne Root-Rechte, wo Docker bzw. Podman rootless ausgeführt werden.&lt;br /&gt;
&lt;br /&gt;
Falls vom Installationsskript einer Anwendung Root-Rechte erforderlich sind, kann entweder versucht werden, dies anzupassen, oder es kann ein Cloud Server gebucht werden, wo der Benutzer Root-Rechte hat.&lt;br /&gt;
&lt;br /&gt;
== Erste Schritte ==&lt;br /&gt;
&lt;br /&gt;
Bei der Bestellung des Container Servers sollte direkt der Public SSH Key mitgegeben werden, am besten bereits nach dem Ed25519-Standard, siehe auch [https://www.heise.de/tipps-tricks/SSH-Key-erstellen-so-geht-s-4400280.html].&lt;br /&gt;
&lt;br /&gt;
Der Zugriff erfolgt über den Benutzer tallyman über SSH auf den Container Server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
ssh tallyman@vm4xxx.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um einen &amp;quot;Hello World&amp;quot; Docker Container zu starten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
tallyman@vm4xxx:~$ docker run hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend sieht der Befehl für Podman aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
tallyman@vm4xxx:~$ podman run hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfreiche Befehle für Docker ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
# in einem Ordner ausführen, wo eine Datei mit dem Namen docker-compose.yml liegt, um die Umgebung zu bauen und zu starten:&lt;br /&gt;
docker compose up --detach&lt;br /&gt;
&lt;br /&gt;
# zeige alle laufenden Container&lt;br /&gt;
docker ps -a&lt;br /&gt;
&lt;br /&gt;
# zeige die Logs eines Containers&lt;br /&gt;
docker logs mein-container&lt;br /&gt;
&lt;br /&gt;
# wechsle in eine Shell im Container&lt;br /&gt;
docker exec -t -i mein-container /bin/sh&lt;br /&gt;
&lt;br /&gt;
# Images aktualisieren&lt;br /&gt;
docker compose pull&lt;br /&gt;
&lt;br /&gt;
# Containerumgebung stoppen und löschen&lt;br /&gt;
docker compose down&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfreiche Befehle für Podman ===&lt;br /&gt;
&lt;br /&gt;
Viele Befehle sind ähnlich wie bei Docker.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
# in einem Ordner ausführen, wo eine Datei mit dem Namen compose.yaml liegt, um die Umgebung zu bauen und zu starten:&lt;br /&gt;
podman-compose up -d&lt;br /&gt;
&lt;br /&gt;
# zeige alle laufenden Container&lt;br /&gt;
podman ps -a&lt;br /&gt;
&lt;br /&gt;
# zeige die Logs eines Containers&lt;br /&gt;
podman logs mein-container&lt;br /&gt;
&lt;br /&gt;
# wechsle in eine Shell im Container&lt;br /&gt;
podman exec -t -i mein-container /bin/sh&lt;br /&gt;
&lt;br /&gt;
# Images aktualisieren&lt;br /&gt;
podman-compose pull&lt;br /&gt;
&lt;br /&gt;
# Containerumgebung stoppen und löschen&lt;br /&gt;
docker-compose down&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist aber zu empfehlen, nicht mit compose zu arbeiten, sondern mit Quadlets. Dabei sind die Container direkt in systemd Userspace eingebettet, und werden mit den richtigen Abhängigkeiten definiert und dann auch bei einem Reboot gestartet.&lt;br /&gt;
&lt;br /&gt;
Siehe auch die Beispiele unten.&lt;br /&gt;
&lt;br /&gt;
Es müssen die container und network Dateien in ~/.config/containers/systemd hinterlegt werden, und dann können die Service Dateien erzeugt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
# eigentlich müsste dieser Befehl die service Dateien in ~/.config/systemd/user/ neu erzeugen, aber es geht irgendwie nicht.&lt;br /&gt;
systemctl --user daemon-reload&lt;br /&gt;
&lt;br /&gt;
# manuell:&lt;br /&gt;
/usr/lib/systemd/system-generators/podman-system-generator --user ~/.config/systemd/user&lt;br /&gt;
systemctl --user daemon-reload&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Integration in Hostsharing Managed Platform ==&lt;br /&gt;
&lt;br /&gt;
=== Subdomain einrichten ===&lt;br /&gt;
&lt;br /&gt;
Wir haben bereits die Hauptdomain bei Hostsharing gebucht.&lt;br /&gt;
&lt;br /&gt;
Nun soll unsere Anwendung auf dem Container Server auf einer Subdomain laufen.&lt;br /&gt;
&lt;br /&gt;
Wir benutzen einen Caddy Container, um Letsencrypt bereitszustellen (siehe in den Beispielen unten).&lt;br /&gt;
&lt;br /&gt;
Auf der Managed Umgebung müssen wir das Zonefile anpassen, um die Subdomain per A und AAAA Eintrag auf den Container Server zu verweisen.&lt;br /&gt;
&lt;br /&gt;
Mit dem Befehl &amp;lt;code&amp;gt;dig&amp;lt;/code&amp;gt; ermitteln wir die ipv4 und ipv6 Adressen unseres Container Servers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
dig -t A +short vm4xxx.hostsharing.net&lt;br /&gt;
dig -t AAAA +short vm4xxx.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf der Managed Umgebung, legen wir ein Zonefile an. Siehe auch die Anleitung im Handbuch: https://www.hostsharing.net/doc/managed-operations-platform/zonefile/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doms/meinedomain.de/etc/pri.meinedomain.de&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
{DEFAULT_ZONEFILE}&lt;br /&gt;
&lt;br /&gt;
meinesubdomain      IN A       83.223.xx.xxx&lt;br /&gt;
meinesubdomain      IN AAAA    2a01:xx:xxxx::xxxx:xxxx:0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tunnel zur Managed Datenbank einrichten ===&lt;br /&gt;
&lt;br /&gt;
Wir lassen die Anwendung auf dem Container Server laufen. Dort kann natürlich auch die Datenbank laufen, in einem eigenen Container.&lt;br /&gt;
&lt;br /&gt;
Wir haben aber auch Datenbanken in der Managed Umgebung von Hostsharing, mit allen Vorteilen (regelmäßiges Backup, usw.).&lt;br /&gt;
&lt;br /&gt;
Wenn wir eine managed Datenbank aus der Managed Umgebung auf dem Container Server einbinden wollen, sind folgende Schritte notwendig:&lt;br /&gt;
&lt;br /&gt;
* Es muss ein Tunnel eingerichtet werden, damit die Datenbank vom Container Server aus erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
Datei .config/systemd/user/sshtunnel.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=SSH Tunnel zu Managed Webspace&lt;br /&gt;
After=network.target&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Environment=&amp;quot;LOCAL_ADDR=localhost&amp;quot;&lt;br /&gt;
Environment=&amp;quot;LOCAL_PORT=5432&amp;quot;&lt;br /&gt;
Environment=&amp;quot;REMOTE_PORT=5432&amp;quot;&lt;br /&gt;
Environment=&amp;quot;TARGET=xyz00-myuser@xyz00.hostsharing.net&amp;quot;&lt;br /&gt;
ExecStart=/usr/bin/ssh -NT -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L ${LOCAL_ADDR}:${LOCAL_PORT}:localhost:${REMOTE_PORT} ${TARGET}&lt;br /&gt;
&lt;br /&gt;
RestartSec=5&lt;br /&gt;
Restart=always&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=multi-user.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Dienst entsprechend starten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user enable sshtunnel --now&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* TODO: Anpassungen an Docker Compose. Beispiel&lt;br /&gt;
&lt;br /&gt;
== Docker fernsteuern ==&lt;br /&gt;
Es besteht die Möglichkeit, über SSH den Docker Socket von außen zu erreichen. Damit wird es möglich, über eine IDE wie z.B. Intellij IDEA die Docker Container zu starten und zu stoppen.&lt;br /&gt;
&lt;br /&gt;
Um das auszuprobieren, können diese Befehle ausgeführt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -nNT -L $(pwd)/docker.sock:/var/run/docker.sock tallyman@vmxxxx.hostsharing.net&lt;br /&gt;
export DOCKER_HOST=unix://$(pwd)/docker.sock&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun sollten die aktuell laufenden Container gelistet werden.&lt;br /&gt;
&lt;br /&gt;
== Beispiel Anwendungen ==&lt;br /&gt;
=== Container Umgebung mit Nginx und Certbot ===&lt;br /&gt;
TODO siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/nginx-certbot&lt;br /&gt;
=== Container Umgebung mit Caddy und Python Anwendung ===&lt;br /&gt;
TODO siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/caddy-test&lt;br /&gt;
&lt;br /&gt;
=== Nextcloud High Performance Backend mit Caddy ===&lt;br /&gt;
* Docker Compose: siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/nextcloud-high_performance_backend&lt;br /&gt;
* Siehe auch dort die [https://codeberg.org/tpokorra/hs.compose/src/branch/main/nextcloud-high_performance_backend#readme README Datei], was für die Einrichtung erforderlich ist.&lt;br /&gt;
&lt;br /&gt;
=== OnlyOffice Documentserver ===&lt;br /&gt;
TODO siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/onlyoffice-document_server&lt;br /&gt;
&lt;br /&gt;
== Backups in Volumes einpflegen ==&lt;br /&gt;
&lt;br /&gt;
Auf Anfrage stellen wir einen read-only Snapshot bereit, der unter anderem Docker-Volumes, Container und Compose-Dateien enthält. &lt;br /&gt;
&lt;br /&gt;
Da Docker nicht direkt mit den User- und Gruppen-IDs des tallyman-Users arbeitet, sondern interne Sub-User- und Sub-Group-IDs verwendet, können diese Daten nicht unmittelbar zurückkopiert werden. Für die Wiederherstellung ist daher ein kurzer Zwischenschritt erforderlich.&lt;br /&gt;
&lt;br /&gt;
Hinweis: selbstverständlich helfen wir auf Anfrage auch dabei, die Dateien wieder in das laufende System zu migrieren.&lt;br /&gt;
&lt;br /&gt;
=== Beispiel: das pgdata Verzeichnis eines PostgreSQL Containers tauschen ===&lt;br /&gt;
&lt;br /&gt;
==== Wo liegt das Volume auf dem Dateisystem? ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
docker ps -a # wie lautet der Containername?&lt;br /&gt;
docker inspect --format &#039;{{ range .Mounts }}{{ if eq .Type &amp;quot;volume&amp;quot; }}{{ .Source }}{{ &amp;quot;\n&amp;quot; }}{{ end }}{{ end }}&#039; postgres-1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In unserem Fall sehen wir den Pfad: &amp;lt;code&amp;gt;/home/tallyman/.local/share/docker/volumes/8c73a862eaf1fc3dee55a2f29b6f3d3dd68e3049da58a21a5f73010e7233190c/_data&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Den betroffenen Container abschalten ====&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel entscheiden wir uns dafür, die Container vollständig zu stoppen.&lt;br /&gt;
Der Grund dafür ist, dass es je nach Image nicht immer eindeutig ist, wie der darin laufende Prozess korrekt gestoppt und wieder gestartet werden sollte.&lt;br /&gt;
&lt;br /&gt;
Alternativ könnten wir das Backup also auch direkt in das Volume kopieren und im bestehenden Container eine Shell öffnen, um die Dateien an die richtige Stelle zu verschieben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
docker ps -a # wie lautet der Containername?&lt;br /&gt;
docker stop app-1&lt;br /&gt;
docker stop postgres-1&lt;br /&gt;
&lt;br /&gt;
# oder über die Service-Namen aus der compose.yaml&lt;br /&gt;
docker compose stop app &lt;br /&gt;
docker compose stop postgres &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== In eine temporäre Subshell wechseln ====&lt;br /&gt;
Hier nutzen wir eine Abkürzung und lassen Docker einen temporären Container starten, der unseren Ordner als Volume einbindet.&lt;br /&gt;
So erhalten wir eine Shell im passenden Userid/Gruppenid-Kontext und können direkt mit den Dateien im Volume arbeiten, ohne den eigentlichen Service-Container starten, oder als root arbeiten zu müssen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
export VOL=&amp;quot;.local/share/docker/volumes&amp;quot;&lt;br /&gt;
docker run --rm -it -v &amp;quot;$VOL:/data&amp;quot; bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir wechseln nun in das oben definierte Volume. Das Beispiel geht davon aus, dass das bereitgestellte Backupverzeichnis &amp;quot;pgdata2&amp;quot; genannt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
cd data&lt;br /&gt;
mv pgdata pgdata.old&lt;br /&gt;
mv pgdata2 pgdata&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Falls wir zusätzliche Pakete brauchen, nutzt das – auf Alpine basierte – Bash image den Paketmanager `apk`. Beispiel: ncdu installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
~$ apk add ncdu&lt;br /&gt;
(1/1) Installing ncdu (1.22-r0)&lt;br /&gt;
Executing busybox-1.37.0-r30.trigger&lt;br /&gt;
OK: 8726 KiB in 20 packages&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Den Container wieder starten ====&lt;br /&gt;
&lt;br /&gt;
Wir verlassen den Container mittels &amp;lt;code&amp;gt;exit&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; oder über die Tastenkombination &amp;lt;code&amp;gt;STRG+D&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
docker start postgres-1&lt;br /&gt;
docker start app-1&lt;br /&gt;
&lt;br /&gt;
# oder über die Service-Namen aus der compose.yaml&lt;br /&gt;
docker compose start app &lt;br /&gt;
docker compose start postgres &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiel: eine Subshell mit Hilfe eine Containerprozesses starten ===&lt;br /&gt;
Für Debugging kann es nützlich sein, direkt mit allen vorinstallierten Tools im Containerserver mit Daten der Volumes zu agieren. Hier sind zwei Wege um eine Subshell ohne extra(!) Container zu starten:&lt;br /&gt;
&lt;br /&gt;
==== Mit Hilfe eines beliebigen laufenden Containers: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
docker ps&lt;br /&gt;
docker inspect --format &#039;{{.State.Pid}}&#039; app-1&lt;br /&gt;
nsenter -U -t 2586740 -- bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== TODO ====&lt;br /&gt;
Funktionierende subshell (mit nötigen Berechtigungen) mittels unshare oder nsenter&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7647</id>
		<title>Discourse installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7647"/>
		<updated>2026-09-10T05:04:54Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Am Beispiel von 2026.1.7 auf 2026.7.2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Textkasten|gelb|Für Managed Server|Ein funktionierender Discourse-Server erfordert mehrere laufende Server-Dienste. Für den Betrieb ist ein Managed Server sinnvoll.}}&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|rot|Support von der Discourse-Community|Die Discourse-Entwickler haben sich entschieden, nur eine mehr oder weniger genormte Installationsmethode (via docker) zu unterstützen. Dies ist so auf der hostsharing-Architektur aufgrund mehrerer Bedenken und Überlegungen nicht möglich. Die Community ist durchaus hilfreich, geht aber davon aus, dass quasi alle Nutzer* eine &amp;quot;supported&amp;quot;e Installation durchgeführt haben. Wenn man in entsprechenden Kanälen nach Hilfe fragt, sollte man unbedingt erwähnen, dass man discourse selber anhand dieser hier lesbaren Anleitung installiert hat, um bereits entsprechenden Kommentaren und Nachfragen vorzugreifen.}}&lt;br /&gt;
&lt;br /&gt;
== Über ==&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel wird die Installation von discourse, Version 2.1.0 (September 2018) beschrieben.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von HSAdmin wird angelegt:&lt;br /&gt;
# Ein User als Service-User mit &#039;&#039;/bin/bash&#039;&#039; als Shell, zum Beispiel Beispiel: &#039;&#039;xyz00-discourse&#039;&#039;&lt;br /&gt;
# Eine Domain mit &#039;&#039;xyz00-discourse&#039; als Domain-Administrator, zum Beispiel &#039;&#039;beispiel.discussion&#039;&#039;&lt;br /&gt;
# Einen Postgresql-User &#039;&#039;xyz00_discourseuser&#039;&#039; mit Passwort &#039;&#039;meinPasswort&#039;&#039;&lt;br /&gt;
# Eine Postgresql-Datenbank &#039;&#039;xyz00_discoursedb&#039;&#039; mit Datenbank-Owner &#039;&#039;xyz00_discourseuser&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verwendete IP-Ports der Server-Dienste:&lt;br /&gt;
# Redis: localhost:32002&lt;br /&gt;
# Discourse-Web: localhost:13000&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der PostgreSQL Datenbank ==&lt;br /&gt;
&lt;br /&gt;
Es müssen noch Erweiterungen für Postgresql installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA public;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration des Redis Server ==&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gelb|Firewall/Redis Port|Leider unterstützt discourse nicht die Kommunikation mit Redis über Unix-Sockets. Dementsprechend muss der für Redis konfigurierte Port von dem hostsharing-Support in der Firewall freigegeben werden.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd&lt;br /&gt;
mkdir redis/etc redis/lib redis/log redis/run&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/redis/etc/redis.conf&#039;&#039; mit folgendem Inhalt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
daemonize no&lt;br /&gt;
pidfile /home/pacs/xyz00/users/discourse/redis/run/redis-server.pid&lt;br /&gt;
port 32002&lt;br /&gt;
tcp-backlog 128&lt;br /&gt;
bind 127.0.0.1&lt;br /&gt;
timeout 300&lt;br /&gt;
loglevel notice&lt;br /&gt;
logfile /home/pacs/xyz00/users/discourse/redis/log/redis.log&lt;br /&gt;
databases 16&lt;br /&gt;
save 900 1&lt;br /&gt;
save 300 10&lt;br /&gt;
save 60 10000&lt;br /&gt;
slave-serve-stale-data yes&lt;br /&gt;
appendonly no&lt;br /&gt;
dbfilename dump.rdb&lt;br /&gt;
dir /home/pacs/xyz00/users/discourse/redis/lib&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für Discourse 3.x gilt: &amp;quot;Discourse requires Redis 6.2.0 or up&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Für Debian Buster und Bullseye ist daher das Installieren eines neueren Binaries erforderlich. Bei Debian Bookwork ist bereits Redis 7.0 enthalten (siehe https://packages.debian.org/search?keywords=redis-server).&lt;br /&gt;
&lt;br /&gt;
Hier steht ein entsprechendes Binary für Debian Buster zur Verfügung, das mit dem Public Key von Timotheus geprüft werden kann:&lt;br /&gt;
&lt;br /&gt;
* https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
* Prüfsignatur: https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz.sig&lt;br /&gt;
&lt;br /&gt;
Prüfen der Signatur:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gpg --verify redis-server-6.2.12-debian-buster.tar.gz.sig redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Binary muss nach &amp;lt;code&amp;gt;$HOME/bin&amp;lt;/code&amp;gt; verschoben werden, und entsprechend beim Starten des Dienstes eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
== Installation von Ruby ==&lt;br /&gt;
&lt;br /&gt;
Als User &#039;&#039;xyz00-discourse&#039;&#039;:  Installation von Ruby mit &#039;&#039;rbenv&#039;&#039; mit folgenden Befehlen:&lt;br /&gt;
&lt;br /&gt;
Zunächst &#039;&#039;rbenv&#039;&#039; and &#039;&#039;ruby-build&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/rbenv.git ~/.rbenv&lt;br /&gt;
cd ~/.rbenv &amp;amp;&amp;amp; src/configure &amp;amp;&amp;amp; make -C src&lt;br /&gt;
echo &#039;export PATH=&amp;quot;$HOME/.rbenv/bin:$PATH&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
echo &#039;eval &amp;quot;$(rbenv init -)&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
starte neue Shell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
exec bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Überprüfe rbenv-Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
type rbenv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installiere ruby-build als rbenv-Plugin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun kann die benötigte Ruby-Version installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
rbenv install 2.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation von Discourse selber ==&lt;br /&gt;
&lt;br /&gt;
Weiterhin Als User &#039;&#039;xyz00-discourse&#039;&#039;:  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~&lt;br /&gt;
git clone https://github.com/discourse/discourse.git discourse&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die stabile Version auschecken:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git checkout stable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ruby Pakete installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gem install bundler&lt;br /&gt;
bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without development test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der Discourse Software ==&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/discourse/config/discourse.conf&#039;&#039; anhand der Beispiel-Datei:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
cp config/discourse_defaults.conf config/discourse.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anpassen folgender Inhalte:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
db_host = 127.0.0.1&lt;br /&gt;
db_port = 5432&lt;br /&gt;
#db_backup_port = 5432 #(auskommentieren)&lt;br /&gt;
db_name = xyz00_discoursedb&lt;br /&gt;
db_username = xyz00_discourseuser&lt;br /&gt;
db_password = &amp;quot;&amp;quot; #db password&lt;br /&gt;
hostname = &amp;quot;discourse.xyz00&amp;quot; # hostname&lt;br /&gt;
smtp_address = localhost&lt;br /&gt;
smtp_enable_start_tls = false&lt;br /&gt;
smtp_openssl_verify_mode = &#039;none&#039;&lt;br /&gt;
developer_emails = # your email-address&lt;br /&gt;
redis_host = 127.0.0.1&lt;br /&gt;
redis_port = 32002&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===TODO: Secrets setzen! ===&lt;br /&gt;
Die Zufallswerte für die Variablen SECRET_KEY_BASE und OTP_SECRET erzeugt man durch zwei Aufrufe des Kommandos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rake secret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq für Hintergrund-Aufgaben konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;config/sidekiq.conf&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wichtig: development auf production ändern.&lt;br /&gt;
&lt;br /&gt;
Mit diesem Dienst werden z.B. die E-Mails zur Aktivierung oder zum Passwort Reset verschickt.&lt;br /&gt;
&lt;br /&gt;
=== Problem mit Content Security Policy ===&lt;br /&gt;
&lt;br /&gt;
Um ein Problem mit Content Security Policy zu lösen, weil manche Dateien über http nachgeladen werden, muss in der Datei &amp;lt;code&amp;gt;config/site_settings.yml&amp;lt;/code&amp;gt; der Default Wert für force_https auf True gesetzt werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
force_https:&lt;br /&gt;
    default: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Problem beim Aufsetzen der Datenbank vermeiden ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;→ Notiz Mai 2024:&#039;&#039;&#039; dies scheint aktuell nicht aufzutreten. &lt;br /&gt;
&lt;br /&gt;
Aus irgendeinem Grund wird beim Initialisieren der Datenbank versucht, den TYPE hotlinked_media_status zweimal in der Datenbank anzulegen. Der Grund ist nicht ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Es kann folgende Änderung an der Datei &amp;lt;code&amp;gt;db/migrate/20220428094026_create_post_hotlinked_media.rb&amp;lt;/code&amp;gt; vorgenommen werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
reversible do |dir|&lt;br /&gt;
  dir.up { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DO $$ BEGIN CREATE TYPE hotlinked_media_status AS ENUM(&#039;downloaded&#039;, &#039;too_large&#039;, &#039;download_failed&#039;, &#039;upload_create_failed&#039;); EXCEPTION WHEN duplicate_object THEN null; END $$;&lt;br /&gt;
    SQL&lt;br /&gt;
  dir.down { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DROP TYPE hotlinked_media_status&lt;br /&gt;
    SQL&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Initialisieren der Datenbank ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
export SAFETY_ASSURED=1&lt;br /&gt;
# In Version 2.0.4 funktioniert db:migrate noch, ansonsten db:schema:load und seed nutzen!&lt;br /&gt;
# In Version 3.0.3 funktioniert db:migrate auch noch, db:schema:load ging nicht weil die Datei structure.sql fehlte&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:schema:load&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:seed&lt;br /&gt;
RAILS_ENV=production bundle exec rails db:migrate&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kompilieren der Assets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rails assets:precompile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration des Web-Servers (am Beispiel Puma)  ===&lt;br /&gt;
&lt;br /&gt;
Die Datei &#039;&#039;config/puma.conf&#039;&#039; anpassen (hier nur Änderungen angezeigt):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini&amp;gt;&lt;br /&gt;
APP_ROOT = &#039;/home/pacs/xyz00/users/discourse/discourse&#039;&lt;br /&gt;
daemonize false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starten der Dienste  ==&lt;br /&gt;
&lt;br /&gt;
Zum Start aller notwendigen Dienste sollte systemd benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Dateien müssen nach &amp;lt;code&amp;gt;.config/systemd/user/&amp;lt;/code&amp;gt; kopiert werden (überlange Zeilen werden hier im Wiki umgebrochen)&lt;br /&gt;
&lt;br /&gt;
redis.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Redis User Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/var/redis&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
ExecStart=%h/bin/redis-server %h/etc/redis.conf&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sidekiq.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Sidekiq Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;DB_POOL=8&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec sidekiq -C %h/discourse/config/sidekiq.yml&lt;br /&gt;
StandardOutput=append:%h/var/log/sidekiq.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
discourse.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Web Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;WEB_CONCURRENCY=2&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MAX_THREADS=5&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec puma -C config/puma.rb -e production -b tcp://127.0.0.1:13000&lt;br /&gt;
StandardOutput=append:%h/var/log/puma.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einrichten des Apache VHost ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/doms/beispiel.discuss&lt;br /&gt;
rm -rf htdocs-ssl subs/www subs-ssl/www&lt;br /&gt;
ln -s ~/live/public htdocs-ssl&lt;br /&gt;
touch htdocs-ssl/.htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann die &#039;&#039;htdocs-ssl/.htaccess&#039;&#039; (durch das gelinkte Verzeichnis entspricht das dem Pfad /home/pacs/xyz00/users/discourse/discourse/public/.htaccess ) mit dem Editor der Wahl öffnen und folgende Konfiguration einfügen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
  &lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RewriteRule .* http://127.0.0.1:13000%{REQUEST_URI} [proxy,last]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wartung ==&lt;br /&gt;
=== Backup ===&lt;br /&gt;
&lt;br /&gt;
Discourse macht selbstätig backups und legt diese unter &#039;public/backups&#039; ab. Enthalten ist ein Datenbank-Dump und die hochgeladenen Dateien.&lt;br /&gt;
&lt;br /&gt;
Im Admin-Bereich lassen sich backups auch manuell antreten.&lt;br /&gt;
&lt;br /&gt;
=== Admin Benutzer einladen ===&lt;br /&gt;
&lt;br /&gt;
Manchmal brauchen wir einen neuen Admin Benutzer, den wir von der Kommandozeile aus einladen möchten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd /discourse&lt;br /&gt;
RAILS_ENV=production rake admin:invite[admin@example.org]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Import aus mbox Archiven ===&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel ein Mailman2 Archiv zu importieren, wo die Nachrichten als .mbox Datei vorliegen, sind folgende Schritte nötig:&lt;br /&gt;
&lt;br /&gt;
Vorbereitungen an Discourse:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
bundle config set frozen false&lt;br /&gt;
IMPORT=1 bundle install&lt;br /&gt;
bundle config set frozen true&lt;br /&gt;
nano script/import_scripts/mbox/settings.yml&lt;br /&gt;
#  dort ändern:&lt;br /&gt;
#    data_dir: /home/pacs/xyz00/users/discourse/list-archiv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hochladen der Mailinglisten-Archive:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/list-archiv&lt;br /&gt;
# dort muss es Unterordner mit dem Namen der gewünschten Kategorie geben,&lt;br /&gt;
# und die mbox Datei muss auch diesen Namen haben, z.B.:&lt;br /&gt;
# ~/list-archiv/beispiel/beispiel.mbox&lt;br /&gt;
# ~/list-archiv/example/example.mbox&lt;br /&gt;
# um die Beiträge in den entsprechenden Kategorien beispiel und example einzufügen.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durchführen des Imports:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
RAILS_ENV=production IMPORT=1 bundle exec rails runner \&lt;br /&gt;
    script/import_scripts/mbox.rb script/import_scripts/mbox/settings.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Export ===&lt;br /&gt;
* Wenn ein Forum beendet wird, möchte man evtl. eine Sicherung als statische HTML Seiten. &lt;br /&gt;
** Das wird hier diskutiert: https://meta.discourse.org/t/how-do-i-export-the-complete-forum-as-static-html-pages/71007/3&lt;br /&gt;
* Um ein Forum von Discourse zu Flarum umzuziehen, hat Timotheus ein Skript geschrieben.&lt;br /&gt;
** Das Migrations-Skript: https://github.com/SolidCharity/discourse_to_flarum&lt;br /&gt;
** siehe auch https://discuss.flarum.org/d/4930-discourse-to-flarum-migration-support/29&lt;br /&gt;
&lt;br /&gt;
=== Updates ===&lt;br /&gt;
&lt;br /&gt;
Discourse wird über update via mail informieren (dies kann man m.W. abschalten).&lt;br /&gt;
&lt;br /&gt;
Achtung: bei größeren Updates auch immer Änderungen an der Datei site_settings.yml (https://github.com/discourse/discourse/blob/main/config/site_settings.yml) beachten!&lt;br /&gt;
&lt;br /&gt;
Siehe auch die unterstützten Releases: https://releases.discourse.org/ und die Tags: https://github.com/discourse/discourse/tags&lt;br /&gt;
&lt;br /&gt;
==== Am Beispiel von 2026.1.7 auf 2026.7.2 ====&lt;br /&gt;
&lt;br /&gt;
# Im Web-Backend unter Administration-&amp;gt;Backups-&amp;gt; Read-Only Mouds setzen (oder Web Server so konfigurieren, dass keine Zugriffe mehr stattfinden können)&lt;br /&gt;
# Backup&lt;br /&gt;
# Die lokalen Änderungen sichern:&lt;br /&gt;
# cd discourse&lt;br /&gt;
# mv ~/plugins.bak/discourse-ai plugins&lt;br /&gt;
# git diff v2026.1.7 &amp;gt; diff-2026.1.7.txt&lt;br /&gt;
# git fetch&lt;br /&gt;
# git checkout -b hostsharing-deployment-v2026.7.2 v2026.7.2&lt;br /&gt;
# evtl. Änderungen aus diff-2026.1.7.txt wieder übernehmen und committen&lt;br /&gt;
# patch -p1 &amp;lt; diff-2026.1.7.txt&lt;br /&gt;
# git commit -a -m &amp;quot;spezifische Änderungen für diese Instanz&amp;quot; --no-verify&lt;br /&gt;
# Schauen, ob discourse eine neue Ruby-Version nutzt (z.B. in https://github.com/discourse/discourse_docker/blob/main/image/base/Dockerfile bzw. https://github.com/discourse/discourse/blob/v2026.1.7/Gemfile)&lt;br /&gt;
# Ist dies der Fall, dann:&lt;br /&gt;
# rbenv install 3.4.10&lt;br /&gt;
# rbenv global 3.4.10&lt;br /&gt;
# rbenv local 3.4.10&lt;br /&gt;
# rbenv rehash&lt;br /&gt;
# echo &amp;quot;3.4.10&amp;quot; &amp;gt; .ruby-version&lt;br /&gt;
# rm -Rf vendor/bundle/ruby/3.3.0/&lt;br /&gt;
# installiere Node 22: https://codeberg.org/tpokorra/hostsharing-scripts/src/branch/main/install-nodejs.sh&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# gem update --system&lt;br /&gt;
# rm -Rf .bundle&lt;br /&gt;
# bundle install&lt;br /&gt;
# npm install -g terser uglify-js pnpm@10&lt;br /&gt;
# corepack use pnpm@latest-10&lt;br /&gt;
# pnpm install&lt;br /&gt;
# export $(grep -v &#039;^#&#039; ~/discourse.env | xargs -d &#039;\n&#039;)&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# Falls die pg extension pg_vector nicht installiert ist: deaktiviere das Plugin während migrate, aber auch für später damit /admin/settings funktioniert (ansonsten in salt pillar pg_vector installieren, und als postgres user: create extension vector;)&lt;br /&gt;
## mkdir -p ~/plugins.bak&lt;br /&gt;
## mv plugins/discourse-ai ~/plugins.bak&lt;br /&gt;
# RAILS_ENV=production bundle exec rake db:migrate&lt;br /&gt;
# RAILS_ENV=production bundle exec rake assets:precompile&lt;br /&gt;
# Services neu starten&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user restart discourse&lt;br /&gt;
systemctl --user restart sidekiq&lt;br /&gt;
systemctl --user restart redis&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zuletzt: Read-Only Modus wieder deaktivieren&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
&lt;br /&gt;
Es können folgende Einstellungen in der Datei config/environments/production.rb vorgenommen werden. Danach den Puma Dienst neustarten. Fehlermeldungen und Stacktraces werden dann im Browser ausgegeben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
config.log_level = :debug&lt;br /&gt;
config.action_dispatch.show_exceptions = :all&lt;br /&gt;
config.action_dispatch.debug_exception_log_level = :error&lt;br /&gt;
&lt;br /&gt;
# Full error reports are enabled and caching is turned off&lt;br /&gt;
config.consider_all_requests_local = true&lt;br /&gt;
config.action_controller.perform_caching = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erforderliche Anpassungen ===&lt;br /&gt;
Weil wir bei Debian Bookworm noch mit ImageMagick 6.9 arbeiten, muss dieser [https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119 Patch] rückgängig gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line&amp;gt;&lt;br /&gt;
wget https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119.patch -O ~/imagemagick.patch&lt;br /&gt;
patch -p1 --reverse &amp;lt; ~/imagemagick.patch&lt;br /&gt;
git commit -a -m &amp;quot;revert imagemagick patch&amp;quot;  --no-verify&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update: es hat sich wieder mehr im Code verändert. Bitte den Patch von https://codeberg.org/tpokorra/hs.ansible/src/branch/main/roles/apps/discourse/templates/imagemagick.patch benutzen!&lt;br /&gt;
&lt;br /&gt;
== ToDos ==&lt;br /&gt;
&lt;br /&gt;
* Ein Patch, um Discourse auch via Unix-Socket mit Redis sprechen lassen zu können dürfte relativ einfach sein (es wird ein Wrapper um das redis-gem genutzt).&lt;br /&gt;
* Konfiguration von discourse, um mit postgresql via Unix-Socket zu kommunizieren (DISCOURSE_DB_SOCKET environment variable)&lt;br /&gt;
* Performance-tuning an diversen Stellen, anhand der discourse_docker-Vorgaben (https://github.com/discourse/discourse_docker), z.B.&lt;br /&gt;
** thpoff (huge page settings)&lt;br /&gt;
** unicorn (hat eine wesentlich ausgefeiltere Konfigurations-Vorlage, wahrscheinlich bereits ordentlich optimiert)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://help.skysilk.com/support/solutions/articles/9000120927-how-to-install-discourse-without-docker-using-skysilk-vps-&lt;br /&gt;
* https://github.com/discourse/discourse_docker&lt;br /&gt;
* https://github.com/discourse/discourse&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/discourse&lt;br /&gt;
&lt;br /&gt;
== Historie ==&lt;br /&gt;
&lt;br /&gt;
* 2018, 14 . September: Initiale Fassung&lt;br /&gt;
* 2019, Januar: Update-Informationen ergänzt&lt;br /&gt;
* 2022, Juni: systemd Dienste, Discourse 3.0&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:RubyOnRails]]&lt;br /&gt;
[[Kategorie:Webforen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7646</id>
		<title>Discourse installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7646"/>
		<updated>2026-09-10T04:36:22Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Am Beispiel von 2026.1.5 auf 2026.1.7 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Textkasten|gelb|Für Managed Server|Ein funktionierender Discourse-Server erfordert mehrere laufende Server-Dienste. Für den Betrieb ist ein Managed Server sinnvoll.}}&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|rot|Support von der Discourse-Community|Die Discourse-Entwickler haben sich entschieden, nur eine mehr oder weniger genormte Installationsmethode (via docker) zu unterstützen. Dies ist so auf der hostsharing-Architektur aufgrund mehrerer Bedenken und Überlegungen nicht möglich. Die Community ist durchaus hilfreich, geht aber davon aus, dass quasi alle Nutzer* eine &amp;quot;supported&amp;quot;e Installation durchgeführt haben. Wenn man in entsprechenden Kanälen nach Hilfe fragt, sollte man unbedingt erwähnen, dass man discourse selber anhand dieser hier lesbaren Anleitung installiert hat, um bereits entsprechenden Kommentaren und Nachfragen vorzugreifen.}}&lt;br /&gt;
&lt;br /&gt;
== Über ==&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel wird die Installation von discourse, Version 2.1.0 (September 2018) beschrieben.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von HSAdmin wird angelegt:&lt;br /&gt;
# Ein User als Service-User mit &#039;&#039;/bin/bash&#039;&#039; als Shell, zum Beispiel Beispiel: &#039;&#039;xyz00-discourse&#039;&#039;&lt;br /&gt;
# Eine Domain mit &#039;&#039;xyz00-discourse&#039; als Domain-Administrator, zum Beispiel &#039;&#039;beispiel.discussion&#039;&#039;&lt;br /&gt;
# Einen Postgresql-User &#039;&#039;xyz00_discourseuser&#039;&#039; mit Passwort &#039;&#039;meinPasswort&#039;&#039;&lt;br /&gt;
# Eine Postgresql-Datenbank &#039;&#039;xyz00_discoursedb&#039;&#039; mit Datenbank-Owner &#039;&#039;xyz00_discourseuser&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verwendete IP-Ports der Server-Dienste:&lt;br /&gt;
# Redis: localhost:32002&lt;br /&gt;
# Discourse-Web: localhost:13000&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der PostgreSQL Datenbank ==&lt;br /&gt;
&lt;br /&gt;
Es müssen noch Erweiterungen für Postgresql installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA public;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration des Redis Server ==&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gelb|Firewall/Redis Port|Leider unterstützt discourse nicht die Kommunikation mit Redis über Unix-Sockets. Dementsprechend muss der für Redis konfigurierte Port von dem hostsharing-Support in der Firewall freigegeben werden.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd&lt;br /&gt;
mkdir redis/etc redis/lib redis/log redis/run&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/redis/etc/redis.conf&#039;&#039; mit folgendem Inhalt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
daemonize no&lt;br /&gt;
pidfile /home/pacs/xyz00/users/discourse/redis/run/redis-server.pid&lt;br /&gt;
port 32002&lt;br /&gt;
tcp-backlog 128&lt;br /&gt;
bind 127.0.0.1&lt;br /&gt;
timeout 300&lt;br /&gt;
loglevel notice&lt;br /&gt;
logfile /home/pacs/xyz00/users/discourse/redis/log/redis.log&lt;br /&gt;
databases 16&lt;br /&gt;
save 900 1&lt;br /&gt;
save 300 10&lt;br /&gt;
save 60 10000&lt;br /&gt;
slave-serve-stale-data yes&lt;br /&gt;
appendonly no&lt;br /&gt;
dbfilename dump.rdb&lt;br /&gt;
dir /home/pacs/xyz00/users/discourse/redis/lib&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für Discourse 3.x gilt: &amp;quot;Discourse requires Redis 6.2.0 or up&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Für Debian Buster und Bullseye ist daher das Installieren eines neueren Binaries erforderlich. Bei Debian Bookwork ist bereits Redis 7.0 enthalten (siehe https://packages.debian.org/search?keywords=redis-server).&lt;br /&gt;
&lt;br /&gt;
Hier steht ein entsprechendes Binary für Debian Buster zur Verfügung, das mit dem Public Key von Timotheus geprüft werden kann:&lt;br /&gt;
&lt;br /&gt;
* https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
* Prüfsignatur: https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz.sig&lt;br /&gt;
&lt;br /&gt;
Prüfen der Signatur:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gpg --verify redis-server-6.2.12-debian-buster.tar.gz.sig redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Binary muss nach &amp;lt;code&amp;gt;$HOME/bin&amp;lt;/code&amp;gt; verschoben werden, und entsprechend beim Starten des Dienstes eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
== Installation von Ruby ==&lt;br /&gt;
&lt;br /&gt;
Als User &#039;&#039;xyz00-discourse&#039;&#039;:  Installation von Ruby mit &#039;&#039;rbenv&#039;&#039; mit folgenden Befehlen:&lt;br /&gt;
&lt;br /&gt;
Zunächst &#039;&#039;rbenv&#039;&#039; and &#039;&#039;ruby-build&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/rbenv.git ~/.rbenv&lt;br /&gt;
cd ~/.rbenv &amp;amp;&amp;amp; src/configure &amp;amp;&amp;amp; make -C src&lt;br /&gt;
echo &#039;export PATH=&amp;quot;$HOME/.rbenv/bin:$PATH&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
echo &#039;eval &amp;quot;$(rbenv init -)&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
starte neue Shell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
exec bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Überprüfe rbenv-Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
type rbenv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installiere ruby-build als rbenv-Plugin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun kann die benötigte Ruby-Version installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
rbenv install 2.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation von Discourse selber ==&lt;br /&gt;
&lt;br /&gt;
Weiterhin Als User &#039;&#039;xyz00-discourse&#039;&#039;:  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~&lt;br /&gt;
git clone https://github.com/discourse/discourse.git discourse&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die stabile Version auschecken:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git checkout stable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ruby Pakete installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gem install bundler&lt;br /&gt;
bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without development test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der Discourse Software ==&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/discourse/config/discourse.conf&#039;&#039; anhand der Beispiel-Datei:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
cp config/discourse_defaults.conf config/discourse.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anpassen folgender Inhalte:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
db_host = 127.0.0.1&lt;br /&gt;
db_port = 5432&lt;br /&gt;
#db_backup_port = 5432 #(auskommentieren)&lt;br /&gt;
db_name = xyz00_discoursedb&lt;br /&gt;
db_username = xyz00_discourseuser&lt;br /&gt;
db_password = &amp;quot;&amp;quot; #db password&lt;br /&gt;
hostname = &amp;quot;discourse.xyz00&amp;quot; # hostname&lt;br /&gt;
smtp_address = localhost&lt;br /&gt;
smtp_enable_start_tls = false&lt;br /&gt;
smtp_openssl_verify_mode = &#039;none&#039;&lt;br /&gt;
developer_emails = # your email-address&lt;br /&gt;
redis_host = 127.0.0.1&lt;br /&gt;
redis_port = 32002&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===TODO: Secrets setzen! ===&lt;br /&gt;
Die Zufallswerte für die Variablen SECRET_KEY_BASE und OTP_SECRET erzeugt man durch zwei Aufrufe des Kommandos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rake secret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq für Hintergrund-Aufgaben konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;config/sidekiq.conf&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wichtig: development auf production ändern.&lt;br /&gt;
&lt;br /&gt;
Mit diesem Dienst werden z.B. die E-Mails zur Aktivierung oder zum Passwort Reset verschickt.&lt;br /&gt;
&lt;br /&gt;
=== Problem mit Content Security Policy ===&lt;br /&gt;
&lt;br /&gt;
Um ein Problem mit Content Security Policy zu lösen, weil manche Dateien über http nachgeladen werden, muss in der Datei &amp;lt;code&amp;gt;config/site_settings.yml&amp;lt;/code&amp;gt; der Default Wert für force_https auf True gesetzt werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
force_https:&lt;br /&gt;
    default: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Problem beim Aufsetzen der Datenbank vermeiden ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;→ Notiz Mai 2024:&#039;&#039;&#039; dies scheint aktuell nicht aufzutreten. &lt;br /&gt;
&lt;br /&gt;
Aus irgendeinem Grund wird beim Initialisieren der Datenbank versucht, den TYPE hotlinked_media_status zweimal in der Datenbank anzulegen. Der Grund ist nicht ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Es kann folgende Änderung an der Datei &amp;lt;code&amp;gt;db/migrate/20220428094026_create_post_hotlinked_media.rb&amp;lt;/code&amp;gt; vorgenommen werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
reversible do |dir|&lt;br /&gt;
  dir.up { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DO $$ BEGIN CREATE TYPE hotlinked_media_status AS ENUM(&#039;downloaded&#039;, &#039;too_large&#039;, &#039;download_failed&#039;, &#039;upload_create_failed&#039;); EXCEPTION WHEN duplicate_object THEN null; END $$;&lt;br /&gt;
    SQL&lt;br /&gt;
  dir.down { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DROP TYPE hotlinked_media_status&lt;br /&gt;
    SQL&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Initialisieren der Datenbank ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
export SAFETY_ASSURED=1&lt;br /&gt;
# In Version 2.0.4 funktioniert db:migrate noch, ansonsten db:schema:load und seed nutzen!&lt;br /&gt;
# In Version 3.0.3 funktioniert db:migrate auch noch, db:schema:load ging nicht weil die Datei structure.sql fehlte&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:schema:load&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:seed&lt;br /&gt;
RAILS_ENV=production bundle exec rails db:migrate&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kompilieren der Assets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rails assets:precompile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration des Web-Servers (am Beispiel Puma)  ===&lt;br /&gt;
&lt;br /&gt;
Die Datei &#039;&#039;config/puma.conf&#039;&#039; anpassen (hier nur Änderungen angezeigt):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini&amp;gt;&lt;br /&gt;
APP_ROOT = &#039;/home/pacs/xyz00/users/discourse/discourse&#039;&lt;br /&gt;
daemonize false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starten der Dienste  ==&lt;br /&gt;
&lt;br /&gt;
Zum Start aller notwendigen Dienste sollte systemd benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Dateien müssen nach &amp;lt;code&amp;gt;.config/systemd/user/&amp;lt;/code&amp;gt; kopiert werden (überlange Zeilen werden hier im Wiki umgebrochen)&lt;br /&gt;
&lt;br /&gt;
redis.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Redis User Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/var/redis&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
ExecStart=%h/bin/redis-server %h/etc/redis.conf&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sidekiq.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Sidekiq Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;DB_POOL=8&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec sidekiq -C %h/discourse/config/sidekiq.yml&lt;br /&gt;
StandardOutput=append:%h/var/log/sidekiq.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
discourse.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Web Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;WEB_CONCURRENCY=2&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MAX_THREADS=5&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec puma -C config/puma.rb -e production -b tcp://127.0.0.1:13000&lt;br /&gt;
StandardOutput=append:%h/var/log/puma.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einrichten des Apache VHost ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/doms/beispiel.discuss&lt;br /&gt;
rm -rf htdocs-ssl subs/www subs-ssl/www&lt;br /&gt;
ln -s ~/live/public htdocs-ssl&lt;br /&gt;
touch htdocs-ssl/.htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann die &#039;&#039;htdocs-ssl/.htaccess&#039;&#039; (durch das gelinkte Verzeichnis entspricht das dem Pfad /home/pacs/xyz00/users/discourse/discourse/public/.htaccess ) mit dem Editor der Wahl öffnen und folgende Konfiguration einfügen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
  &lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RewriteRule .* http://127.0.0.1:13000%{REQUEST_URI} [proxy,last]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wartung ==&lt;br /&gt;
=== Backup ===&lt;br /&gt;
&lt;br /&gt;
Discourse macht selbstätig backups und legt diese unter &#039;public/backups&#039; ab. Enthalten ist ein Datenbank-Dump und die hochgeladenen Dateien.&lt;br /&gt;
&lt;br /&gt;
Im Admin-Bereich lassen sich backups auch manuell antreten.&lt;br /&gt;
&lt;br /&gt;
=== Admin Benutzer einladen ===&lt;br /&gt;
&lt;br /&gt;
Manchmal brauchen wir einen neuen Admin Benutzer, den wir von der Kommandozeile aus einladen möchten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd /discourse&lt;br /&gt;
RAILS_ENV=production rake admin:invite[admin@example.org]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Import aus mbox Archiven ===&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel ein Mailman2 Archiv zu importieren, wo die Nachrichten als .mbox Datei vorliegen, sind folgende Schritte nötig:&lt;br /&gt;
&lt;br /&gt;
Vorbereitungen an Discourse:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
bundle config set frozen false&lt;br /&gt;
IMPORT=1 bundle install&lt;br /&gt;
bundle config set frozen true&lt;br /&gt;
nano script/import_scripts/mbox/settings.yml&lt;br /&gt;
#  dort ändern:&lt;br /&gt;
#    data_dir: /home/pacs/xyz00/users/discourse/list-archiv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hochladen der Mailinglisten-Archive:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/list-archiv&lt;br /&gt;
# dort muss es Unterordner mit dem Namen der gewünschten Kategorie geben,&lt;br /&gt;
# und die mbox Datei muss auch diesen Namen haben, z.B.:&lt;br /&gt;
# ~/list-archiv/beispiel/beispiel.mbox&lt;br /&gt;
# ~/list-archiv/example/example.mbox&lt;br /&gt;
# um die Beiträge in den entsprechenden Kategorien beispiel und example einzufügen.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durchführen des Imports:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
RAILS_ENV=production IMPORT=1 bundle exec rails runner \&lt;br /&gt;
    script/import_scripts/mbox.rb script/import_scripts/mbox/settings.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Export ===&lt;br /&gt;
* Wenn ein Forum beendet wird, möchte man evtl. eine Sicherung als statische HTML Seiten. &lt;br /&gt;
** Das wird hier diskutiert: https://meta.discourse.org/t/how-do-i-export-the-complete-forum-as-static-html-pages/71007/3&lt;br /&gt;
* Um ein Forum von Discourse zu Flarum umzuziehen, hat Timotheus ein Skript geschrieben.&lt;br /&gt;
** Das Migrations-Skript: https://github.com/SolidCharity/discourse_to_flarum&lt;br /&gt;
** siehe auch https://discuss.flarum.org/d/4930-discourse-to-flarum-migration-support/29&lt;br /&gt;
&lt;br /&gt;
=== Updates ===&lt;br /&gt;
&lt;br /&gt;
Discourse wird über update via mail informieren (dies kann man m.W. abschalten).&lt;br /&gt;
&lt;br /&gt;
Achtung: bei größeren Updates auch immer Änderungen an der Datei site_settings.yml (https://github.com/discourse/discourse/blob/main/config/site_settings.yml) beachten!&lt;br /&gt;
&lt;br /&gt;
Siehe auch die unterstützten Releases: https://releases.discourse.org/ und die Tags: https://github.com/discourse/discourse/tags&lt;br /&gt;
&lt;br /&gt;
==== Am Beispiel von 2026.1.7 auf 2026.7.2 ====&lt;br /&gt;
&lt;br /&gt;
# Im Web-Backend unter Administration-&amp;gt;Backups-&amp;gt; Read-Only Mouds setzen (oder Web Server so konfigurieren, dass keine Zugriffe mehr stattfinden können)&lt;br /&gt;
# Backup&lt;br /&gt;
# Die lokalen Änderungen sichern:&lt;br /&gt;
# cd discourse&lt;br /&gt;
# mv ~/plugins.bak/discourse-ai plugins&lt;br /&gt;
# git diff v2026.1.7 &amp;gt; diff-2026.1.7.txt&lt;br /&gt;
# git fetch&lt;br /&gt;
# git checkout -b hostsharing-deployment-v2026.7.2 v2026.7.2&lt;br /&gt;
# evtl. Änderungen aus diff-2026.1.7.txt wieder übernehmen und committen&lt;br /&gt;
# patch -p1 &amp;lt; diff-2026.1.7.txt&lt;br /&gt;
# git commit -a -m &amp;quot;spezifische Änderungen für diese Instanz&amp;quot; --no-verify&lt;br /&gt;
# Schauen, ob discourse eine neue Ruby-Version nutzt (z.B. in https://github.com/discourse/discourse_docker/blob/main/image/base/Dockerfile bzw. https://github.com/discourse/discourse/blob/v2026.1.7/Gemfile)&lt;br /&gt;
# Ist dies der Fall, dann:&lt;br /&gt;
# rbenv install 3.4.10&lt;br /&gt;
# rbenv global 3.4.10&lt;br /&gt;
# rbenv rehash&lt;br /&gt;
# echo &amp;quot;3.4.10&amp;quot; &amp;gt; .ruby-version&lt;br /&gt;
# installiere Node 22: https://codeberg.org/tpokorra/hostsharing-scripts/src/branch/main/install-nodejs.sh&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# gem update --system&lt;br /&gt;
# bundle install&lt;br /&gt;
# npm install -g terser uglify-js pnpm@10&lt;br /&gt;
# corepack use pnpm@latest-10&lt;br /&gt;
# pnpm install&lt;br /&gt;
# export $(grep -v &#039;^#&#039; ~/discourse.env | xargs -d &#039;\n&#039;)&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# Falls die pg extension pg_vector nicht installiert ist: deaktiviere das Plugin während migrate, aber auch für später damit /admin/settings funktioniert (ansonsten in salt pillar pg_vector installieren, und als postgres user: create extension vector;)&lt;br /&gt;
## mkdir -p ~/plugins.bak&lt;br /&gt;
## mv plugins/discourse-ai ~/plugins.bak&lt;br /&gt;
# RAILS_ENV=production bundle exec rake db:migrate&lt;br /&gt;
# RAILS_ENV=production bundle exec rake assets:precompile&lt;br /&gt;
# Services neu starten&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user restart discourse&lt;br /&gt;
systemctl --user restart sidekiq&lt;br /&gt;
systemctl --user restart redis&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zuletzt: Read-Only Modus wieder deaktivieren&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
&lt;br /&gt;
Es können folgende Einstellungen in der Datei config/environments/production.rb vorgenommen werden. Danach den Puma Dienst neustarten. Fehlermeldungen und Stacktraces werden dann im Browser ausgegeben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
config.log_level = :debug&lt;br /&gt;
config.action_dispatch.show_exceptions = :all&lt;br /&gt;
config.action_dispatch.debug_exception_log_level = :error&lt;br /&gt;
&lt;br /&gt;
# Full error reports are enabled and caching is turned off&lt;br /&gt;
config.consider_all_requests_local = true&lt;br /&gt;
config.action_controller.perform_caching = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erforderliche Anpassungen ===&lt;br /&gt;
Weil wir bei Debian Bookworm noch mit ImageMagick 6.9 arbeiten, muss dieser [https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119 Patch] rückgängig gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line&amp;gt;&lt;br /&gt;
wget https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119.patch -O ~/imagemagick.patch&lt;br /&gt;
patch -p1 --reverse &amp;lt; ~/imagemagick.patch&lt;br /&gt;
git commit -a -m &amp;quot;revert imagemagick patch&amp;quot;  --no-verify&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update: es hat sich wieder mehr im Code verändert. Bitte den Patch von https://codeberg.org/tpokorra/hs.ansible/src/branch/main/roles/apps/discourse/templates/imagemagick.patch benutzen!&lt;br /&gt;
&lt;br /&gt;
== ToDos ==&lt;br /&gt;
&lt;br /&gt;
* Ein Patch, um Discourse auch via Unix-Socket mit Redis sprechen lassen zu können dürfte relativ einfach sein (es wird ein Wrapper um das redis-gem genutzt).&lt;br /&gt;
* Konfiguration von discourse, um mit postgresql via Unix-Socket zu kommunizieren (DISCOURSE_DB_SOCKET environment variable)&lt;br /&gt;
* Performance-tuning an diversen Stellen, anhand der discourse_docker-Vorgaben (https://github.com/discourse/discourse_docker), z.B.&lt;br /&gt;
** thpoff (huge page settings)&lt;br /&gt;
** unicorn (hat eine wesentlich ausgefeiltere Konfigurations-Vorlage, wahrscheinlich bereits ordentlich optimiert)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://help.skysilk.com/support/solutions/articles/9000120927-how-to-install-discourse-without-docker-using-skysilk-vps-&lt;br /&gt;
* https://github.com/discourse/discourse_docker&lt;br /&gt;
* https://github.com/discourse/discourse&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/discourse&lt;br /&gt;
&lt;br /&gt;
== Historie ==&lt;br /&gt;
&lt;br /&gt;
* 2018, 14 . September: Initiale Fassung&lt;br /&gt;
* 2019, Januar: Update-Informationen ergänzt&lt;br /&gt;
* 2022, Juni: systemd Dienste, Discourse 3.0&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:RubyOnRails]]&lt;br /&gt;
[[Kategorie:Webforen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Znuny_installieren&amp;diff=7643</id>
		<title>Znuny installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Znuny_installieren&amp;diff=7643"/>
		<updated>2026-09-09T14:48:47Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Fehlersuche */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemein ==&lt;br /&gt;
&lt;br /&gt;
[https://www.znuny.org/de Znuny] ist ein Open Source Ticketing System, und ist als Community Fork von OTRS entstanden. Das Versprechen ist, ein Ticket System mit Langzeitunterstützung (LTS) zu bieten.&lt;br /&gt;
&lt;br /&gt;
Znuny ist in Perl geschrieben.&lt;br /&gt;
&lt;br /&gt;
== Technische Details ==&lt;br /&gt;
Es gibt ein Ansible Skript, das die Installationsschritte für Znuny automatisiert durchführt.&lt;br /&gt;
&lt;br /&gt;
Die Quellen für das Ansible Skript können hier eingesehen werden: https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/znuny&lt;br /&gt;
&lt;br /&gt;
== Updates ==&lt;br /&gt;
&lt;br /&gt;
Hier gibt es eine Übersicht über die aktuellen Versionen von Znuny: https://www.znuny.org/de/releases&lt;br /&gt;
&lt;br /&gt;
Updates werden hier beschrieben:&lt;br /&gt;
* auf Znuny 6.5: https://doc.znuny.org/znuny_lts/releases/installupdate/update/update-6.5.html&lt;br /&gt;
&lt;br /&gt;
Vor der Durchführung eines Updates auf dem Produktivsystem sollte ein Backup erstellt werden, das im Fall eines Problems wiederhergestellt werden kann.&lt;br /&gt;
&lt;br /&gt;
Der Cronjob sollte deaktiviert werden, und im Administrationsbereich von Znuny sollte der Wartungsmodus aktiviert werden (unter SystemWartung).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
# crontab -e&lt;br /&gt;
#    Kommentar einfügen vor:&lt;br /&gt;
&lt;br /&gt;
#*/5 * * * *    $HOME/otrs/bin/otrs.Daemon.pl start &amp;amp;&amp;gt;/dev/null&lt;br /&gt;
$HOME/otrs/bin/otrs.Daemon.pl stop&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann muss der Tarball der gewünschten Version von Znuny heruntergeladen werden, und entpackt werden.&lt;br /&gt;
&lt;br /&gt;
Die Konfigurationsdatei (Kernel/Config.pm) muss aus dem alten Verzeichnis in das neue Verzeichnis kopiert werden, ebenso evtl. Dateien in var/article. Cronjobs sollten ebenfalls von var/cron ins neue Verzeichnis kopiert werden.&lt;br /&gt;
&lt;br /&gt;
Dann wird der symbolische Link gelöscht, und ein neuer symbolischer Link auf das neue Verzeichnis eingerichtet, zum Beispiel so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
rm Znuny &amp;amp;&amp;amp; ln -s znuny-6.5.6 Znuny&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach werden die folgenden Befehle ausgeführt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd Znuny&lt;br /&gt;
./bin/otrs.Console.pl Maint::Database::Check&lt;br /&gt;
./bin/otrs.CheckModules.pl --all&lt;br /&gt;
./scripts/MigrateToZnuny6_5.pl&lt;br /&gt;
./bin/otrs.Console.pl Admin::Package::UpgradeAll&lt;br /&gt;
./bin/otrs.Console.pl Admin::Package::ReinstallAll&lt;br /&gt;
./bin/otrs.Console.pl Admin::Package::UpgradeAll&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun können die Cronjobs wieder aktiviert werden, und der Wartungsmodus kann beendet werden.&lt;br /&gt;
&lt;br /&gt;
Gegebenenfalls müssen die Prozess-Tickets nach einem Update wieder in Betrieb genommen werden, in der Admin-Oberfläche unter Prozessmanagement.&lt;br /&gt;
&lt;br /&gt;
== Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
=== Prozesse ===&lt;br /&gt;
&lt;br /&gt;
Es lassen sich beliebige Prozesse einrichten.&lt;br /&gt;
&lt;br /&gt;
Siehe dazu auch ein Blogbeitrag inkl. Video unseres Mitglieds Timotheus Pokorra:  https://solidevereine.de/blog/2023/06/13/2023-06-znuny_prozess/&lt;br /&gt;
&lt;br /&gt;
=== Eingehende E-Mails in Queues sortieren ===&lt;br /&gt;
&lt;br /&gt;
Eingehende E-Mails können nach verschiedenen Kriterien mit Procmail in verschiedene Queues einsortiert werden.&lt;br /&gt;
&lt;br /&gt;
Das sieht zum Beispiel für eine Queue Service mit Subqueue Letsencrypt so aus, in der Datei &amp;lt;code&amp;gt;.procmailrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
:0&lt;br /&gt;
* ^From: .+expiry@letsencrypt.org&lt;br /&gt;
|${HOME}/otrs/bin/otrs.Console.pl Maint::PostMaster::Read --target-queue Service::Letsencrypt --quiet&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Automatische Antwort bei eingehenden E-Mails ===&lt;br /&gt;
&lt;br /&gt;
Normalerweise haben wir eine automatisierte Antwort für eingehende E-Mails (&amp;quot;Wir haben Ihre Anfrage erhalten, und melden uns bald bei Ihnen&amp;quot;). Das konfigurieren wir in den Einstellungen bei &#039;&#039;&#039;Auto Response&#039;&#039;&#039;/&#039;&#039;&#039;Automatische Antworten&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Von manchen Dienstleistern erhalten wir E-Mails im Ticketsystem, und wollen dort keine automatisierte Antwort schicken. &lt;br /&gt;
Um das umzusetzen, bearbeiten wir in den Einstellungen bei Systemkonfiguration den Eintrag &#039;&#039;&#039;SendNoAutoResponseRegExp&#039;&#039;&#039;, wo wir einen regulären Ausdruck definieren können.&lt;br /&gt;
&lt;br /&gt;
siehe auch https://doc.znuny.org/znuny_lts/admin/communication/autoresponses/index.html&lt;br /&gt;
&lt;br /&gt;
== Fehlersuche ==&lt;br /&gt;
&lt;br /&gt;
Die Konfigurationsdatei ist in &amp;lt;code&amp;gt;Kernel/Config.pm&amp;lt;/code&amp;gt;. Die Default Einstellungen sind zu finden in &amp;lt;code&amp;gt;Kernel/Config/Defaults.pm&amp;lt;/code&amp;gt; (siehe auch [https://github.com/znuny/Znuny/blob/dev/Kernel/Config/Defaults.pm])&lt;br /&gt;
&lt;br /&gt;
Normalerweise wird in das SysLog (System Log) des Users geloggt. Dieses Log kann so gelesen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
journalctl --user&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Session Einstellungen ===&lt;br /&gt;
&lt;br /&gt;
Wenn das komische Verhalten auftritt, dass z.B. nur das zuletzt hinzugefügte Attachment verschickt wird, dann ist was an den Sessions kaputt.&lt;br /&gt;
&lt;br /&gt;
Wir empfehlen, die Einstellung SessionUseCookie anzuschalten.&lt;br /&gt;
&lt;br /&gt;
Wenn die Session ID im GET Parameter OTRSAgentInterface in der URL erscheint: Das ist ein Zeichen dafür, dass das SessionManagement kaputt ist. Wenn sich aber in der Sysconfig von Znuny was ändert, z.B. Switches für Session per GET-Param oder Cookie, für den ScriptAlias, für HTTP/HTTPS oder den FQDN, dann wird auf Session-ID per URL umgestellt. Das kann auch mit Änderungen am fastcgi-bin Pfad verursacht werden.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
*[https://www.znuny.org/de Webseite des Znuny Projekts]&lt;br /&gt;
*[https://github.com/znuny/Znuny Quelltext von Znuny bei Github]&lt;br /&gt;
*[https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/znuny Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Helpdesk]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Nextcloud&amp;diff=7642</id>
		<title>Nextcloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Nextcloud&amp;diff=7642"/>
		<updated>2026-09-04T20:54:50Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Nextcloud Push */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Nextcloud =&lt;br /&gt;
&lt;br /&gt;
[https://nextcloud.com/ Nextcloud] ist eine PHP-basierte Open Source Lösung für gängige Cloud-Anwendungen, u.a.:&lt;br /&gt;
&lt;br /&gt;
* Filesharing unter Nutzern derselben Nextcloud, und mit der Öffentlichkeit&lt;br /&gt;
* Single-Sign-On Authentifizierung (SSO)&lt;br /&gt;
* Videokonferenzen (WebRTC)&lt;br /&gt;
* Online-Office Anwendung [https://www.collaboraoffice.com/ Collabora Online]&lt;br /&gt;
&lt;br /&gt;
Beispiel-Funktionalität, die über Plugins, sogenannte [https://apps.nextcloud.com/ &amp;quot;Apps&amp;quot;], bereit gestellt werden kann:&lt;br /&gt;
&lt;br /&gt;
* Kalender, Aufgabenverwaltung, Adressbuch&lt;br /&gt;
* Datei-Kollaboration (Kommentare zu Dateien, Verschlagwortung)&lt;br /&gt;
* Feedreader&lt;br /&gt;
* E-Mail-Programm&lt;br /&gt;
* Fotogalerie&lt;br /&gt;
* Musik- und Videowiedergabe&lt;br /&gt;
&lt;br /&gt;
= Nextcloud installieren =&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;cloud.example.org&#039;&#039;&lt;br /&gt;
* PostgreSQL-User &lt;br /&gt;
* PostgreSQL Datenbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-cloud&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Nextcloud&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;cloud.example.org&#039;,user:&#039;xyz00-cloud&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; postgresqluser.add({set:{name:&#039;xyz00_nextclusr&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; postgresqldb.add({set:{name:&#039;xyz00_nextcloud&#039;,owner:&#039;xyz00_nextclusr&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nextcloud installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-cloud&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
ssh -l xyz00-cloud xyz00.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd&lt;br /&gt;
mkdir nextcloud&lt;br /&gt;
cd doms/cloud.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www htdocs-ssl&lt;br /&gt;
ln -s $HOME/nextcloud htdocs-ssl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls der &#039;&#039;Redirect&#039;&#039; auf die Domain &#039;&#039;example.org&#039;&#039; umleitet statt auf die Subdomain &#039;&#039;cloud.example.org&#039;&#039;, kann diese Aktion helfen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/cloud.example.org&lt;br /&gt;
mkdir -p subs-ssl/www&lt;br /&gt;
cp htdocs/.htaccess subs-ssl/www/.htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nextcloud herunterladen und entpacken.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd &lt;br /&gt;
wget https://download.nextcloud.com/server/releases/nextcloud-30.0.6.zip&lt;br /&gt;
unzip nextcloud-30.0.6.zip &lt;br /&gt;
rm nextcloud-30.0.6.zip&lt;br /&gt;
mkdir data tmp&lt;br /&gt;
chmod 700 data tmp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um Probleme mit der Anmeldung der Nextcloud App am Mobilgerät zu vermeiden, müssen folgende Zeilen in der Datei &amp;lt;code&amp;gt;doms/cloud.example.org/.htaccess&amp;lt;/code&amp;gt; eingefügt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=htaccess&amp;gt;&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteCond %{HTTP:Authorization} ^(.*)&lt;br /&gt;
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nextcloud konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Verzeichnis &amp;quot;$HOME/doms/cloud.example.org/fastcgi-ssl/&amp;quot; eine Datei &amp;quot;php.ini&amp;quot; anlegen mit folgendem Inhalt: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini&amp;gt;&lt;br /&gt;
memory_limit=512M&lt;br /&gt;
session.save_path=/home/pacs/xyz00/users/cloud/tmp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann mit einem Editor diese Datei bearbeiten: In der zweiten Zeile den korrekten Pfad des vorher angelegten tmp-Verzeichnisses eintragen.&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://cloud.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
Auf der ersten Seite sind anzugeben:&lt;br /&gt;
&lt;br /&gt;
* Login und Passwort für den Administrator definieren&lt;br /&gt;
* PostgreSQL als Datenbanksystem&lt;br /&gt;
* PostgreSQL-User und Passwort aus dem ersten Schritt oben&lt;br /&gt;
* Name der PostgreSQL-Datenbank aus dem ersten Schritt&lt;br /&gt;
* &amp;quot;localhost&amp;quot; als Datenbankserver (Nextcloud 23.0.2 empfiehlt hier die Angabe des Ports, diesen also lt. [[PostgreSQL]] angeben)&lt;br /&gt;
* Das Verzeichnis &amp;quot;/home/pacs/xyz00/users/cloud/data/&amp;quot; als Daten-Verzeichnis (bitte beachten: das im Eingabefeld voreingestellte verweist auf das Verzeichnis &amp;quot;/home/pacs/xyz00/users/cloud/&#039;&#039;&#039;nextcloud&#039;&#039;&#039;/data/&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung!&#039;&#039;&#039; Die Felder für die Datenbank sind auf dem Startscreen hinter einem unscheinbaren Link versteckt. Um man das Formular für die Datenbank-Daten zu gelangen, muss man auf den Link klicken. Anschließend kann man die gewünschte Datenbank auswählen und die entsprechenden Daten eintragen. &#039;&#039;&#039;Das sollte geschehen, bevor man die Installation abschließt!&#039;&#039;&#039; Tut man dies nicht, wird Nextcloud mit SQLite installiert. Eine Änderung der Datenbank soll zwar laut Dokumentation auch später noch möglich sein, ging aber bei einem Test schief.&lt;br /&gt;
&lt;br /&gt;
In der Konfigurationsdatei der Nextcloud (in &#039;&#039;~/nextcloud/config/config.php&#039;&#039;) lassen sich weitere Voreinstellungen treffen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php line&amp;gt;&lt;br /&gt;
&#039;maintenance_window_start&#039; =&amp;gt; 1,    // Wartungsfenster ab 1:00 Uhr&lt;br /&gt;
&#039;defaultapp&#039; =&amp;gt; &#039;calendar,files&#039;,   // bei Start wird der Kalender gezeigt&lt;br /&gt;
&#039;default_phone_region&#039; =&amp;gt; &#039;DE&#039;,     // Format Telefonnummern&lt;br /&gt;
&#039;default_language&#039; =&amp;gt; &#039;de&#039;,         // Sprache deutsch&lt;br /&gt;
&#039;force_language&#039; =&amp;gt; &#039;de&#039;,&lt;br /&gt;
&#039;default_locale&#039; =&amp;gt; &#039;de_DE&#039;,        // Locale (Formatierung Zeitangaben etc.) &lt;br /&gt;
&#039;force_locale&#039; =&amp;gt; &#039;de_DE&#039;,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nextcloud beschleunigen ==&lt;br /&gt;
&lt;br /&gt;
Dieser Teil ist optional.&lt;br /&gt;
&lt;br /&gt;
Wenn regelmäßig &#039;&#039;&#039;im Browser&#039;&#039;&#039; mit Nextcloud gearbeitet werden soll, ist Nextcloud im Browser oft sehr langsam. Um dies zu verbessern, unterstützt Nextcloud die Anwendung von unterschiedlichen Cache-Verfahren (zum Beispiel Memcache, Redis).&lt;br /&gt;
&lt;br /&gt;
=== Redis Cache ===&lt;br /&gt;
&lt;br /&gt;
Redis ist auf den Hostsharing-Servern vorinstalliert und wird von den Nextcloud-Entwicklern empfohlen. Redis wird als eigener Serverdienst gestartet. &#039;&#039;&#039;In Verbindung mit Hostsharing Managed Webspace muss für Redis [https://www.hostsharing.net/paas/managed-webspace/ Arbeitsspeicher für eigene Serverdienste] gebucht werden&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Die Konfiguration des Redis-Dientes ist auf der Seite [[Redis]] beschrieben. Hier wird für Nextcloud die Variante mit einem Unixsocket benutzt.&lt;br /&gt;
&lt;br /&gt;
In der Konfiguration der Nextcloud (in &#039;&#039;~/nextcloud/config/config.php&#039;&#039;) wird der Redis-Cache wie folgt konfiguriert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php line&amp;gt;&lt;br /&gt;
&#039;memcache.local&#039; =&amp;gt; &#039;\\OC\\Memcache\\Redis&#039;,&lt;br /&gt;
&#039;memcache.distributed&#039; =&amp;gt; &#039;\\OC\\Memcache\\Redis&#039;,&lt;br /&gt;
&#039;memcache.locking&#039; =&amp;gt; &#039;\\OC\\Memcache\\Redis&#039;,&lt;br /&gt;
&#039;redis&#039; =&amp;gt; &lt;br /&gt;
  array (&lt;br /&gt;
    &#039;host&#039; =&amp;gt; &#039;/home/pacs/xyz00/users/cloud/redis/var/redis-server.sock&#039;,&lt;br /&gt;
    &#039;port&#039; =&amp;gt; 0,&lt;br /&gt;
    &#039;password&#039; =&amp;gt; &#039;mein-redis-passwort&#039;,&lt;br /&gt;
    &#039;timeout&#039; =&amp;gt; 1.5,&lt;br /&gt;
  ),&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um es perfekt zu machen, nutze ich &#039;&#039;logrotate&#039;&#039; um die Logdateien zu organisieren. Dazu die Konfiguration in &#039;&#039;~/.logrotate&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
compress&lt;br /&gt;
/home/pacs/xyz00/users/cloud/redis/var/redis.log {&lt;br /&gt;
  rotate 5&lt;br /&gt;
  daily&lt;br /&gt;
  missingok&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Mit systemd-Timern werden die Logdateien täglich rotiert:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;~/.config/systemd/user/logrotate.service&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=rotate log files&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=oneshot&lt;br /&gt;
ExecStart=/usr/sbin/logrotate -s %h/.logrotate.state %h/.logrotate&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;~/.config/systemd/user/logrotate.timer&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=timer for nextcloud cleanup job&lt;br /&gt;
&lt;br /&gt;
[Timer]&lt;br /&gt;
OnCalendar=1:1&lt;br /&gt;
Persistent=True&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=timers.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Timer aktivieren und starten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
$ systemctl --user enable logrotate.timer&lt;br /&gt;
$ systemctl --user start logrotate.timer&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nextcloud Cronjob ===&lt;br /&gt;
&lt;br /&gt;
Für die regelmäßigen Hintergrundaufgaben innerhalb der Nextcloud sollte ein Cronjob eingerichtet werden. Wir lösen dies hier mit einem weiteren Systemd-Timer:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;~/.config/systemd/user/nextcloud_background.service&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=nextcloud cleanup job&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=oneshot&lt;br /&gt;
ExecStart=/usr/bin/php %h/nextcloud/cron.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;~/.config/systemd/user/nextcloud_background.timer&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=timer for nextcloud cleanup job&lt;br /&gt;
&lt;br /&gt;
[Timer]&lt;br /&gt;
OnCalendar=*:0/5&lt;br /&gt;
Persistent=True&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=timers.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Timer aktivieren und starten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
$ systemctl --user enable nextcloud_background.timer&lt;br /&gt;
$ systemctl --user start nextcloud_background.timer&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nextcloud Push ===&lt;br /&gt;
&lt;br /&gt;
Um Vorgänge wie Sync und Benachrichtigungen bei sehr großen Nextcloud Installationen zu beschleunigen, kann der &amp;lt;code&amp;gt;notify_push&amp;lt;/code&amp;gt; Dienst hinzuinstalliert werden.&lt;br /&gt;
&lt;br /&gt;
==== Abhängigkeiten und Einschränkungen ====&lt;br /&gt;
* &amp;lt;code&amp;gt;notify_push&amp;lt;/code&amp;gt; muss Zugriff auf den gleichen Redis-Cache wie die Nextcloud haben &lt;br /&gt;
** aufgrund von eingeschränktem Passwort Support sollte ein Redis Socket mit sicheren Berechtigungseinstellungen als Alternative zum Redis Port mit Passwort konfiguriert werden.&lt;br /&gt;
* optimaler Weise holt sich &amp;lt;code&amp;gt;notify_push&amp;lt;/code&amp;gt; benötigte informationen aus der &amp;lt;code&amp;gt;config.php&amp;lt;/code&amp;gt; der bestehenden Nextcloud-Installation&lt;br /&gt;
* eine zusätzliche (Sub)domain im gleichen User ist nötig. Andernfalls muss die bestehende &amp;lt;code&amp;gt;.htaccess&amp;lt;/code&amp;gt; muss aus o.g. Gründen modifiziert werden, dies könnte bei Nextcloud-Updates verloren gehen(!)&lt;br /&gt;
* Bestimmte Portbereiche sind bei Hostsharing eingeschränkt, es empfiehlt sich, direkt beispielsweise Port &amp;lt;code&amp;gt;37867&amp;lt;/code&amp;gt; zu nehmen. &amp;lt;strong&amp;gt;aus diesem Grund ist das automatische Setup durch das Plugin bei Hostsharing nicht möglich!&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation ====&lt;br /&gt;
Siehe auch: https://github.com/nextcloud/notify_push#manual-setup &lt;br /&gt;
&lt;br /&gt;
1. Installieren der Nextcloud-App &amp;lt;code&amp;gt;notify_push&amp;lt;/code&amp;gt; – (nach Push suchen, &amp;quot;Client Push&amp;quot; wählen)&amp;lt;br&amp;gt;&lt;br /&gt;
2. falls noch nicht erstellt: &amp;lt;code&amp;gt;mkdir -p ~/.config/systemd/user&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. mit Lieblingseditor die Datei &amp;lt;code&amp;gt;~/.config/systemd/user/notify_push.service&amp;lt;/code&amp;gt; anlegen:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description = Push daemon for Nextcloud clients&lt;br /&gt;
Documentation = https://github.com/nextcloud/notify_push&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Environment = BIND=127.0.0.1&lt;br /&gt;
# Change if you already have something running on this port&lt;br /&gt;
Environment = PORT=37867&lt;br /&gt;
# We don&#039;t want to bind to 0.0.0.0, hence the --bind&lt;br /&gt;
ExecStart = /home/pacs/xyz00/users/cloud/bin/notify_push --bind 127.0.0.1 /home/pacs/xyz00/users/cloud/nextcloud/config/config.php&lt;br /&gt;
Type=notify&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy = default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
4. das Verzeichnis &amp;lt;code&amp;gt;~/bin&amp;lt;/code&amp;gt; anlegen und die aktuellste binary herunterladen und ausführbar machen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot; line&amp;gt;release=`curl -L https://api.github.com/repos/nextcloud/notify_push/releases/latest -s | jq -r &#039;.tag_name&#039;` &amp;amp;&amp;amp; wget --show-progress -qO ~/bin/notify_push https://github.com/nextcloud/notify_push/releases/download/$release/notify_push-x86_64-unknown-linux-musl &amp;amp;&amp;amp; chmod +x ~/bin/notify_push&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
5. es könnte die folgende Umgebungsvariable zum Bedienen von systemd notwendig werden:&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;export XDG_RUNTIME_DIR=/run/user/$UID&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
6. den neuen systemd-Dienst automatisch bei Systemstart, sowie jetzt sofort starten:&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;systemctl enable --now --user notify_push&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
7. nun gehen wir in &amp;lt;code&amp;gt;doms/push.cloud.example.com/htdocs-ssl/.htaccess&amp;lt;/code&amp;gt; und ersetzen den Inhalt (bevorzugt), oder wir ergänzen die .htaccess der Nextcloud im unteren Teil um die folgenden Zeilen (letzteres kann bei Updates überschrieben werden!):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot; line&amp;gt;&lt;br /&gt;
# bei eigener (sub)domain ist /push/ nicht erforderlich, aber wer weiß, eventuell ist das mit robuster&lt;br /&gt;
RewriteCond %{REQUEST_URI}  ^/push/ws    [NC,OR]&lt;br /&gt;
RewriteCond %{HTTP:UPGRADE} ^WebSocket$           [NC,OR]&lt;br /&gt;
RewriteCond %{HTTP:CONNECTION} ^Upgrade$          [NC]&lt;br /&gt;
RewriteRule .* ws://127.0.0.1:37867/ws  [proxy]&lt;br /&gt;
&lt;br /&gt;
RewriteCond %{REQUEST_URI}  ^/push    [NC]&lt;br /&gt;
RewriteRule .* http://127.0.0.1:37867%{REQUEST_URI}  [proxy]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
8. abschließend im Nextcloud Ordner die Konfiguration des Plugins anstoßen: &amp;lt;code&amp;gt;php occ notify_push:setup https://cloud.example.com/push&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;php occ notify_push:setup https://push.cloud.example.com/push&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
9. es ist möglich, das die erkannte IP-Adresse des Hives noch nicht vertraut ist. In diesem Fall wird der obige Befehl scheitern und es muss jene aus der Fehlermeldung des Setups unter &amp;lt;code&amp;gt;trusted_proxies&amp;lt;/code&amp;gt; in der &amp;lt;code&amp;gt;config.php&amp;lt;/code&amp;gt; ergänzt werden. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es wird im Repo außerdem ein Testclient bereitgestellt, der sich testweise mit dem Push-Dienst verbindet&lt;br /&gt;
&lt;br /&gt;
Folgende Befehle helfen ebenfalls beim Debugging:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
~/nextcloud$ php occ notify_push:self-test&lt;br /&gt;
~/nextcloud$ php occ notify_push:metrics&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nextcloud mit Online Office ==&lt;br /&gt;
&lt;br /&gt;
In Nextcloud können Office-Dokumente (Textverarbeitung, Tabellen und Präsentationen) im Browser bearbeitet werden. Dazu steht bei Hostsharing die Collabora Developer Version zur Verfügung. Bestellung und Konfiguration sind hier im Wiki auf der Seite [[Collabora_Online]] beschrieben.&lt;br /&gt;
&lt;br /&gt;
== Nextcloud mit Nextcloud Talk ==&lt;br /&gt;
&lt;br /&gt;
Über die Nextcloud-App &amp;quot;Talk&amp;quot; können Videokonfererenzen mit Screensharing durchgeführt werden. Für die regelmäßige Nutzung kann es sinnvoll sein, einen eigenen TURN Server zu betreiben. Siehe dazu [[Coturn_Installieren]]&lt;br /&gt;
&lt;br /&gt;
Das Hochleistungs-Backend haben wir mittlerweile bei manchen Mitgliedern bereits im Einsatz. Es wird auf einem Container Server installiert. (siehe auch [[Container#Nextcloud_High_Performance_Backend_mit_Caddy|Nextcloud High Performance Backend auf Container Server]])&lt;br /&gt;
&lt;br /&gt;
Unser Mitglied Timotheus Pokorra bietet auch einen Nextcloud High Performance Backend Server zum Teilen an. Siehe [https://solidevereine.de/organisation/nextcloud/#highperf]&lt;br /&gt;
&lt;br /&gt;
Ohne das Hochleistungs-Backend macht wohl die Audio bzw. Video Funktion kaum Sinn, wenn es mit mehr als 2 Teilnehmern genutzt werden soll. Deswegen empfehlen wir, die Anrufe in Talk zu deaktivieren, und stattdessen die BBB zu benutzen.&lt;br /&gt;
&lt;br /&gt;
Das Deaktivieren der Anrufe geschieht in der Administrationsoberfläche von Nextcloud, unter Talk, &amp;quot;Auf Gruppen beschränken&amp;quot;, &amp;quot;Starten von Anrufen begrenzen&amp;quot;: &amp;quot;Anrufe deaktivieren&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Datei:NextcloudTalkAnrufeDeaktivieren.png]]&lt;br /&gt;
&lt;br /&gt;
Die Warnung wegen dem fehlenden Hochleistungs-Backend lässt sich &amp;quot;entschärfen&amp;quot;: in der Einstellungsseite von Talk in der Administrationsoberfläche, ganz oben, deaktiviere: &amp;quot;Vor Verbindungsproblemen bei Anrufen mit mehr als 2 Teilnehmern warnen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Datei:NextcloudTalkWarnungDeaktivieren.png]]&lt;br /&gt;
&lt;br /&gt;
== Virenscanner ==&lt;br /&gt;
&lt;br /&gt;
Einige Nutzer wollen die Dateien in Ihrer Nextcloud regelmäßig auf Viren überprüfen. Auf unseren Servern steht dafür der OpenSource-Virenscanner &amp;quot;ClamAV&amp;quot; zur Verfügung. Wenn dieser Scanner benutzt wird, dann sollten die Einstellungen so gewählt sein, dass der ClamAV-Daemon über eine Socket Verbindung angesprochen wird. Die Einstellungen sind im Screenshot dokumentiert.&lt;br /&gt;
&lt;br /&gt;
* Es wird die App [https://apps.nextcloud.com/apps/files_antivirus Antivirus für Dateien] installiert.&lt;br /&gt;
* Bei Modus wird gewählt: &amp;lt;code&amp;gt;ClamAV-Daemon (Socket)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bei Socket wird gewählt: &amp;lt;code&amp;gt;/var/run/clamav/clamd.ctl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Nextcloud-ClamAV-Einstellungen.png||nextcloud einstellungen für die virenscanner-app]]&lt;br /&gt;
&lt;br /&gt;
== Volltextsuche ==&lt;br /&gt;
&lt;br /&gt;
Über die Dokumente einer Nextcloud kann ein Volltextindex erstellt werden. Die Volltextsuche ermöglicht über den Index eine Suche über beliebige Begriffe, die in Dokumenten vorkommen.&lt;br /&gt;
&lt;br /&gt;
Voraussetzung ist der Betrieb eines Elasticsearch Servers. Der Betrieb im Managed Webspace erfodert die Buchung von zwei &amp;quot;Serverdiensten&amp;quot;. Nutzer eines Managed Server müssen mit einem spürbaren Mehrbedarf an Hauptspeicher rechnen.&lt;br /&gt;
&lt;br /&gt;
Zur Installation von Elasticsearch existiert eine eigene Wikiseite: [[Elasticsearch]].&lt;br /&gt;
&lt;br /&gt;
In der Nextcloud sind folgende &#039;&#039;Apps&#039;&#039; zu installieren:&lt;br /&gt;
* Full Text Search&lt;br /&gt;
* Full Text Search - Elasticsearch Platform&lt;br /&gt;
* Full Text Search - Files&lt;br /&gt;
&lt;br /&gt;
nach der Installation der drei Apps steht in den Einstellungen ein neuer Menüpunkt &amp;quot;Volltextsuche&amp;quot; zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Hier ist einzustellen:&lt;br /&gt;
* Suchplattform: Elasticsearch&lt;br /&gt;
* Adresse des Servlets: http://elastic:das-erzeugt-passwort@127.0.0.1:39200&lt;br /&gt;
* Index: frei-gewaehlter-name-idx&lt;br /&gt;
* Analyzer tokenizer: standard&lt;br /&gt;
&lt;br /&gt;
Die anderen Einstellung nach den eigenen Vorstellungen vornehmen.&lt;br /&gt;
&lt;br /&gt;
Der initiale Aufbau des Suchindex erfolgt über ein &amp;quot;occ&amp;quot;-Kommando auf der Shell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
cd nextcloud/&lt;br /&gt;
php occ fulltextsearch:index --output&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn dieser Fehler kommt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
TypeError: Return value of OCA\Files_FullTextSearch\Model\MountPoint::isGlobal()&lt;br /&gt;
must be of the type bool, null returned in [...]/apps/files_fulltextsearch/lib/Model/MountPoint.php:103&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
sollte dieser Patch angewendet werden: https://github.com/nextcloud/files_fulltextsearch/issues/125#issuecomment-877789742&lt;br /&gt;
&lt;br /&gt;
Zur Pflege des Indexes wird ein weiterer Hintergrundprozess gestartet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
cd nextcloud/&lt;br /&gt;
php occ fulltextsearch:live -q&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Monit Konfiguration dafür sieht so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
#~/bin/start-fulltextsearchlive&lt;br /&gt;
#&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
export HOME=/home/pacs/xyz00/users/cloud&lt;br /&gt;
cd $HOME&lt;br /&gt;
mkdir -p $HOME/var&lt;br /&gt;
cd $HOME/nextcloud&lt;br /&gt;
exec php occ fulltextsearch:live -q &amp;amp;&lt;br /&gt;
echo $! &amp;gt;$HOME/var/fulltextsearchlive.pid&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
#~/bin/stop-fulltextsearchlive&lt;br /&gt;
#&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
export HOME=/home/pacs/xyz00/users/cloud&lt;br /&gt;
kill $( cat $HOME/var/fulltextsearchlive.pid )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/.monitrc (siehe oben von der Redis Installation) entsprechend ergänzen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
check process fulltextsearchlive with pidfile /home/pacs/xyz00/users/cloud/var/fulltextsearchlive.pid&lt;br /&gt;
    start program &amp;quot;/home/pacs/xyz00/users/cloud/bin/start-fulltextsearchlive&amp;quot;&lt;br /&gt;
    stop program &amp;quot;/home/pacs/xyz00/users/cloud/bin/stop-fulltextsearchlive&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Integration mit LDAP ==&lt;br /&gt;
&lt;br /&gt;
Um einheitliche Benutzerzugänge für verschiedene Anwendungen zu ermöglichen, wird oft auf ein zentrales LDAP Verzeichnis gesetzt. &lt;br /&gt;
&lt;br /&gt;
Dieses kann für Nextcloud eingesetzt werden, damit Benutzer nicht lokal in Nextcloud, sondern in LDAP verwaltet werden können.&lt;br /&gt;
&lt;br /&gt;
Siehe auch https://docs.nextcloud.com/server/latest/admin_manual/configuration_user/user_auth_ldap.html&lt;br /&gt;
&lt;br /&gt;
Dazu muss die App &amp;quot;LDAP user and group backend&amp;quot; in den Nextcloud Apps aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
Dann muss die LDAP Anbindung in den Administrationseinstellungen unter &amp;quot;LDAP/AD-Integration&amp;quot; eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Der Server mit Port, die BenutzerDN mit Passwort und die BaseDN müssen eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Es muss auch bestimmt werden, welche Klasse (z.B. inetOrgPerson) die Benutzer brauchen, um Zugriff auf die Nextcloud zu erhalten.&lt;br /&gt;
&lt;br /&gt;
Falls schon Benutzer in der Nextcloud existieren, und diese zu LDAP mitgenommen werden sollen, kann der Anleitung aus diesem Forum Eintrag gefolgt werden: https://help.nextcloud.com/t/migration-to-ldap-keeping-users-and-data/13205&lt;br /&gt;
&lt;br /&gt;
* Voraussetzung ist, dass der Benutzernamen der zu übernehmenden Benutzer in Nextcloud der uid in LDAP entspricht.&lt;br /&gt;
* Es wird ein Administrator Benutzer benötigt, der lokal angelegt wurde, und auch lokal bleibt.&lt;br /&gt;
* Mit diesem Administrator Benutzer wird die LDAP Anbindung eingerichtet.&lt;br /&gt;
* In der Experten Ansicht von LDAP/AD muss bei &amp;quot;Attribut für interne Benutzernamen&amp;quot; eingetragen werden: uid&lt;br /&gt;
* Klicke den Schalter &amp;quot;LDAP Benutzernamenzuordnung löschen&amp;quot;&lt;br /&gt;
* Klicke den Schalter &amp;quot;LDAP Gruppennamenzuordnung löschen&amp;quot;&lt;br /&gt;
* dann in der MySQL Datenbank anmelden, und aus uc_users alle Benutzer bis auf den Administrator Benutzer löschen&lt;br /&gt;
* Dann in der Nextcloud Weboberfläche sich alle Benutzer anzeigen lassen&lt;br /&gt;
* Nun gelingt die Anmeldung mit den anderen Benutzern mit dem LDAP Passwort, und die Dateien wurden übernommen.&lt;br /&gt;
&lt;br /&gt;
== Optimierung der Geschwindigkeit ==&lt;br /&gt;
Manchmal fühlt sich die Nextcloud träge an.&lt;br /&gt;
&lt;br /&gt;
Folgende Änderungen können helfen:&lt;br /&gt;
&lt;br /&gt;
* HTTP/2.0 aktivieren: dem Service von Hostsharing Bescheid geben&lt;br /&gt;
* Die App Dashboard deaktivieren, und dafür werden direkt die Dateien angezeigt&lt;br /&gt;
* Einblenden der README in den Ordnern abschalten: das kann pro Ordner in der UI geschehen (links unten), oder global: &amp;lt;code&amp;gt;occ config:app:set text workspace_available --value=0&amp;lt;/code&amp;gt;. Siehe auch [https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/text_configuration.html#disable-rich-workspaces-globally]&lt;br /&gt;
&lt;br /&gt;
== Default App einstellen ==&lt;br /&gt;
&lt;br /&gt;
In der Datei config.php können wir einstellen, welche App direkt nach der Anmeldung gezeigt wird.&lt;br /&gt;
&lt;br /&gt;
Das ist entweder die Dashboard App, wenn sie aktiviert ist, oder die Dateien App (files).&lt;br /&gt;
&lt;br /&gt;
Falls der Kalender direkt angezeigt werden soll, muss folgende Zeile in der config.php hinzugefügt werden (siehe auch [https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/config_sample_php_parameters.html#defaultapp]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&#039;defaultapp&#039; =&amp;gt; &#039;calendar&#039;,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Nextcloud Updates =&lt;br /&gt;
&lt;br /&gt;
== Updater über die Shell starten ==&lt;br /&gt;
&lt;br /&gt;
Wenn die NextCloud sich nicht über das Webfrontend updaten lässt, kann der Updater auch per Shell im directory /updater durch ausführen des updater.phar gestartet werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php updater/updater.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls während des Updates kein Backup angelegt werden soll:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php updater/updater.phar --no-backup&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es sollten außerdem ein paar Routine-Aufräumarbeiten durchgeführt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:add-missing-primary-keys --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:add-missing-columns --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:add-missing-indices --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:convert-filecache-bigint --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ maintenance:repair --include-expensive&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So können die Apps noch alle aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ app:update --all -n --no-ansi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für weitere Informationen kann auf die offizielle Doku ab Ziffer 2. zurückgegriffen werden.&lt;br /&gt;
&lt;br /&gt;
* [https://docs.nextcloud.com/server/latest/admin_manual/maintenance/update.html#using-the-command-line-based-updater https://docs.nextcloud.com]&lt;br /&gt;
&lt;br /&gt;
Hier gibt es ein kurzes Video, das die Anmeldung über die Kommandozeile mit Putty erklärt und die Aktualisierung von Nextcloud auf der Kommandozeile:&lt;br /&gt;
&lt;br /&gt;
* [https://tube.solidcharity.net/w/0cf5ee97-ba7c-41df-a56f-8d1fea842ab0 Nextcloud auf der Kommandozeile aktualisieren]&lt;br /&gt;
&lt;br /&gt;
== Wartungsmodus per Shell ein- oder ausschalten ==&lt;br /&gt;
&lt;br /&gt;
So kann der Wartungsmodus angeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ maintenance:mode --on&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So kann der Wartungsmodus wieder ausgeschaltet werden, d.h. die Nextcloud ist dann wieder in Betrieb:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ maintenance:mode --off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Webfrontend-Updater Probleme / Lösungen ==&lt;br /&gt;
&lt;br /&gt;
=== Datenbank: Indizes | Primärschlüssel | Konvertierungen ===&lt;br /&gt;
&lt;br /&gt;
Aufgetreten nach erfolgtem Versionsupdate Nextcloud 19 auf Nextcloud 20&lt;br /&gt;
&lt;br /&gt;
Nach dem erfolgten Update lädt automatisch die Seite: &#039;&#039;&#039;Sicherheits- und Einrichtungswarnungen&#039;&#039;&#039; auf dieser wird angemerkt, dass manuelle Schritte für die Datenbank durchzuführen sind. Dies betrifft Indizes, Primärschlüssel und Konvertierungen. &lt;br /&gt;
&lt;br /&gt;
Per Shell in der directory /nextcloud folgende Kommandos ausführen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:add-missing-primary-keys --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:add-missing-columns --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:add-missing-indices --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:convert-filecache-bigint --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ maintenance:repair --include-expensive&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig ist hier dem durch Nextcloud angegebenen Kommando ein &#039;&#039;&#039;php&#039;&#039;&#039; voranzustellen.&lt;br /&gt;
&lt;br /&gt;
== Update per Skript ==&lt;br /&gt;
&lt;br /&gt;
Es ist möglich die regelmäßigen Updates weitgehend zu automatisieren. Ein Skript wäre etwa:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
if [ -f $HOME/nextcloud/occ ]; then &lt;br /&gt;
  echo &amp;quot;Nextcloud Update&amp;quot;; &lt;br /&gt;
  cd $HOME/nextcloud;&lt;br /&gt;
  php updater/updater.phar -vv --no-backup --no-interaction&lt;br /&gt;
  php occ maintenance:mode --on&lt;br /&gt;
  php occ db:add-missing-primary-keys --no-interaction&lt;br /&gt;
  php occ db:add-missing-columns --no-interaction&lt;br /&gt;
  php occ db:add-missing-indices --no-interaction&lt;br /&gt;
  php occ db:convert-filecache-bigint --no-interaction&lt;br /&gt;
  php occ maintenance:repair --include-expensive&lt;br /&gt;
  php occ app:update --all&lt;br /&gt;
  php occ maintenance:mode --off&lt;br /&gt;
else &lt;br /&gt;
  echo &amp;quot;Keine Nextcloud Installation gefunden&amp;quot;; &lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Update: bei old-stable Version bleiben ==&lt;br /&gt;
&lt;br /&gt;
Normalerweise fragt jede Nextcloud Instanz zentral ab, welches Update zur Verfügung steht, abhängig vom Release Channel. Dabei wird aber relativ schnell auf die nächste Version gewechselt, also z.B. von Nextcloud 31 auf Nextcloud 32, obwohl Nextcloud 31 noch mehrere Monate gepflegt wird, und manche Apps noch nicht bereit sind für Nextcloud 32.&lt;br /&gt;
&lt;br /&gt;
Es kann aber auch eine Alternative eingerichtet werden, in der Datei nextcloud/config/config.php, unter dem Eintrag updater.server.url&lt;br /&gt;
&lt;br /&gt;
Hier wird z.B. auf einen Updater von unserem Mitglied Timotheus Pokorra verwiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php line&amp;gt;&lt;br /&gt;
updater_server_url: &amp;quot;https://ncupdater.solidcharity.com/31/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dahinter läuft ein Skript, mit dem wir noch länger eine bestimmte Version anbieten können: https://codeberg.org/tpokorra/ncupdater&lt;br /&gt;
&lt;br /&gt;
= Daten auf HDD Storage =&lt;br /&gt;
== Einrichtung des HDD Storage ==&lt;br /&gt;
&lt;br /&gt;
Um den langsameren aber günstigeren HDD Storage von Hostsharing zu nutzen, kann das data Verzeichnis von SSD auf HDD Storage verschoben werden. Ein symbolischer Link reicht nicht aus, man muss den Pfad in der Nextcloud Konfigurationsdatei anpassen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
# Nextcloud in Wartungsmodus versetzen&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ maintenance:mode --on&lt;br /&gt;
# Daten auf HDD Storage verschieben&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ mv data /home/storage/xyz00/users/cloud/&lt;br /&gt;
# symbolischen Link anlegen&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ ln -s /home/storage/xyz00/users/cloud/data data&lt;br /&gt;
# Pfad in config.php ändern&lt;br /&gt;
nano config/config.php&lt;br /&gt;
# Die Zeile mit &#039;datadirectory&#039; finden und entsprechend ändern:&lt;br /&gt;
# &#039;datadirectory&#039; =&amp;gt; &#039;/home/storage/xyz00/users/cloud/data&#039;,&lt;br /&gt;
# Wartungsmodus beenden&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ maintenance:mode --off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Fallstrick: Im data-Verzeichnis liegt eine versteckte Datei &amp;quot;.ncdata&amp;quot;. Beim Move-Befehl &amp;quot;mv&amp;quot; für das komplette Data-Verzeichnis wird diese Datei mit verschoben. Sonst muss die Datei ggf. ins neue data-Verzeichnis kopiert werden!&lt;br /&gt;
&lt;br /&gt;
= Einschränkende Bemerkungen =&lt;br /&gt;
== Nextcloud Sync Client ==&lt;br /&gt;
&lt;br /&gt;
Der Nextcloud Sync Client erfüllt eine Funktion ähnlich wie Dropbox, und synchronisiert ganze Ordnerstrukturen. &lt;br /&gt;
&lt;br /&gt;
Gerade wenn man mit mehreren Menschen in einer Nextcloud arbeitet, ist diese Funktion mit Vorsicht zu benutzen.&lt;br /&gt;
&lt;br /&gt;
* Änderungen an der Ordnerstruktur sollten nicht lokal, sondern im Webbrowser vorgenommen werden.&lt;br /&gt;
* Wenn die Gefahr besteht, dass mehrere Menschen gleichzeitig eine Datei bearbeiten, sollte die Datei nicht lokal, sondern im Webbrowser bearbeitet werden.&lt;br /&gt;
* Aus Sicht des Datenschutzes und der Daten-Minimierung sollte überlegt werden, ob die Daten wirklich auf jeden Laptop und Rechner synchronisiert werden sollen, oder ob es reicht, ausschließlich über den Webbrowser auf die Daten zuzugreifen.&lt;br /&gt;
&lt;br /&gt;
= weiterführende Links =&lt;br /&gt;
&lt;br /&gt;
* [https://docs.nextcloud.com/ Nextcloud Dokumentation]&lt;br /&gt;
* [https://apps.nextcloud.com/ Nextcloud Erweiterungen (&amp;quot;Apps&amp;quot;)]&lt;br /&gt;
* [https://docs.nextcloud.com/server/stable/admin_manual/installation/server_tuning.html Optimierung des Caches z.B. für Previews]&lt;br /&gt;
* [https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/nextcloud Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
= Nextcloud Reseller bei HS =&lt;br /&gt;
&lt;br /&gt;
[https://nextcloud.ossaas.de OS SaaS]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:CalDAV]]&lt;br /&gt;
[[Kategorie:Nextcloud]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Nextcloud&amp;diff=7641</id>
		<title>Nextcloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Nextcloud&amp;diff=7641"/>
		<updated>2026-09-04T20:28:36Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Installation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Nextcloud =&lt;br /&gt;
&lt;br /&gt;
[https://nextcloud.com/ Nextcloud] ist eine PHP-basierte Open Source Lösung für gängige Cloud-Anwendungen, u.a.:&lt;br /&gt;
&lt;br /&gt;
* Filesharing unter Nutzern derselben Nextcloud, und mit der Öffentlichkeit&lt;br /&gt;
* Single-Sign-On Authentifizierung (SSO)&lt;br /&gt;
* Videokonferenzen (WebRTC)&lt;br /&gt;
* Online-Office Anwendung [https://www.collaboraoffice.com/ Collabora Online]&lt;br /&gt;
&lt;br /&gt;
Beispiel-Funktionalität, die über Plugins, sogenannte [https://apps.nextcloud.com/ &amp;quot;Apps&amp;quot;], bereit gestellt werden kann:&lt;br /&gt;
&lt;br /&gt;
* Kalender, Aufgabenverwaltung, Adressbuch&lt;br /&gt;
* Datei-Kollaboration (Kommentare zu Dateien, Verschlagwortung)&lt;br /&gt;
* Feedreader&lt;br /&gt;
* E-Mail-Programm&lt;br /&gt;
* Fotogalerie&lt;br /&gt;
* Musik- und Videowiedergabe&lt;br /&gt;
&lt;br /&gt;
= Nextcloud installieren =&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;cloud.example.org&#039;&#039;&lt;br /&gt;
* PostgreSQL-User &lt;br /&gt;
* PostgreSQL Datenbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-cloud&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Nextcloud&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;cloud.example.org&#039;,user:&#039;xyz00-cloud&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; postgresqluser.add({set:{name:&#039;xyz00_nextclusr&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; postgresqldb.add({set:{name:&#039;xyz00_nextcloud&#039;,owner:&#039;xyz00_nextclusr&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nextcloud installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-cloud&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
ssh -l xyz00-cloud xyz00.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd&lt;br /&gt;
mkdir nextcloud&lt;br /&gt;
cd doms/cloud.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www htdocs-ssl&lt;br /&gt;
ln -s $HOME/nextcloud htdocs-ssl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls der &#039;&#039;Redirect&#039;&#039; auf die Domain &#039;&#039;example.org&#039;&#039; umleitet statt auf die Subdomain &#039;&#039;cloud.example.org&#039;&#039;, kann diese Aktion helfen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/cloud.example.org&lt;br /&gt;
mkdir -p subs-ssl/www&lt;br /&gt;
cp htdocs/.htaccess subs-ssl/www/.htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nextcloud herunterladen und entpacken.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd &lt;br /&gt;
wget https://download.nextcloud.com/server/releases/nextcloud-30.0.6.zip&lt;br /&gt;
unzip nextcloud-30.0.6.zip &lt;br /&gt;
rm nextcloud-30.0.6.zip&lt;br /&gt;
mkdir data tmp&lt;br /&gt;
chmod 700 data tmp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um Probleme mit der Anmeldung der Nextcloud App am Mobilgerät zu vermeiden, müssen folgende Zeilen in der Datei &amp;lt;code&amp;gt;doms/cloud.example.org/.htaccess&amp;lt;/code&amp;gt; eingefügt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=htaccess&amp;gt;&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteCond %{HTTP:Authorization} ^(.*)&lt;br /&gt;
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nextcloud konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Verzeichnis &amp;quot;$HOME/doms/cloud.example.org/fastcgi-ssl/&amp;quot; eine Datei &amp;quot;php.ini&amp;quot; anlegen mit folgendem Inhalt: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini&amp;gt;&lt;br /&gt;
memory_limit=512M&lt;br /&gt;
session.save_path=/home/pacs/xyz00/users/cloud/tmp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann mit einem Editor diese Datei bearbeiten: In der zweiten Zeile den korrekten Pfad des vorher angelegten tmp-Verzeichnisses eintragen.&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://cloud.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
Auf der ersten Seite sind anzugeben:&lt;br /&gt;
&lt;br /&gt;
* Login und Passwort für den Administrator definieren&lt;br /&gt;
* PostgreSQL als Datenbanksystem&lt;br /&gt;
* PostgreSQL-User und Passwort aus dem ersten Schritt oben&lt;br /&gt;
* Name der PostgreSQL-Datenbank aus dem ersten Schritt&lt;br /&gt;
* &amp;quot;localhost&amp;quot; als Datenbankserver (Nextcloud 23.0.2 empfiehlt hier die Angabe des Ports, diesen also lt. [[PostgreSQL]] angeben)&lt;br /&gt;
* Das Verzeichnis &amp;quot;/home/pacs/xyz00/users/cloud/data/&amp;quot; als Daten-Verzeichnis (bitte beachten: das im Eingabefeld voreingestellte verweist auf das Verzeichnis &amp;quot;/home/pacs/xyz00/users/cloud/&#039;&#039;&#039;nextcloud&#039;&#039;&#039;/data/&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung!&#039;&#039;&#039; Die Felder für die Datenbank sind auf dem Startscreen hinter einem unscheinbaren Link versteckt. Um man das Formular für die Datenbank-Daten zu gelangen, muss man auf den Link klicken. Anschließend kann man die gewünschte Datenbank auswählen und die entsprechenden Daten eintragen. &#039;&#039;&#039;Das sollte geschehen, bevor man die Installation abschließt!&#039;&#039;&#039; Tut man dies nicht, wird Nextcloud mit SQLite installiert. Eine Änderung der Datenbank soll zwar laut Dokumentation auch später noch möglich sein, ging aber bei einem Test schief.&lt;br /&gt;
&lt;br /&gt;
In der Konfigurationsdatei der Nextcloud (in &#039;&#039;~/nextcloud/config/config.php&#039;&#039;) lassen sich weitere Voreinstellungen treffen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php line&amp;gt;&lt;br /&gt;
&#039;maintenance_window_start&#039; =&amp;gt; 1,    // Wartungsfenster ab 1:00 Uhr&lt;br /&gt;
&#039;defaultapp&#039; =&amp;gt; &#039;calendar,files&#039;,   // bei Start wird der Kalender gezeigt&lt;br /&gt;
&#039;default_phone_region&#039; =&amp;gt; &#039;DE&#039;,     // Format Telefonnummern&lt;br /&gt;
&#039;default_language&#039; =&amp;gt; &#039;de&#039;,         // Sprache deutsch&lt;br /&gt;
&#039;force_language&#039; =&amp;gt; &#039;de&#039;,&lt;br /&gt;
&#039;default_locale&#039; =&amp;gt; &#039;de_DE&#039;,        // Locale (Formatierung Zeitangaben etc.) &lt;br /&gt;
&#039;force_locale&#039; =&amp;gt; &#039;de_DE&#039;,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nextcloud beschleunigen ==&lt;br /&gt;
&lt;br /&gt;
Dieser Teil ist optional.&lt;br /&gt;
&lt;br /&gt;
Wenn regelmäßig &#039;&#039;&#039;im Browser&#039;&#039;&#039; mit Nextcloud gearbeitet werden soll, ist Nextcloud im Browser oft sehr langsam. Um dies zu verbessern, unterstützt Nextcloud die Anwendung von unterschiedlichen Cache-Verfahren (zum Beispiel Memcache, Redis).&lt;br /&gt;
&lt;br /&gt;
=== Redis Cache ===&lt;br /&gt;
&lt;br /&gt;
Redis ist auf den Hostsharing-Servern vorinstalliert und wird von den Nextcloud-Entwicklern empfohlen. Redis wird als eigener Serverdienst gestartet. &#039;&#039;&#039;In Verbindung mit Hostsharing Managed Webspace muss für Redis [https://www.hostsharing.net/paas/managed-webspace/ Arbeitsspeicher für eigene Serverdienste] gebucht werden&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Die Konfiguration des Redis-Dientes ist auf der Seite [[Redis]] beschrieben. Hier wird für Nextcloud die Variante mit einem Unixsocket benutzt.&lt;br /&gt;
&lt;br /&gt;
In der Konfiguration der Nextcloud (in &#039;&#039;~/nextcloud/config/config.php&#039;&#039;) wird der Redis-Cache wie folgt konfiguriert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php line&amp;gt;&lt;br /&gt;
&#039;memcache.local&#039; =&amp;gt; &#039;\\OC\\Memcache\\Redis&#039;,&lt;br /&gt;
&#039;memcache.distributed&#039; =&amp;gt; &#039;\\OC\\Memcache\\Redis&#039;,&lt;br /&gt;
&#039;memcache.locking&#039; =&amp;gt; &#039;\\OC\\Memcache\\Redis&#039;,&lt;br /&gt;
&#039;redis&#039; =&amp;gt; &lt;br /&gt;
  array (&lt;br /&gt;
    &#039;host&#039; =&amp;gt; &#039;/home/pacs/xyz00/users/cloud/redis/var/redis-server.sock&#039;,&lt;br /&gt;
    &#039;port&#039; =&amp;gt; 0,&lt;br /&gt;
    &#039;password&#039; =&amp;gt; &#039;mein-redis-passwort&#039;,&lt;br /&gt;
    &#039;timeout&#039; =&amp;gt; 1.5,&lt;br /&gt;
  ),&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um es perfekt zu machen, nutze ich &#039;&#039;logrotate&#039;&#039; um die Logdateien zu organisieren. Dazu die Konfiguration in &#039;&#039;~/.logrotate&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
compress&lt;br /&gt;
/home/pacs/xyz00/users/cloud/redis/var/redis.log {&lt;br /&gt;
  rotate 5&lt;br /&gt;
  daily&lt;br /&gt;
  missingok&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Mit systemd-Timern werden die Logdateien täglich rotiert:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;~/.config/systemd/user/logrotate.service&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=rotate log files&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=oneshot&lt;br /&gt;
ExecStart=/usr/sbin/logrotate -s %h/.logrotate.state %h/.logrotate&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;~/.config/systemd/user/logrotate.timer&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=timer for nextcloud cleanup job&lt;br /&gt;
&lt;br /&gt;
[Timer]&lt;br /&gt;
OnCalendar=1:1&lt;br /&gt;
Persistent=True&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=timers.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Timer aktivieren und starten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
$ systemctl --user enable logrotate.timer&lt;br /&gt;
$ systemctl --user start logrotate.timer&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nextcloud Cronjob ===&lt;br /&gt;
&lt;br /&gt;
Für die regelmäßigen Hintergrundaufgaben innerhalb der Nextcloud sollte ein Cronjob eingerichtet werden. Wir lösen dies hier mit einem weiteren Systemd-Timer:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;~/.config/systemd/user/nextcloud_background.service&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=nextcloud cleanup job&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=oneshot&lt;br /&gt;
ExecStart=/usr/bin/php %h/nextcloud/cron.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;~/.config/systemd/user/nextcloud_background.timer&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=timer for nextcloud cleanup job&lt;br /&gt;
&lt;br /&gt;
[Timer]&lt;br /&gt;
OnCalendar=*:0/5&lt;br /&gt;
Persistent=True&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=timers.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Timer aktivieren und starten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
$ systemctl --user enable nextcloud_background.timer&lt;br /&gt;
$ systemctl --user start nextcloud_background.timer&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nextcloud Push ===&lt;br /&gt;
&lt;br /&gt;
Um Vorgänge wie Sync und Benachrichtigungen bei sehr großen Nextcloud Installationen zu beschleunigen, kann der &amp;lt;code&amp;gt;notify_push&amp;lt;/code&amp;gt; Dienst hinzuinstalliert werden.&lt;br /&gt;
&lt;br /&gt;
==== Abhängigkeiten und Einschränkungen ====&lt;br /&gt;
* &amp;lt;code&amp;gt;notify_push&amp;lt;/code&amp;gt; muss Zugriff auf den gleichen Redis-Cache wie die Nextcloud haben &lt;br /&gt;
** aufgrund von eingeschränktem Passwort Support sollte ein Redis Socket mit sicheren Berechtigungseinstellungen als Alternative zum Redis Port mit Passwort konfiguriert werden.&lt;br /&gt;
* optimaler Weise holt sich &amp;lt;code&amp;gt;notify_push&amp;lt;/code&amp;gt; benötigte informationen aus der &amp;lt;code&amp;gt;config.php&amp;lt;/code&amp;gt; der bestehenden Nextcloud-Installation&lt;br /&gt;
* eine zusätzliche (Sub)domain im gleichen User ist nötig. Andernfalls muss die bestehende &amp;lt;code&amp;gt;.htaccess&amp;lt;/code&amp;gt; muss aus o.g. Gründen modifiziert werden, dies könnte bei Nextcloud-Updates verloren gehen(!)&lt;br /&gt;
* Bestimmte Portbereiche sind bei Hostsharing eingeschränkt, es empfiehlt sich, direkt beispielsweise Port &amp;lt;code&amp;gt;37867&amp;lt;/code&amp;gt; zu nehmen. &amp;lt;strong&amp;gt;aus diesem Grund ist das automatische Setup durch das Plugin bei Hostsharing nicht möglich!&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation ====&lt;br /&gt;
Siehe auch: https://github.com/nextcloud/notify_push#manual-setup &lt;br /&gt;
&lt;br /&gt;
1. Installieren der Nextcloud-App &amp;lt;code&amp;gt;notify_push&amp;lt;/code&amp;gt; – (nach Push suchen, &amp;quot;Client Push&amp;quot; wählen)&amp;lt;br&amp;gt;&lt;br /&gt;
2. falls noch nicht erstellt: &amp;lt;code&amp;gt;mkdir -p ~/.config/systemd/user&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. mit Lieblingseditor die Datei &amp;lt;code&amp;gt;~/.config/systemd/user/notify_push.service&amp;lt;/code&amp;gt; anlegen:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description = Push daemon for Nextcloud clients&lt;br /&gt;
Documentation = https://github.com/nextcloud/notify_push&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Environment = BIND=127.0.0.1&lt;br /&gt;
# Change if you already have something running on this port&lt;br /&gt;
Environment = PORT=37867&lt;br /&gt;
# We don&#039;t want to bind to 0.0.0.0, hence the --bind&lt;br /&gt;
ExecStart = /home/pacs/xyz00/users/cloud/bin/notify_push --bind 127.0.0.1 /home/pacs/xyz00/users/cloud/nextcloud/config/config.php&lt;br /&gt;
Type=notify&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy = default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
4. das Verzeichnis &amp;lt;code&amp;gt;~/bin&amp;lt;/code&amp;gt; anlegen und die aktuellste binary herunterladen und ausführbar machen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot; line&amp;gt;release=`curl -L https://api.github.com/repos/nextcloud/notify_push/releases/latest -s | jq -r &#039;.tag_name&#039;` &amp;amp;&amp;amp; wget --show-progress -qO ~/bin/notify_push https://github.com/nextcloud/notify_push/releases/download/$release/notify_push-x86_64-unknown-linux-musl &amp;amp;&amp;amp; chmod +x ~/bin/notify_push&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
5. es könnte die folgende Umgebungsvariable zum Bedienen von systemd notwendig werden:&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;export XDG_RUNTIME_DIR=/run/user/$UID&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
6. den neuen systemd-Dienst automatisch bei Systemstart, sowie jetzt sofort starten:&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;systemctl enable --now --user notify_push&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
7. nun gehen wir in &amp;lt;code&amp;gt;doms/push.cloud.example.com/htdocs-ssl/.htaccess&amp;lt;/code&amp;gt; und ersetzen den Inhalt (bevorzugt), oder wir ergänzen die .htaccess der Nextcloud im unteren Teil um die folgenden Zeilen (letzteres kann bei Updates überschrieben werden!):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot; line&amp;gt;&lt;br /&gt;
# bei eigener (sub)domain ist /push/ nicht erforderlich, aber wer weiß, eventuell ist das mit robuster&lt;br /&gt;
RewriteCond %{REQUEST_URI}  ^/push/ws    [NC,OR]&lt;br /&gt;
RewriteCond %{HTTP:UPGRADE} ^WebSocket$           [NC,OR]&lt;br /&gt;
RewriteCond %{HTTP:CONNECTION} ^Upgrade$          [NC]&lt;br /&gt;
RewriteRule .* ws://127.0.0.1:37867/ws  [proxy]&lt;br /&gt;
&lt;br /&gt;
RewriteCond %{REQUEST_URI}  ^/push    [NC]&lt;br /&gt;
RewriteRule .* http://127.0.0.1:37867%{REQUEST_URI}  [proxy]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
8. abschließend im Nextcloud Ordner die Konfiguration des Plugins anstoßen: &amp;lt;code&amp;gt;php occ notify_push:setup https://cloud.example.com/push&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;php occ notify_push:setup https://push.cloud.example.com/push&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
9. es ist möglich, das die erkannte IP-Adresse des Hives noch nicht vertraut ist. In diesem Fall wird der obige Befehl scheitern und es muss jene aus der Fehlermeldung des Setups unter &amp;lt;code&amp;gt;trusted_proxies&amp;lt;/code&amp;gt; in der &amp;lt;code&amp;gt;config.php&amp;lt;/code&amp;gt; ergänzt werden. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es wird im Repo außerdem ein Testclient bereitgestellt, der sich testweise mit dem Push-Dienst verbindet&lt;br /&gt;
&lt;br /&gt;
== Nextcloud mit Online Office ==&lt;br /&gt;
&lt;br /&gt;
In Nextcloud können Office-Dokumente (Textverarbeitung, Tabellen und Präsentationen) im Browser bearbeitet werden. Dazu steht bei Hostsharing die Collabora Developer Version zur Verfügung. Bestellung und Konfiguration sind hier im Wiki auf der Seite [[Collabora_Online]] beschrieben.&lt;br /&gt;
&lt;br /&gt;
== Nextcloud mit Nextcloud Talk ==&lt;br /&gt;
&lt;br /&gt;
Über die Nextcloud-App &amp;quot;Talk&amp;quot; können Videokonfererenzen mit Screensharing durchgeführt werden. Für die regelmäßige Nutzung kann es sinnvoll sein, einen eigenen TURN Server zu betreiben. Siehe dazu [[Coturn_Installieren]]&lt;br /&gt;
&lt;br /&gt;
Das Hochleistungs-Backend haben wir mittlerweile bei manchen Mitgliedern bereits im Einsatz. Es wird auf einem Container Server installiert. (siehe auch [[Container#Nextcloud_High_Performance_Backend_mit_Caddy|Nextcloud High Performance Backend auf Container Server]])&lt;br /&gt;
&lt;br /&gt;
Unser Mitglied Timotheus Pokorra bietet auch einen Nextcloud High Performance Backend Server zum Teilen an. Siehe [https://solidevereine.de/organisation/nextcloud/#highperf]&lt;br /&gt;
&lt;br /&gt;
Ohne das Hochleistungs-Backend macht wohl die Audio bzw. Video Funktion kaum Sinn, wenn es mit mehr als 2 Teilnehmern genutzt werden soll. Deswegen empfehlen wir, die Anrufe in Talk zu deaktivieren, und stattdessen die BBB zu benutzen.&lt;br /&gt;
&lt;br /&gt;
Das Deaktivieren der Anrufe geschieht in der Administrationsoberfläche von Nextcloud, unter Talk, &amp;quot;Auf Gruppen beschränken&amp;quot;, &amp;quot;Starten von Anrufen begrenzen&amp;quot;: &amp;quot;Anrufe deaktivieren&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Datei:NextcloudTalkAnrufeDeaktivieren.png]]&lt;br /&gt;
&lt;br /&gt;
Die Warnung wegen dem fehlenden Hochleistungs-Backend lässt sich &amp;quot;entschärfen&amp;quot;: in der Einstellungsseite von Talk in der Administrationsoberfläche, ganz oben, deaktiviere: &amp;quot;Vor Verbindungsproblemen bei Anrufen mit mehr als 2 Teilnehmern warnen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Datei:NextcloudTalkWarnungDeaktivieren.png]]&lt;br /&gt;
&lt;br /&gt;
== Virenscanner ==&lt;br /&gt;
&lt;br /&gt;
Einige Nutzer wollen die Dateien in Ihrer Nextcloud regelmäßig auf Viren überprüfen. Auf unseren Servern steht dafür der OpenSource-Virenscanner &amp;quot;ClamAV&amp;quot; zur Verfügung. Wenn dieser Scanner benutzt wird, dann sollten die Einstellungen so gewählt sein, dass der ClamAV-Daemon über eine Socket Verbindung angesprochen wird. Die Einstellungen sind im Screenshot dokumentiert.&lt;br /&gt;
&lt;br /&gt;
* Es wird die App [https://apps.nextcloud.com/apps/files_antivirus Antivirus für Dateien] installiert.&lt;br /&gt;
* Bei Modus wird gewählt: &amp;lt;code&amp;gt;ClamAV-Daemon (Socket)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Bei Socket wird gewählt: &amp;lt;code&amp;gt;/var/run/clamav/clamd.ctl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Nextcloud-ClamAV-Einstellungen.png||nextcloud einstellungen für die virenscanner-app]]&lt;br /&gt;
&lt;br /&gt;
== Volltextsuche ==&lt;br /&gt;
&lt;br /&gt;
Über die Dokumente einer Nextcloud kann ein Volltextindex erstellt werden. Die Volltextsuche ermöglicht über den Index eine Suche über beliebige Begriffe, die in Dokumenten vorkommen.&lt;br /&gt;
&lt;br /&gt;
Voraussetzung ist der Betrieb eines Elasticsearch Servers. Der Betrieb im Managed Webspace erfodert die Buchung von zwei &amp;quot;Serverdiensten&amp;quot;. Nutzer eines Managed Server müssen mit einem spürbaren Mehrbedarf an Hauptspeicher rechnen.&lt;br /&gt;
&lt;br /&gt;
Zur Installation von Elasticsearch existiert eine eigene Wikiseite: [[Elasticsearch]].&lt;br /&gt;
&lt;br /&gt;
In der Nextcloud sind folgende &#039;&#039;Apps&#039;&#039; zu installieren:&lt;br /&gt;
* Full Text Search&lt;br /&gt;
* Full Text Search - Elasticsearch Platform&lt;br /&gt;
* Full Text Search - Files&lt;br /&gt;
&lt;br /&gt;
nach der Installation der drei Apps steht in den Einstellungen ein neuer Menüpunkt &amp;quot;Volltextsuche&amp;quot; zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Hier ist einzustellen:&lt;br /&gt;
* Suchplattform: Elasticsearch&lt;br /&gt;
* Adresse des Servlets: http://elastic:das-erzeugt-passwort@127.0.0.1:39200&lt;br /&gt;
* Index: frei-gewaehlter-name-idx&lt;br /&gt;
* Analyzer tokenizer: standard&lt;br /&gt;
&lt;br /&gt;
Die anderen Einstellung nach den eigenen Vorstellungen vornehmen.&lt;br /&gt;
&lt;br /&gt;
Der initiale Aufbau des Suchindex erfolgt über ein &amp;quot;occ&amp;quot;-Kommando auf der Shell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
cd nextcloud/&lt;br /&gt;
php occ fulltextsearch:index --output&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn dieser Fehler kommt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
TypeError: Return value of OCA\Files_FullTextSearch\Model\MountPoint::isGlobal()&lt;br /&gt;
must be of the type bool, null returned in [...]/apps/files_fulltextsearch/lib/Model/MountPoint.php:103&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
sollte dieser Patch angewendet werden: https://github.com/nextcloud/files_fulltextsearch/issues/125#issuecomment-877789742&lt;br /&gt;
&lt;br /&gt;
Zur Pflege des Indexes wird ein weiterer Hintergrundprozess gestartet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
cd nextcloud/&lt;br /&gt;
php occ fulltextsearch:live -q&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Monit Konfiguration dafür sieht so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
#~/bin/start-fulltextsearchlive&lt;br /&gt;
#&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
export HOME=/home/pacs/xyz00/users/cloud&lt;br /&gt;
cd $HOME&lt;br /&gt;
mkdir -p $HOME/var&lt;br /&gt;
cd $HOME/nextcloud&lt;br /&gt;
exec php occ fulltextsearch:live -q &amp;amp;&lt;br /&gt;
echo $! &amp;gt;$HOME/var/fulltextsearchlive.pid&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
#~/bin/stop-fulltextsearchlive&lt;br /&gt;
#&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
export HOME=/home/pacs/xyz00/users/cloud&lt;br /&gt;
kill $( cat $HOME/var/fulltextsearchlive.pid )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/.monitrc (siehe oben von der Redis Installation) entsprechend ergänzen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
check process fulltextsearchlive with pidfile /home/pacs/xyz00/users/cloud/var/fulltextsearchlive.pid&lt;br /&gt;
    start program &amp;quot;/home/pacs/xyz00/users/cloud/bin/start-fulltextsearchlive&amp;quot;&lt;br /&gt;
    stop program &amp;quot;/home/pacs/xyz00/users/cloud/bin/stop-fulltextsearchlive&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Integration mit LDAP ==&lt;br /&gt;
&lt;br /&gt;
Um einheitliche Benutzerzugänge für verschiedene Anwendungen zu ermöglichen, wird oft auf ein zentrales LDAP Verzeichnis gesetzt. &lt;br /&gt;
&lt;br /&gt;
Dieses kann für Nextcloud eingesetzt werden, damit Benutzer nicht lokal in Nextcloud, sondern in LDAP verwaltet werden können.&lt;br /&gt;
&lt;br /&gt;
Siehe auch https://docs.nextcloud.com/server/latest/admin_manual/configuration_user/user_auth_ldap.html&lt;br /&gt;
&lt;br /&gt;
Dazu muss die App &amp;quot;LDAP user and group backend&amp;quot; in den Nextcloud Apps aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
Dann muss die LDAP Anbindung in den Administrationseinstellungen unter &amp;quot;LDAP/AD-Integration&amp;quot; eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Der Server mit Port, die BenutzerDN mit Passwort und die BaseDN müssen eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Es muss auch bestimmt werden, welche Klasse (z.B. inetOrgPerson) die Benutzer brauchen, um Zugriff auf die Nextcloud zu erhalten.&lt;br /&gt;
&lt;br /&gt;
Falls schon Benutzer in der Nextcloud existieren, und diese zu LDAP mitgenommen werden sollen, kann der Anleitung aus diesem Forum Eintrag gefolgt werden: https://help.nextcloud.com/t/migration-to-ldap-keeping-users-and-data/13205&lt;br /&gt;
&lt;br /&gt;
* Voraussetzung ist, dass der Benutzernamen der zu übernehmenden Benutzer in Nextcloud der uid in LDAP entspricht.&lt;br /&gt;
* Es wird ein Administrator Benutzer benötigt, der lokal angelegt wurde, und auch lokal bleibt.&lt;br /&gt;
* Mit diesem Administrator Benutzer wird die LDAP Anbindung eingerichtet.&lt;br /&gt;
* In der Experten Ansicht von LDAP/AD muss bei &amp;quot;Attribut für interne Benutzernamen&amp;quot; eingetragen werden: uid&lt;br /&gt;
* Klicke den Schalter &amp;quot;LDAP Benutzernamenzuordnung löschen&amp;quot;&lt;br /&gt;
* Klicke den Schalter &amp;quot;LDAP Gruppennamenzuordnung löschen&amp;quot;&lt;br /&gt;
* dann in der MySQL Datenbank anmelden, und aus uc_users alle Benutzer bis auf den Administrator Benutzer löschen&lt;br /&gt;
* Dann in der Nextcloud Weboberfläche sich alle Benutzer anzeigen lassen&lt;br /&gt;
* Nun gelingt die Anmeldung mit den anderen Benutzern mit dem LDAP Passwort, und die Dateien wurden übernommen.&lt;br /&gt;
&lt;br /&gt;
== Optimierung der Geschwindigkeit ==&lt;br /&gt;
Manchmal fühlt sich die Nextcloud träge an.&lt;br /&gt;
&lt;br /&gt;
Folgende Änderungen können helfen:&lt;br /&gt;
&lt;br /&gt;
* HTTP/2.0 aktivieren: dem Service von Hostsharing Bescheid geben&lt;br /&gt;
* Die App Dashboard deaktivieren, und dafür werden direkt die Dateien angezeigt&lt;br /&gt;
* Einblenden der README in den Ordnern abschalten: das kann pro Ordner in der UI geschehen (links unten), oder global: &amp;lt;code&amp;gt;occ config:app:set text workspace_available --value=0&amp;lt;/code&amp;gt;. Siehe auch [https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/text_configuration.html#disable-rich-workspaces-globally]&lt;br /&gt;
&lt;br /&gt;
== Default App einstellen ==&lt;br /&gt;
&lt;br /&gt;
In der Datei config.php können wir einstellen, welche App direkt nach der Anmeldung gezeigt wird.&lt;br /&gt;
&lt;br /&gt;
Das ist entweder die Dashboard App, wenn sie aktiviert ist, oder die Dateien App (files).&lt;br /&gt;
&lt;br /&gt;
Falls der Kalender direkt angezeigt werden soll, muss folgende Zeile in der config.php hinzugefügt werden (siehe auch [https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/config_sample_php_parameters.html#defaultapp]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&#039;defaultapp&#039; =&amp;gt; &#039;calendar&#039;,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Nextcloud Updates =&lt;br /&gt;
&lt;br /&gt;
== Updater über die Shell starten ==&lt;br /&gt;
&lt;br /&gt;
Wenn die NextCloud sich nicht über das Webfrontend updaten lässt, kann der Updater auch per Shell im directory /updater durch ausführen des updater.phar gestartet werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php updater/updater.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls während des Updates kein Backup angelegt werden soll:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php updater/updater.phar --no-backup&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es sollten außerdem ein paar Routine-Aufräumarbeiten durchgeführt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:add-missing-primary-keys --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:add-missing-columns --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:add-missing-indices --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:convert-filecache-bigint --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ maintenance:repair --include-expensive&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So können die Apps noch alle aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ app:update --all -n --no-ansi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für weitere Informationen kann auf die offizielle Doku ab Ziffer 2. zurückgegriffen werden.&lt;br /&gt;
&lt;br /&gt;
* [https://docs.nextcloud.com/server/latest/admin_manual/maintenance/update.html#using-the-command-line-based-updater https://docs.nextcloud.com]&lt;br /&gt;
&lt;br /&gt;
Hier gibt es ein kurzes Video, das die Anmeldung über die Kommandozeile mit Putty erklärt und die Aktualisierung von Nextcloud auf der Kommandozeile:&lt;br /&gt;
&lt;br /&gt;
* [https://tube.solidcharity.net/w/0cf5ee97-ba7c-41df-a56f-8d1fea842ab0 Nextcloud auf der Kommandozeile aktualisieren]&lt;br /&gt;
&lt;br /&gt;
== Wartungsmodus per Shell ein- oder ausschalten ==&lt;br /&gt;
&lt;br /&gt;
So kann der Wartungsmodus angeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ maintenance:mode --on&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So kann der Wartungsmodus wieder ausgeschaltet werden, d.h. die Nextcloud ist dann wieder in Betrieb:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ maintenance:mode --off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Webfrontend-Updater Probleme / Lösungen ==&lt;br /&gt;
&lt;br /&gt;
=== Datenbank: Indizes | Primärschlüssel | Konvertierungen ===&lt;br /&gt;
&lt;br /&gt;
Aufgetreten nach erfolgtem Versionsupdate Nextcloud 19 auf Nextcloud 20&lt;br /&gt;
&lt;br /&gt;
Nach dem erfolgten Update lädt automatisch die Seite: &#039;&#039;&#039;Sicherheits- und Einrichtungswarnungen&#039;&#039;&#039; auf dieser wird angemerkt, dass manuelle Schritte für die Datenbank durchzuführen sind. Dies betrifft Indizes, Primärschlüssel und Konvertierungen. &lt;br /&gt;
&lt;br /&gt;
Per Shell in der directory /nextcloud folgende Kommandos ausführen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
xyz00-cloud@h00:~$ cd ~/nextcloud&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:add-missing-primary-keys --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:add-missing-columns --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:add-missing-indices --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ db:convert-filecache-bigint --no-interaction&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ maintenance:repair --include-expensive&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig ist hier dem durch Nextcloud angegebenen Kommando ein &#039;&#039;&#039;php&#039;&#039;&#039; voranzustellen.&lt;br /&gt;
&lt;br /&gt;
== Update per Skript ==&lt;br /&gt;
&lt;br /&gt;
Es ist möglich die regelmäßigen Updates weitgehend zu automatisieren. Ein Skript wäre etwa:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
if [ -f $HOME/nextcloud/occ ]; then &lt;br /&gt;
  echo &amp;quot;Nextcloud Update&amp;quot;; &lt;br /&gt;
  cd $HOME/nextcloud;&lt;br /&gt;
  php updater/updater.phar -vv --no-backup --no-interaction&lt;br /&gt;
  php occ maintenance:mode --on&lt;br /&gt;
  php occ db:add-missing-primary-keys --no-interaction&lt;br /&gt;
  php occ db:add-missing-columns --no-interaction&lt;br /&gt;
  php occ db:add-missing-indices --no-interaction&lt;br /&gt;
  php occ db:convert-filecache-bigint --no-interaction&lt;br /&gt;
  php occ maintenance:repair --include-expensive&lt;br /&gt;
  php occ app:update --all&lt;br /&gt;
  php occ maintenance:mode --off&lt;br /&gt;
else &lt;br /&gt;
  echo &amp;quot;Keine Nextcloud Installation gefunden&amp;quot;; &lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Update: bei old-stable Version bleiben ==&lt;br /&gt;
&lt;br /&gt;
Normalerweise fragt jede Nextcloud Instanz zentral ab, welches Update zur Verfügung steht, abhängig vom Release Channel. Dabei wird aber relativ schnell auf die nächste Version gewechselt, also z.B. von Nextcloud 31 auf Nextcloud 32, obwohl Nextcloud 31 noch mehrere Monate gepflegt wird, und manche Apps noch nicht bereit sind für Nextcloud 32.&lt;br /&gt;
&lt;br /&gt;
Es kann aber auch eine Alternative eingerichtet werden, in der Datei nextcloud/config/config.php, unter dem Eintrag updater.server.url&lt;br /&gt;
&lt;br /&gt;
Hier wird z.B. auf einen Updater von unserem Mitglied Timotheus Pokorra verwiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php line&amp;gt;&lt;br /&gt;
updater_server_url: &amp;quot;https://ncupdater.solidcharity.com/31/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dahinter läuft ein Skript, mit dem wir noch länger eine bestimmte Version anbieten können: https://codeberg.org/tpokorra/ncupdater&lt;br /&gt;
&lt;br /&gt;
= Daten auf HDD Storage =&lt;br /&gt;
== Einrichtung des HDD Storage ==&lt;br /&gt;
&lt;br /&gt;
Um den langsameren aber günstigeren HDD Storage von Hostsharing zu nutzen, kann das data Verzeichnis von SSD auf HDD Storage verschoben werden. Ein symbolischer Link reicht nicht aus, man muss den Pfad in der Nextcloud Konfigurationsdatei anpassen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
# Nextcloud in Wartungsmodus versetzen&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ maintenance:mode --on&lt;br /&gt;
# Daten auf HDD Storage verschieben&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ mv data /home/storage/xyz00/users/cloud/&lt;br /&gt;
# symbolischen Link anlegen&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ ln -s /home/storage/xyz00/users/cloud/data data&lt;br /&gt;
# Pfad in config.php ändern&lt;br /&gt;
nano config/config.php&lt;br /&gt;
# Die Zeile mit &#039;datadirectory&#039; finden und entsprechend ändern:&lt;br /&gt;
# &#039;datadirectory&#039; =&amp;gt; &#039;/home/storage/xyz00/users/cloud/data&#039;,&lt;br /&gt;
# Wartungsmodus beenden&lt;br /&gt;
xyz00-cloud@h00:~/nextcloud$ php occ maintenance:mode --off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Fallstrick: Im data-Verzeichnis liegt eine versteckte Datei &amp;quot;.ncdata&amp;quot;. Beim Move-Befehl &amp;quot;mv&amp;quot; für das komplette Data-Verzeichnis wird diese Datei mit verschoben. Sonst muss die Datei ggf. ins neue data-Verzeichnis kopiert werden!&lt;br /&gt;
&lt;br /&gt;
= Einschränkende Bemerkungen =&lt;br /&gt;
== Nextcloud Sync Client ==&lt;br /&gt;
&lt;br /&gt;
Der Nextcloud Sync Client erfüllt eine Funktion ähnlich wie Dropbox, und synchronisiert ganze Ordnerstrukturen. &lt;br /&gt;
&lt;br /&gt;
Gerade wenn man mit mehreren Menschen in einer Nextcloud arbeitet, ist diese Funktion mit Vorsicht zu benutzen.&lt;br /&gt;
&lt;br /&gt;
* Änderungen an der Ordnerstruktur sollten nicht lokal, sondern im Webbrowser vorgenommen werden.&lt;br /&gt;
* Wenn die Gefahr besteht, dass mehrere Menschen gleichzeitig eine Datei bearbeiten, sollte die Datei nicht lokal, sondern im Webbrowser bearbeitet werden.&lt;br /&gt;
* Aus Sicht des Datenschutzes und der Daten-Minimierung sollte überlegt werden, ob die Daten wirklich auf jeden Laptop und Rechner synchronisiert werden sollen, oder ob es reicht, ausschließlich über den Webbrowser auf die Daten zuzugreifen.&lt;br /&gt;
&lt;br /&gt;
= weiterführende Links =&lt;br /&gt;
&lt;br /&gt;
* [https://docs.nextcloud.com/ Nextcloud Dokumentation]&lt;br /&gt;
* [https://apps.nextcloud.com/ Nextcloud Erweiterungen (&amp;quot;Apps&amp;quot;)]&lt;br /&gt;
* [https://docs.nextcloud.com/server/stable/admin_manual/installation/server_tuning.html Optimierung des Caches z.B. für Previews]&lt;br /&gt;
* [https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/nextcloud Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
= Nextcloud Reseller bei HS =&lt;br /&gt;
&lt;br /&gt;
[https://nextcloud.ossaas.de OS SaaS]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:CalDAV]]&lt;br /&gt;
[[Kategorie:Nextcloud]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Roundcube_-_Filter&amp;diff=7640</id>
		<title>Roundcube - Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Roundcube_-_Filter&amp;diff=7640"/>
		<updated>2026-09-03T12:26:15Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* E-Mail nach Spam Score in den Junk Ordner schieben */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Roundcube - Filter ==&lt;br /&gt;
&lt;br /&gt;
Das Webmailprogramm [[Roundcube]] erlaubt Emails automatisch zu Filtern. Dieser Artikel beschreibt, wie mit der Erweiterung sieverules solche Filter definiert werden können.&lt;br /&gt;
&lt;br /&gt;
=== Allgemeines zum Filtern ===&lt;br /&gt;
&lt;br /&gt;
Über das Mailzustellungsprogramm Deliver ist es mit der Erweiterung [[Managesieve]] möglich Emails beim Eintreffen in der Mailbox zu Filtern. Die Filterung findet hierbei bereits auf dem Server statt, so daß der User nicht mit seinem Mailprogramm oder Webmailer eingeloggt sein muß.&lt;br /&gt;
&lt;br /&gt;
Hierbei ist es möglich u.a. folgende Aktionen durchzuführen&lt;br /&gt;
&lt;br /&gt;
* Mails in einen bestimmten Ordner abzuspeichern&lt;br /&gt;
* Mails an einen anderen Empfänger weiterzuleiten&lt;br /&gt;
* eine Abwesenheitsmeldung zu verschicken&lt;br /&gt;
* den Empfang einer Email abzulehnen&lt;br /&gt;
* eine Mail zu löschen&lt;br /&gt;
&lt;br /&gt;
Die Ausführung dieser Filteraktionen kann gesteuert werden z.B. basierend auf&lt;br /&gt;
&lt;br /&gt;
* dem Absender der eintreffenden Email&lt;br /&gt;
* des Titels oder Teilen hiervon&lt;br /&gt;
* dem Vorhandensein oder Nichtvorhandensein bestimmter Wörter im Text der Nachricht&lt;br /&gt;
* die Auswertung von zusätzlichen Mail-Headern.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-01-einstellungen.png|miniatur|250px|right|Einstellungen]]&lt;br /&gt;
Detaillierte Informationen können z.B. der [http://de.wikipedia.org/wiki/Sieve Wikipedia] oder unter [http://www.sieve.info sieve.info] entnommen werden. Im Hostsharing-Wiki unter [[Managesieve]] sind ebenfalls weitere Grundlageninformationen zu finden.&lt;br /&gt;
&lt;br /&gt;
=== Einrichtung ===&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn der Nutzer schon eine .forward mit z.b. procmail nutzt muss wie unter &lt;br /&gt;
[https://wiki.hostsharing.net/index.php?title=Managesieve#Zusammenarbeit_mit_Procmail Zusammenarbeit_mit_Procmail]&lt;br /&gt;
beschrieben ist beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Filter können unter &amp;lt;tt&amp;gt;Einstellungen&amp;lt;/tt&amp;gt; eingerichtet und verändert werden. Hierzu im Menu Einstellungen den Reiter ganz rechts &amp;lt;tt&amp;gt;Filter&amp;lt;/tt&amp;gt; auswählen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-02-mailuebersicht.png|center|none|frame|Ungefilterter Posteingang]]&lt;br /&gt;
Für die folgenden Beispiele wird davon ausgegangen, daß der Nutzer in seinem Posteingang ohne Filter die Situation, wie im Bild oben angezeigt vorfindet: Viele Emails aus (drei) Mailinglisten und eine private Email. Alle Mails sind in einem Ordner und erschweren das Finden der ggf. wichtigen privaten Email.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-03-neuer-filter.png|miniatur|250px|right|Neuen Filter anlegen]]&lt;br /&gt;
Zunächst soll ein neuer Filter angelegt werden, der die Emails der Mailingliste &amp;lt;tt&amp;gt;otrs-de&amp;lt;/tt&amp;gt; [http://doc.otrs.org/2.2/de/html/additional-resources-mailinglists.html] in einen eigenen Ordner verschiebt.&lt;br /&gt;
&lt;br /&gt;
Hierzu unter der (leeren) Filterliste auf das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; zum Anlegen eines Neuen Filters klicken.&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-04-OTRS-filter.png|miniatur|600px|right|Anlegen eines Filters für eine Mailingliste]]&lt;br /&gt;
Im neu geöffneten Formular kann der neue Filter definiert werden.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Filternamen&#039;&#039;&#039; vergeben: zum Beispiel OTRS für die entsprechende Maillingliste (oder zur besseren späteren Erinnerung: &amp;quot;Mailingliste otrs-de&amp;quot;). &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;OTRS&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Filterregel&#039;&#039;&#039;: Hier wird definiert unter welchen Bedingungen der Filter angewandt werden soll.&amp;lt;br&amp;gt;Drei Optionen stehen zur Auswahl&lt;br /&gt;
** Irgendeine Bedingung muß erfüllt sein (ODER)&lt;br /&gt;
** Alle Bedingungen müssen erfüllt sein (UND) &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Auswählen&amp;lt;/span&amp;gt;&lt;br /&gt;
** Die Bedingung ist für alle Emails gültig (keine Bedingung notwendig)&lt;br /&gt;
* Die Definition der Filterregel beinhaltet das Auswahl eines Teils der Nachricht (z.B. Absender, Datum, Betreff, Text) und einem Wert, mit dem verglichen werden soll. In unserem Beispiel: &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;BETREFF enthält &amp;lt;nowiki&amp;gt;[otrs-de]&amp;lt;/nowiki&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Filteraktion&#039;&#039;&#039;: Die Aktion, die ausgeführt werden soll. &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Verschiebe Nachricht nach OTRS&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Bei Aktionen, die Nachrichten in andere Ordner verschieben oder kopieren werden die möglichen Ordner die zum Zeitpunkt der Filteranlage existieren in einem Drop-Down-Menu angezeigt.&lt;br /&gt;
* &#039;&#039;&#039;Speichern&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-05-hostsharing-filter.png|miniatur|600px|right|Filter für Mailingliste über Mail-Header und Ausnahme]]&lt;br /&gt;
=== Weitere Beispiele ===&lt;br /&gt;
&lt;br /&gt;
==== Maillinglisten Filter ====&lt;br /&gt;
&lt;br /&gt;
Im Beispiel rechts werden wieder die Emails einer Mailinglliste gefiltert. Hier handelt es sich um die &amp;lt;tt&amp;gt;Technik&amp;lt;/tt&amp;gt;-Liste von Hostsharing.&lt;br /&gt;
&lt;br /&gt;
Der Filter erhält folgende Kriterien:&lt;br /&gt;
* &#039;&#039;&#039;Filterregel&#039;&#039;&#039;: Der Filter wird &#039;&#039;&#039;nicht&#039;&#039;&#039; angewandt, wenn der Text der Nachricht das Wort &amp;quot;Festplattencrash&amp;quot; enthält, der Empfänger, solche Emails also in seinem Posteingang behalten möchte.&amp;lt;br&amp;gt;Darüber hinaus wird die Mailingliste identifiziert über den Mail-Header &amp;lt;tt&amp;gt;List-Id&amp;lt;/tt&amp;gt;. Solche zusätzlichen Mail-Header können über die Auswahl &amp;quot;Anderer Header&amp;quot; ausgewählt werden.&amp;lt;br&amp;gt;Beide Bedingungen müssen erfüllt sein (UND), also &amp;quot;trifft alle folgenden Regeln&amp;quot; auswählen.&lt;br /&gt;
* &#039;&#039;&#039;Filteraktion&#039;&#039;&#039;: Wie im ersten Beispiele wieder das Verschieben in einen Ordner, hier &amp;lt;tt&amp;gt;hostsharing&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-06-abwesenheitsmeldung-filter.png|miniatur|600px|right|Abwesenheitsmeldung]]&lt;br /&gt;
==== Abwesenheitsmeldung ====&lt;br /&gt;
&lt;br /&gt;
Nutzer möchten oft bei längerer Abwesenheit dem Absender einer Email mitteilen, daß sie die empfangene Email z.B. wegen Urlaubs nicht lesen können. Hierzu kann eine Abwesenheitsmeldung definiert werden, die automatisch eine Antwort-Email generiert mit einem vordefinierten Text.&lt;br /&gt;
&lt;br /&gt;
Im Beispiel sollen die Absender &amp;quot;peter.lustig&amp;quot; und &amp;quot;Wickie&amp;quot; keine Abwesenheitsmeldung erhalten, sowie bei Emails, die das Wort &amp;quot;Werbung&amp;quot; im Betreff enthalten auch keine Abwesenheitsmeldung verschickt werden.&lt;br /&gt;
* &amp;quot;Absender enthält nicht &#039;peter.lustig&#039;&amp;quot; - Ein Vergleich mit der Email-&#039;&#039;Adresse&#039;&#039; wird durchgeführt.&amp;lt;br&amp;gt;Peter &amp;lt;peter.lustig@example.org&amp;gt; - Hier ist peter.lustig in der Adresse enthalten&amp;lt;br&amp;gt;Peter.Lustig &amp;lt;peter@example.org&amp;gt; - Hier ist peter.lustig &#039;&#039;nicht&#039;&#039; in der &#039;&#039;Adresse&#039;&#039; enthalten.&lt;br /&gt;
* &amp;quot;Anderer Header &amp;quot;From&amp;quot; enthält nicht &#039;Wickie&#039;&amp;quot; - Ein Vergleich mit der &#039;&#039;kompletten Absender-Angabe&#039;&#039; wird durchgeführt&amp;lt;br&amp;gt;&#039;&#039;Susanne &amp;lt;wickie@example.org&amp;gt;&#039;&#039; aber auch &#039;&#039;Wickie &amp;lt;susanne@example.org&amp;gt;&#039;&#039; werden gefunden&lt;br /&gt;
* &amp;quot;Betreff enthält nicht &#039;Werbung&#039; - Das Wort Werbung darf nicht im Betreff enthalten sein.&lt;br /&gt;
&lt;br /&gt;
In den &#039;&#039;&#039;Filteraktionen&#039;&#039;&#039; wird die Aktion &amp;quot;Abwesenheitsmeldung&amp;quot; ausgewählt.&lt;br /&gt;
* &#039;&#039;&#039;Absender&#039;&#039;&#039;: Hat man mehrere Identitäten in Webmail angelegt, kann man hier aussuchen unter welchem Absender die Abwesenheitsmeldung geschickt werden soll.&lt;br /&gt;
* &#039;&#039;&#039;Alias&#039;&#039;&#039;: Die Vacation-Extension schickt Abwesenheitsmeldungen &#039;&#039;&#039;nur&#039;&#039;&#039; wenn die Mail an eine dem System für &#039;&#039;diesen&#039;&#039; Account bekannte Email-Adresse geschickt wurde. Im konkreten Fall bei der Erstellung über Roundcube müssen also für jede Email-Adresse Identitäten angelegt werden, also z.B. sowohl max.mustermann@example.org und maexchen@example.org. Diese müssen dann auch unter &amp;quot;Alias&amp;quot; explizit ausgewählt werden. Werden Emails an den Account mit einer anderen Empfänger-Adresse geschickt, erhalten diese &#039;&#039;&#039;keine&#039;&#039;&#039; Abwesenheitsmeldung. siehe auch [http://tools.ietf.org/html/rfc5230#section-4.5 RFC5230] Abschnitt 4.5&lt;br /&gt;
* &#039;&#039;&#039;Zeitraum&#039;&#039;&#039;: Sagt aus, nach wieviel Tagen ein Absender eine erneute Abwesenheitsmeldung erhält. Im Beispiel also z.B. nur einmal alle 3 Tage. Wenn der Absender dazwischen neue Emails versendet, erhält er keine neue Abwesenheitsmeldung. Nach 3 Tagen wird bei erneuten Emails wieder eine Abwesenheitsmeldung verschickt. Hierz speichert sich &amp;lt;tt&amp;gt;deliver&amp;lt;/tt&amp;gt; eine Liste der Empfänger.&lt;br /&gt;
* &#039;&#039;&#039;Betreff&#039;&#039;&#039;: Der Betreff der Abwesenheitsmeldung, z.B. &amp;quot;Abwesenheit - Urlaub&amp;quot;; der originale Betreff der Email kann zur Identifizierung angehängt werden.&amp;lt;br&amp;gt;Wird also automatisch auf eine Mail &amp;quot;Geburtstagseinladung&amp;quot; geantwortet, wäre der Betreff der Abwesenheitsmeldung &amp;quot;Abwesenheit - Urlaub Geburtstagseinladung&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;Nachricht&#039;&#039;&#039;: Der eigentliche Text der Abwesenheitsmeldung, z.B. Dauer der Abwesenheitsmeldung, Vertretungsregelung, Erreichbarkeit.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-07-reihenfolge-a.png|miniatur|300px|left|Reihenfolge Filter ändern über Pfeile]]&lt;br /&gt;
[[Bild:Sieve-07-reihenfolge-b.png|miniatur|300px|right|Nach Änderung der Reihenfolge]]&lt;br /&gt;
===== Reihenfolge von Filtern =====&lt;br /&gt;
&lt;br /&gt;
Insbesondere bei Abwesenheitsmeldungen ist die Reihenfolge der Filter wichtig. Im Beispiel links wird der Filter &amp;quot;osm&amp;quot; erst nach der Abwesenheitsmeldung angewandt, Mails, die durch diesen Filter nicht schon wegsortiert wurden, erhalten also eine Abwesenheitsmeldung. Wenn dies unerwünscht ist, muß der Filter &#039;&#039;&#039;vor&#039;&#039;&#039; den Filter der Abwesenheitsmeldung verschoben werden (über die Pfeile rechts neben des Filterliste).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
In (u.a.) folgenden Fällen werden &#039;&#039;&#039;Abwesenheitsmeldungen vom System nicht verschickt&#039;&#039;&#039;:&lt;br /&gt;
* Die Absenderadresse deutet auf eine Mailingliste hin, z.B. beginnt mit: &#039;&#039;mailer-daemon&#039;&#039;, &#039;&#039;listserv&#039;&#039;, &#039;&#039;majordomo&#039;&#039;, &#039;&#039;owner-&#039;&#039; oder enthält &#039;&#039;-request&#039;&#039;&lt;br /&gt;
* Es existiert ein Header &amp;quot;Precedence&amp;quot; der &#039;&#039;junk&#039;&#039;, &#039;&#039;bulk&#039;&#039; oder &#039;&#039;list&#039;&#039; enthält.&lt;br /&gt;
* Der Empfänger der Nachricht steht nicht in &#039;&#039;To&#039;&#039; oder &#039;&#039;Cc&#039;&#039;.&lt;br /&gt;
* Sender und Empfänger haben dieselbe Email-Adresse.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-08-kopiesenden.png|miniatur|600px|right|TEXT]]&lt;br /&gt;
&lt;br /&gt;
==== Kopie an anderen Empfänger versenden. ====&lt;br /&gt;
&lt;br /&gt;
Eine erhaltene Email soll an eine andere Email-Adresse (in Kopie) weitergeleitet werden, z.B. von der Privatadresse an die Geschäftsadresse.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Filterregel&#039;&#039;&#039;: In diesem Beispiel soll der lokale Teil der Absender-Adresse verglichen werden. &amp;quot;Absender&amp;quot; wählen, dann &amp;quot;weitere Optionen&amp;quot; &#039;&#039;&#039;(1)&#039;&#039;&#039; und unter &#039;&#039;Operatoren&#039;&#039; &#039;&#039;User-Teil gleich&#039;&#039;. &#039;&#039;&#039;(2)&#039;&#039;&#039;&amp;lt;br&amp;gt; Im Beispiel wurde der User-Teil mit &#039;&#039;susanne.musterfrau&#039;&#039; &#039;&#039;&#039;(3)&#039;&#039;&#039; angegeben. Zur Email-Adresse &#039;&#039;susanne.musterfrau@example.de&#039;&#039; wird ein Match gefunden für &#039;&#039;sara-susanne.musterfrau@example.org&#039;&#039; hingegen nicht, weil der lokale Teil der Email-Adresse nicht übereinstimmt.&lt;br /&gt;
* &#039;&#039;&#039;Filteraktionen&#039;&#039;&#039;: &amp;quot;Sende eine Kopie an&amp;quot; wählen &#039;&#039;&#039;(4)&#039;&#039;&#039; und eine Ziel-Adresse angeben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-09-filter-abschalten-a.png|miniatur|400px|left|Filter abschalten]]&lt;br /&gt;
[[Bild:Sieve-09-filter-abschalten-b.png|miniatur|300px|right|Filterübersicht im inaktivem Filter]]&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
==== E-Mail nach Spam Score in den Junk Ordner schieben ====&lt;br /&gt;
&lt;br /&gt;
Wenn eine E-Mail eine bestimmte Einstufung von Spam hat, soll die E-Mail in den Spam Ordner geschoben werden.&lt;br /&gt;
&lt;br /&gt;
Dazu muss anstelle von &amp;quot;Betreff&amp;quot; der Eintrag mit den 3 Punkten gewählt werden (...), um dort von Hand &amp;quot;X-Spam-Level&amp;quot; einzugeben.&lt;br /&gt;
&lt;br /&gt;
Mit der Anzahl der Sterne bestimmt man, ab welcher Einstufung eine E-Mail als Spam kategorisiert wird.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Roundcube Sieve X-Spam-Level.png|miniatur|600px|X-Spam-Level filtern]]&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Filter deaktivieren/aktivieren ====&lt;br /&gt;
&lt;br /&gt;
Soll ein Filter temporär deaktivitert werden, kann in der Filterbearbeitung &#039;&#039;&#039;Filterregel abschalten&#039;&#039;&#039; angeklickt werden. In der Filterübersicht ist der Filter dann als &#039;&#039;&amp;quot;(abgeschaltet)&amp;quot;&#039;&#039; markiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-10-nach-anwendung-filter.png|miniatur|600px|right|Nach dem Filtern]]&lt;br /&gt;
==== Nach dem Filtern ====&lt;br /&gt;
&lt;br /&gt;
Die im obigen Beispiel gezeigte Inbox mit über 200 Emails sieht nach Anwendung der Filter wie im nebenstehenden Bild aus.&lt;br /&gt;
&lt;br /&gt;
* Im Posteingang &#039;&#039;&#039;(1)&#039;&#039;&#039; ist nur noch eine private Email vorhanden&lt;br /&gt;
* Die Emails and die Mailinglisten wurden in die jeweiligen Ordner &#039;&#039;&#039;(2)&#039;&#039;&#039; einsortiert.&lt;br /&gt;
&lt;br /&gt;
=== Technisches ===&lt;br /&gt;
&lt;br /&gt;
==== Speicherort ====&lt;br /&gt;
&lt;br /&gt;
Roundcube speichert die erstellten Regeln unter &lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
~/Maildir/sieve/roundcube.sieve&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und verlinkt diese Filterdatei automatisch für die Benutzung mit dovecot:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@h01:~$ ls -al &lt;br /&gt;
drwxr-xr-x  5 xyz00-max xyz00  4096 Nov 16 07:28 .&lt;br /&gt;
drwxr-xr-x 28 xyz00-max xyz00  4096 Oct 22 23:06 ..&lt;br /&gt;
lrwxrwxrwx  1 xyz00-max xyz00    29 Nov 16 07:28 .dovecot.sieve -&amp;gt; Maildir/sieve/roundcube.sieve&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wurden von anderen Programmen -- oder manuell -- andere Filtersets angelegt, werden diese vom Plugin deaktiviert. Die ursprüngliche Filterdatei bleibt erhalten, aber obiger Symlink verweist dann auf die Roundcube-Filter.&lt;br /&gt;
&lt;br /&gt;
==== Manuelles Editieren ====&lt;br /&gt;
&lt;br /&gt;
Vom manuellen Bearbeiten der Filterdatei &amp;lt;tt&amp;gt;roundcube.sieve&amp;lt;/tt&amp;gt; wird abgeraten, da bei erneutem Einlesen durch das Roundcube-Plugin diese Regeln mit großer Wahrscheinlichkeit wieder automatisch umgeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Für komplexeres Filtern kann eine komplett manuelle Datei angelegt werden und entsprechend verlinkt werden. Siehe auch den Artikel zu [[Managesieve]].&lt;br /&gt;
&lt;br /&gt;
==== Links ====&lt;br /&gt;
&lt;br /&gt;
Einige Sieve-relevante Links, sind im entsprechenden [https://wiki.hostsharing.net/index.php?title=Managesieve#Links Managesieve Wiki-Artikel] angegeben: &lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;br /&gt;
[[Kategorie:Glossar]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Roundcube_-_Filter&amp;diff=7639</id>
		<title>Roundcube - Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Roundcube_-_Filter&amp;diff=7639"/>
		<updated>2026-09-03T12:24:37Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Kopie an anderen Empfänger versenden. */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Roundcube - Filter ==&lt;br /&gt;
&lt;br /&gt;
Das Webmailprogramm [[Roundcube]] erlaubt Emails automatisch zu Filtern. Dieser Artikel beschreibt, wie mit der Erweiterung sieverules solche Filter definiert werden können.&lt;br /&gt;
&lt;br /&gt;
=== Allgemeines zum Filtern ===&lt;br /&gt;
&lt;br /&gt;
Über das Mailzustellungsprogramm Deliver ist es mit der Erweiterung [[Managesieve]] möglich Emails beim Eintreffen in der Mailbox zu Filtern. Die Filterung findet hierbei bereits auf dem Server statt, so daß der User nicht mit seinem Mailprogramm oder Webmailer eingeloggt sein muß.&lt;br /&gt;
&lt;br /&gt;
Hierbei ist es möglich u.a. folgende Aktionen durchzuführen&lt;br /&gt;
&lt;br /&gt;
* Mails in einen bestimmten Ordner abzuspeichern&lt;br /&gt;
* Mails an einen anderen Empfänger weiterzuleiten&lt;br /&gt;
* eine Abwesenheitsmeldung zu verschicken&lt;br /&gt;
* den Empfang einer Email abzulehnen&lt;br /&gt;
* eine Mail zu löschen&lt;br /&gt;
&lt;br /&gt;
Die Ausführung dieser Filteraktionen kann gesteuert werden z.B. basierend auf&lt;br /&gt;
&lt;br /&gt;
* dem Absender der eintreffenden Email&lt;br /&gt;
* des Titels oder Teilen hiervon&lt;br /&gt;
* dem Vorhandensein oder Nichtvorhandensein bestimmter Wörter im Text der Nachricht&lt;br /&gt;
* die Auswertung von zusätzlichen Mail-Headern.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-01-einstellungen.png|miniatur|250px|right|Einstellungen]]&lt;br /&gt;
Detaillierte Informationen können z.B. der [http://de.wikipedia.org/wiki/Sieve Wikipedia] oder unter [http://www.sieve.info sieve.info] entnommen werden. Im Hostsharing-Wiki unter [[Managesieve]] sind ebenfalls weitere Grundlageninformationen zu finden.&lt;br /&gt;
&lt;br /&gt;
=== Einrichtung ===&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn der Nutzer schon eine .forward mit z.b. procmail nutzt muss wie unter &lt;br /&gt;
[https://wiki.hostsharing.net/index.php?title=Managesieve#Zusammenarbeit_mit_Procmail Zusammenarbeit_mit_Procmail]&lt;br /&gt;
beschrieben ist beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Filter können unter &amp;lt;tt&amp;gt;Einstellungen&amp;lt;/tt&amp;gt; eingerichtet und verändert werden. Hierzu im Menu Einstellungen den Reiter ganz rechts &amp;lt;tt&amp;gt;Filter&amp;lt;/tt&amp;gt; auswählen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-02-mailuebersicht.png|center|none|frame|Ungefilterter Posteingang]]&lt;br /&gt;
Für die folgenden Beispiele wird davon ausgegangen, daß der Nutzer in seinem Posteingang ohne Filter die Situation, wie im Bild oben angezeigt vorfindet: Viele Emails aus (drei) Mailinglisten und eine private Email. Alle Mails sind in einem Ordner und erschweren das Finden der ggf. wichtigen privaten Email.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-03-neuer-filter.png|miniatur|250px|right|Neuen Filter anlegen]]&lt;br /&gt;
Zunächst soll ein neuer Filter angelegt werden, der die Emails der Mailingliste &amp;lt;tt&amp;gt;otrs-de&amp;lt;/tt&amp;gt; [http://doc.otrs.org/2.2/de/html/additional-resources-mailinglists.html] in einen eigenen Ordner verschiebt.&lt;br /&gt;
&lt;br /&gt;
Hierzu unter der (leeren) Filterliste auf das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; zum Anlegen eines Neuen Filters klicken.&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-04-OTRS-filter.png|miniatur|600px|right|Anlegen eines Filters für eine Mailingliste]]&lt;br /&gt;
Im neu geöffneten Formular kann der neue Filter definiert werden.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Filternamen&#039;&#039;&#039; vergeben: zum Beispiel OTRS für die entsprechende Maillingliste (oder zur besseren späteren Erinnerung: &amp;quot;Mailingliste otrs-de&amp;quot;). &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;OTRS&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Filterregel&#039;&#039;&#039;: Hier wird definiert unter welchen Bedingungen der Filter angewandt werden soll.&amp;lt;br&amp;gt;Drei Optionen stehen zur Auswahl&lt;br /&gt;
** Irgendeine Bedingung muß erfüllt sein (ODER)&lt;br /&gt;
** Alle Bedingungen müssen erfüllt sein (UND) &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Auswählen&amp;lt;/span&amp;gt;&lt;br /&gt;
** Die Bedingung ist für alle Emails gültig (keine Bedingung notwendig)&lt;br /&gt;
* Die Definition der Filterregel beinhaltet das Auswahl eines Teils der Nachricht (z.B. Absender, Datum, Betreff, Text) und einem Wert, mit dem verglichen werden soll. In unserem Beispiel: &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;BETREFF enthält &amp;lt;nowiki&amp;gt;[otrs-de]&amp;lt;/nowiki&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Filteraktion&#039;&#039;&#039;: Die Aktion, die ausgeführt werden soll. &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Verschiebe Nachricht nach OTRS&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Bei Aktionen, die Nachrichten in andere Ordner verschieben oder kopieren werden die möglichen Ordner die zum Zeitpunkt der Filteranlage existieren in einem Drop-Down-Menu angezeigt.&lt;br /&gt;
* &#039;&#039;&#039;Speichern&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-05-hostsharing-filter.png|miniatur|600px|right|Filter für Mailingliste über Mail-Header und Ausnahme]]&lt;br /&gt;
=== Weitere Beispiele ===&lt;br /&gt;
&lt;br /&gt;
==== Maillinglisten Filter ====&lt;br /&gt;
&lt;br /&gt;
Im Beispiel rechts werden wieder die Emails einer Mailinglliste gefiltert. Hier handelt es sich um die &amp;lt;tt&amp;gt;Technik&amp;lt;/tt&amp;gt;-Liste von Hostsharing.&lt;br /&gt;
&lt;br /&gt;
Der Filter erhält folgende Kriterien:&lt;br /&gt;
* &#039;&#039;&#039;Filterregel&#039;&#039;&#039;: Der Filter wird &#039;&#039;&#039;nicht&#039;&#039;&#039; angewandt, wenn der Text der Nachricht das Wort &amp;quot;Festplattencrash&amp;quot; enthält, der Empfänger, solche Emails also in seinem Posteingang behalten möchte.&amp;lt;br&amp;gt;Darüber hinaus wird die Mailingliste identifiziert über den Mail-Header &amp;lt;tt&amp;gt;List-Id&amp;lt;/tt&amp;gt;. Solche zusätzlichen Mail-Header können über die Auswahl &amp;quot;Anderer Header&amp;quot; ausgewählt werden.&amp;lt;br&amp;gt;Beide Bedingungen müssen erfüllt sein (UND), also &amp;quot;trifft alle folgenden Regeln&amp;quot; auswählen.&lt;br /&gt;
* &#039;&#039;&#039;Filteraktion&#039;&#039;&#039;: Wie im ersten Beispiele wieder das Verschieben in einen Ordner, hier &amp;lt;tt&amp;gt;hostsharing&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-06-abwesenheitsmeldung-filter.png|miniatur|600px|right|Abwesenheitsmeldung]]&lt;br /&gt;
==== Abwesenheitsmeldung ====&lt;br /&gt;
&lt;br /&gt;
Nutzer möchten oft bei längerer Abwesenheit dem Absender einer Email mitteilen, daß sie die empfangene Email z.B. wegen Urlaubs nicht lesen können. Hierzu kann eine Abwesenheitsmeldung definiert werden, die automatisch eine Antwort-Email generiert mit einem vordefinierten Text.&lt;br /&gt;
&lt;br /&gt;
Im Beispiel sollen die Absender &amp;quot;peter.lustig&amp;quot; und &amp;quot;Wickie&amp;quot; keine Abwesenheitsmeldung erhalten, sowie bei Emails, die das Wort &amp;quot;Werbung&amp;quot; im Betreff enthalten auch keine Abwesenheitsmeldung verschickt werden.&lt;br /&gt;
* &amp;quot;Absender enthält nicht &#039;peter.lustig&#039;&amp;quot; - Ein Vergleich mit der Email-&#039;&#039;Adresse&#039;&#039; wird durchgeführt.&amp;lt;br&amp;gt;Peter &amp;lt;peter.lustig@example.org&amp;gt; - Hier ist peter.lustig in der Adresse enthalten&amp;lt;br&amp;gt;Peter.Lustig &amp;lt;peter@example.org&amp;gt; - Hier ist peter.lustig &#039;&#039;nicht&#039;&#039; in der &#039;&#039;Adresse&#039;&#039; enthalten.&lt;br /&gt;
* &amp;quot;Anderer Header &amp;quot;From&amp;quot; enthält nicht &#039;Wickie&#039;&amp;quot; - Ein Vergleich mit der &#039;&#039;kompletten Absender-Angabe&#039;&#039; wird durchgeführt&amp;lt;br&amp;gt;&#039;&#039;Susanne &amp;lt;wickie@example.org&amp;gt;&#039;&#039; aber auch &#039;&#039;Wickie &amp;lt;susanne@example.org&amp;gt;&#039;&#039; werden gefunden&lt;br /&gt;
* &amp;quot;Betreff enthält nicht &#039;Werbung&#039; - Das Wort Werbung darf nicht im Betreff enthalten sein.&lt;br /&gt;
&lt;br /&gt;
In den &#039;&#039;&#039;Filteraktionen&#039;&#039;&#039; wird die Aktion &amp;quot;Abwesenheitsmeldung&amp;quot; ausgewählt.&lt;br /&gt;
* &#039;&#039;&#039;Absender&#039;&#039;&#039;: Hat man mehrere Identitäten in Webmail angelegt, kann man hier aussuchen unter welchem Absender die Abwesenheitsmeldung geschickt werden soll.&lt;br /&gt;
* &#039;&#039;&#039;Alias&#039;&#039;&#039;: Die Vacation-Extension schickt Abwesenheitsmeldungen &#039;&#039;&#039;nur&#039;&#039;&#039; wenn die Mail an eine dem System für &#039;&#039;diesen&#039;&#039; Account bekannte Email-Adresse geschickt wurde. Im konkreten Fall bei der Erstellung über Roundcube müssen also für jede Email-Adresse Identitäten angelegt werden, also z.B. sowohl max.mustermann@example.org und maexchen@example.org. Diese müssen dann auch unter &amp;quot;Alias&amp;quot; explizit ausgewählt werden. Werden Emails an den Account mit einer anderen Empfänger-Adresse geschickt, erhalten diese &#039;&#039;&#039;keine&#039;&#039;&#039; Abwesenheitsmeldung. siehe auch [http://tools.ietf.org/html/rfc5230#section-4.5 RFC5230] Abschnitt 4.5&lt;br /&gt;
* &#039;&#039;&#039;Zeitraum&#039;&#039;&#039;: Sagt aus, nach wieviel Tagen ein Absender eine erneute Abwesenheitsmeldung erhält. Im Beispiel also z.B. nur einmal alle 3 Tage. Wenn der Absender dazwischen neue Emails versendet, erhält er keine neue Abwesenheitsmeldung. Nach 3 Tagen wird bei erneuten Emails wieder eine Abwesenheitsmeldung verschickt. Hierz speichert sich &amp;lt;tt&amp;gt;deliver&amp;lt;/tt&amp;gt; eine Liste der Empfänger.&lt;br /&gt;
* &#039;&#039;&#039;Betreff&#039;&#039;&#039;: Der Betreff der Abwesenheitsmeldung, z.B. &amp;quot;Abwesenheit - Urlaub&amp;quot;; der originale Betreff der Email kann zur Identifizierung angehängt werden.&amp;lt;br&amp;gt;Wird also automatisch auf eine Mail &amp;quot;Geburtstagseinladung&amp;quot; geantwortet, wäre der Betreff der Abwesenheitsmeldung &amp;quot;Abwesenheit - Urlaub Geburtstagseinladung&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;Nachricht&#039;&#039;&#039;: Der eigentliche Text der Abwesenheitsmeldung, z.B. Dauer der Abwesenheitsmeldung, Vertretungsregelung, Erreichbarkeit.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-07-reihenfolge-a.png|miniatur|300px|left|Reihenfolge Filter ändern über Pfeile]]&lt;br /&gt;
[[Bild:Sieve-07-reihenfolge-b.png|miniatur|300px|right|Nach Änderung der Reihenfolge]]&lt;br /&gt;
===== Reihenfolge von Filtern =====&lt;br /&gt;
&lt;br /&gt;
Insbesondere bei Abwesenheitsmeldungen ist die Reihenfolge der Filter wichtig. Im Beispiel links wird der Filter &amp;quot;osm&amp;quot; erst nach der Abwesenheitsmeldung angewandt, Mails, die durch diesen Filter nicht schon wegsortiert wurden, erhalten also eine Abwesenheitsmeldung. Wenn dies unerwünscht ist, muß der Filter &#039;&#039;&#039;vor&#039;&#039;&#039; den Filter der Abwesenheitsmeldung verschoben werden (über die Pfeile rechts neben des Filterliste).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
In (u.a.) folgenden Fällen werden &#039;&#039;&#039;Abwesenheitsmeldungen vom System nicht verschickt&#039;&#039;&#039;:&lt;br /&gt;
* Die Absenderadresse deutet auf eine Mailingliste hin, z.B. beginnt mit: &#039;&#039;mailer-daemon&#039;&#039;, &#039;&#039;listserv&#039;&#039;, &#039;&#039;majordomo&#039;&#039;, &#039;&#039;owner-&#039;&#039; oder enthält &#039;&#039;-request&#039;&#039;&lt;br /&gt;
* Es existiert ein Header &amp;quot;Precedence&amp;quot; der &#039;&#039;junk&#039;&#039;, &#039;&#039;bulk&#039;&#039; oder &#039;&#039;list&#039;&#039; enthält.&lt;br /&gt;
* Der Empfänger der Nachricht steht nicht in &#039;&#039;To&#039;&#039; oder &#039;&#039;Cc&#039;&#039;.&lt;br /&gt;
* Sender und Empfänger haben dieselbe Email-Adresse.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-08-kopiesenden.png|miniatur|600px|right|TEXT]]&lt;br /&gt;
&lt;br /&gt;
==== Kopie an anderen Empfänger versenden. ====&lt;br /&gt;
&lt;br /&gt;
Eine erhaltene Email soll an eine andere Email-Adresse (in Kopie) weitergeleitet werden, z.B. von der Privatadresse an die Geschäftsadresse.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Filterregel&#039;&#039;&#039;: In diesem Beispiel soll der lokale Teil der Absender-Adresse verglichen werden. &amp;quot;Absender&amp;quot; wählen, dann &amp;quot;weitere Optionen&amp;quot; &#039;&#039;&#039;(1)&#039;&#039;&#039; und unter &#039;&#039;Operatoren&#039;&#039; &#039;&#039;User-Teil gleich&#039;&#039;. &#039;&#039;&#039;(2)&#039;&#039;&#039;&amp;lt;br&amp;gt; Im Beispiel wurde der User-Teil mit &#039;&#039;susanne.musterfrau&#039;&#039; &#039;&#039;&#039;(3)&#039;&#039;&#039; angegeben. Zur Email-Adresse &#039;&#039;susanne.musterfrau@example.de&#039;&#039; wird ein Match gefunden für &#039;&#039;sara-susanne.musterfrau@example.org&#039;&#039; hingegen nicht, weil der lokale Teil der Email-Adresse nicht übereinstimmt.&lt;br /&gt;
* &#039;&#039;&#039;Filteraktionen&#039;&#039;&#039;: &amp;quot;Sende eine Kopie an&amp;quot; wählen &#039;&#039;&#039;(4)&#039;&#039;&#039; und eine Ziel-Adresse angeben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-09-filter-abschalten-a.png|miniatur|400px|left|Filter abschalten]]&lt;br /&gt;
[[Bild:Sieve-09-filter-abschalten-b.png|miniatur|300px|right|Filterübersicht im inaktivem Filter]]&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
==== E-Mail nach Spam Score in den Junk Ordner schieben ====&lt;br /&gt;
&lt;br /&gt;
Wenn eine E-Mail eine bestimmte Einstufung von Spam hat, soll die E-Mail in den Spam Ordner geschoben werden.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Roundcube Sieve X-Spam-Level.png|miniatur|600px|X-Spam-Level filtern]]&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Filter deaktivieren/aktivieren ====&lt;br /&gt;
&lt;br /&gt;
Soll ein Filter temporär deaktivitert werden, kann in der Filterbearbeitung &#039;&#039;&#039;Filterregel abschalten&#039;&#039;&#039; angeklickt werden. In der Filterübersicht ist der Filter dann als &#039;&#039;&amp;quot;(abgeschaltet)&amp;quot;&#039;&#039; markiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-10-nach-anwendung-filter.png|miniatur|600px|right|Nach dem Filtern]]&lt;br /&gt;
==== Nach dem Filtern ====&lt;br /&gt;
&lt;br /&gt;
Die im obigen Beispiel gezeigte Inbox mit über 200 Emails sieht nach Anwendung der Filter wie im nebenstehenden Bild aus.&lt;br /&gt;
&lt;br /&gt;
* Im Posteingang &#039;&#039;&#039;(1)&#039;&#039;&#039; ist nur noch eine private Email vorhanden&lt;br /&gt;
* Die Emails and die Mailinglisten wurden in die jeweiligen Ordner &#039;&#039;&#039;(2)&#039;&#039;&#039; einsortiert.&lt;br /&gt;
&lt;br /&gt;
=== Technisches ===&lt;br /&gt;
&lt;br /&gt;
==== Speicherort ====&lt;br /&gt;
&lt;br /&gt;
Roundcube speichert die erstellten Regeln unter &lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
~/Maildir/sieve/roundcube.sieve&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und verlinkt diese Filterdatei automatisch für die Benutzung mit dovecot:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@h01:~$ ls -al &lt;br /&gt;
drwxr-xr-x  5 xyz00-max xyz00  4096 Nov 16 07:28 .&lt;br /&gt;
drwxr-xr-x 28 xyz00-max xyz00  4096 Oct 22 23:06 ..&lt;br /&gt;
lrwxrwxrwx  1 xyz00-max xyz00    29 Nov 16 07:28 .dovecot.sieve -&amp;gt; Maildir/sieve/roundcube.sieve&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wurden von anderen Programmen -- oder manuell -- andere Filtersets angelegt, werden diese vom Plugin deaktiviert. Die ursprüngliche Filterdatei bleibt erhalten, aber obiger Symlink verweist dann auf die Roundcube-Filter.&lt;br /&gt;
&lt;br /&gt;
==== Manuelles Editieren ====&lt;br /&gt;
&lt;br /&gt;
Vom manuellen Bearbeiten der Filterdatei &amp;lt;tt&amp;gt;roundcube.sieve&amp;lt;/tt&amp;gt; wird abgeraten, da bei erneutem Einlesen durch das Roundcube-Plugin diese Regeln mit großer Wahrscheinlichkeit wieder automatisch umgeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Für komplexeres Filtern kann eine komplett manuelle Datei angelegt werden und entsprechend verlinkt werden. Siehe auch den Artikel zu [[Managesieve]].&lt;br /&gt;
&lt;br /&gt;
==== Links ====&lt;br /&gt;
&lt;br /&gt;
Einige Sieve-relevante Links, sind im entsprechenden [https://wiki.hostsharing.net/index.php?title=Managesieve#Links Managesieve Wiki-Artikel] angegeben: &lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;br /&gt;
[[Kategorie:Glossar]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Datei:Roundcube_Sieve_X-Spam-Level.png&amp;diff=7638</id>
		<title>Datei:Roundcube Sieve X-Spam-Level.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Datei:Roundcube_Sieve_X-Spam-Level.png&amp;diff=7638"/>
		<updated>2026-09-03T12:22:38Z</updated>

		<summary type="html">&lt;p&gt;Tim00: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Roundcube_-_Filter&amp;diff=7637</id>
		<title>Roundcube - Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Roundcube_-_Filter&amp;diff=7637"/>
		<updated>2026-09-03T12:19:49Z</updated>

		<summary type="html">&lt;p&gt;Tim00: Änderung 7636 von Tim00 (Diskussion) rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Roundcube - Filter ==&lt;br /&gt;
&lt;br /&gt;
Das Webmailprogramm [[Roundcube]] erlaubt Emails automatisch zu Filtern. Dieser Artikel beschreibt, wie mit der Erweiterung sieverules solche Filter definiert werden können.&lt;br /&gt;
&lt;br /&gt;
=== Allgemeines zum Filtern ===&lt;br /&gt;
&lt;br /&gt;
Über das Mailzustellungsprogramm Deliver ist es mit der Erweiterung [[Managesieve]] möglich Emails beim Eintreffen in der Mailbox zu Filtern. Die Filterung findet hierbei bereits auf dem Server statt, so daß der User nicht mit seinem Mailprogramm oder Webmailer eingeloggt sein muß.&lt;br /&gt;
&lt;br /&gt;
Hierbei ist es möglich u.a. folgende Aktionen durchzuführen&lt;br /&gt;
&lt;br /&gt;
* Mails in einen bestimmten Ordner abzuspeichern&lt;br /&gt;
* Mails an einen anderen Empfänger weiterzuleiten&lt;br /&gt;
* eine Abwesenheitsmeldung zu verschicken&lt;br /&gt;
* den Empfang einer Email abzulehnen&lt;br /&gt;
* eine Mail zu löschen&lt;br /&gt;
&lt;br /&gt;
Die Ausführung dieser Filteraktionen kann gesteuert werden z.B. basierend auf&lt;br /&gt;
&lt;br /&gt;
* dem Absender der eintreffenden Email&lt;br /&gt;
* des Titels oder Teilen hiervon&lt;br /&gt;
* dem Vorhandensein oder Nichtvorhandensein bestimmter Wörter im Text der Nachricht&lt;br /&gt;
* die Auswertung von zusätzlichen Mail-Headern.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-01-einstellungen.png|miniatur|250px|right|Einstellungen]]&lt;br /&gt;
Detaillierte Informationen können z.B. der [http://de.wikipedia.org/wiki/Sieve Wikipedia] oder unter [http://www.sieve.info sieve.info] entnommen werden. Im Hostsharing-Wiki unter [[Managesieve]] sind ebenfalls weitere Grundlageninformationen zu finden.&lt;br /&gt;
&lt;br /&gt;
=== Einrichtung ===&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn der Nutzer schon eine .forward mit z.b. procmail nutzt muss wie unter &lt;br /&gt;
[https://wiki.hostsharing.net/index.php?title=Managesieve#Zusammenarbeit_mit_Procmail Zusammenarbeit_mit_Procmail]&lt;br /&gt;
beschrieben ist beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Filter können unter &amp;lt;tt&amp;gt;Einstellungen&amp;lt;/tt&amp;gt; eingerichtet und verändert werden. Hierzu im Menu Einstellungen den Reiter ganz rechts &amp;lt;tt&amp;gt;Filter&amp;lt;/tt&amp;gt; auswählen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-02-mailuebersicht.png|center|none|frame|Ungefilterter Posteingang]]&lt;br /&gt;
Für die folgenden Beispiele wird davon ausgegangen, daß der Nutzer in seinem Posteingang ohne Filter die Situation, wie im Bild oben angezeigt vorfindet: Viele Emails aus (drei) Mailinglisten und eine private Email. Alle Mails sind in einem Ordner und erschweren das Finden der ggf. wichtigen privaten Email.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-03-neuer-filter.png|miniatur|250px|right|Neuen Filter anlegen]]&lt;br /&gt;
Zunächst soll ein neuer Filter angelegt werden, der die Emails der Mailingliste &amp;lt;tt&amp;gt;otrs-de&amp;lt;/tt&amp;gt; [http://doc.otrs.org/2.2/de/html/additional-resources-mailinglists.html] in einen eigenen Ordner verschiebt.&lt;br /&gt;
&lt;br /&gt;
Hierzu unter der (leeren) Filterliste auf das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; zum Anlegen eines Neuen Filters klicken.&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-04-OTRS-filter.png|miniatur|600px|right|Anlegen eines Filters für eine Mailingliste]]&lt;br /&gt;
Im neu geöffneten Formular kann der neue Filter definiert werden.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Filternamen&#039;&#039;&#039; vergeben: zum Beispiel OTRS für die entsprechende Maillingliste (oder zur besseren späteren Erinnerung: &amp;quot;Mailingliste otrs-de&amp;quot;). &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;OTRS&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Filterregel&#039;&#039;&#039;: Hier wird definiert unter welchen Bedingungen der Filter angewandt werden soll.&amp;lt;br&amp;gt;Drei Optionen stehen zur Auswahl&lt;br /&gt;
** Irgendeine Bedingung muß erfüllt sein (ODER)&lt;br /&gt;
** Alle Bedingungen müssen erfüllt sein (UND) &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Auswählen&amp;lt;/span&amp;gt;&lt;br /&gt;
** Die Bedingung ist für alle Emails gültig (keine Bedingung notwendig)&lt;br /&gt;
* Die Definition der Filterregel beinhaltet das Auswahl eines Teils der Nachricht (z.B. Absender, Datum, Betreff, Text) und einem Wert, mit dem verglichen werden soll. In unserem Beispiel: &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;BETREFF enthält &amp;lt;nowiki&amp;gt;[otrs-de]&amp;lt;/nowiki&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Filteraktion&#039;&#039;&#039;: Die Aktion, die ausgeführt werden soll. &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Verschiebe Nachricht nach OTRS&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Bei Aktionen, die Nachrichten in andere Ordner verschieben oder kopieren werden die möglichen Ordner die zum Zeitpunkt der Filteranlage existieren in einem Drop-Down-Menu angezeigt.&lt;br /&gt;
* &#039;&#039;&#039;Speichern&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-05-hostsharing-filter.png|miniatur|600px|right|Filter für Mailingliste über Mail-Header und Ausnahme]]&lt;br /&gt;
=== Weitere Beispiele ===&lt;br /&gt;
&lt;br /&gt;
==== Maillinglisten Filter ====&lt;br /&gt;
&lt;br /&gt;
Im Beispiel rechts werden wieder die Emails einer Mailinglliste gefiltert. Hier handelt es sich um die &amp;lt;tt&amp;gt;Technik&amp;lt;/tt&amp;gt;-Liste von Hostsharing.&lt;br /&gt;
&lt;br /&gt;
Der Filter erhält folgende Kriterien:&lt;br /&gt;
* &#039;&#039;&#039;Filterregel&#039;&#039;&#039;: Der Filter wird &#039;&#039;&#039;nicht&#039;&#039;&#039; angewandt, wenn der Text der Nachricht das Wort &amp;quot;Festplattencrash&amp;quot; enthält, der Empfänger, solche Emails also in seinem Posteingang behalten möchte.&amp;lt;br&amp;gt;Darüber hinaus wird die Mailingliste identifiziert über den Mail-Header &amp;lt;tt&amp;gt;List-Id&amp;lt;/tt&amp;gt;. Solche zusätzlichen Mail-Header können über die Auswahl &amp;quot;Anderer Header&amp;quot; ausgewählt werden.&amp;lt;br&amp;gt;Beide Bedingungen müssen erfüllt sein (UND), also &amp;quot;trifft alle folgenden Regeln&amp;quot; auswählen.&lt;br /&gt;
* &#039;&#039;&#039;Filteraktion&#039;&#039;&#039;: Wie im ersten Beispiele wieder das Verschieben in einen Ordner, hier &amp;lt;tt&amp;gt;hostsharing&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-06-abwesenheitsmeldung-filter.png|miniatur|600px|right|Abwesenheitsmeldung]]&lt;br /&gt;
==== Abwesenheitsmeldung ====&lt;br /&gt;
&lt;br /&gt;
Nutzer möchten oft bei längerer Abwesenheit dem Absender einer Email mitteilen, daß sie die empfangene Email z.B. wegen Urlaubs nicht lesen können. Hierzu kann eine Abwesenheitsmeldung definiert werden, die automatisch eine Antwort-Email generiert mit einem vordefinierten Text.&lt;br /&gt;
&lt;br /&gt;
Im Beispiel sollen die Absender &amp;quot;peter.lustig&amp;quot; und &amp;quot;Wickie&amp;quot; keine Abwesenheitsmeldung erhalten, sowie bei Emails, die das Wort &amp;quot;Werbung&amp;quot; im Betreff enthalten auch keine Abwesenheitsmeldung verschickt werden.&lt;br /&gt;
* &amp;quot;Absender enthält nicht &#039;peter.lustig&#039;&amp;quot; - Ein Vergleich mit der Email-&#039;&#039;Adresse&#039;&#039; wird durchgeführt.&amp;lt;br&amp;gt;Peter &amp;lt;peter.lustig@example.org&amp;gt; - Hier ist peter.lustig in der Adresse enthalten&amp;lt;br&amp;gt;Peter.Lustig &amp;lt;peter@example.org&amp;gt; - Hier ist peter.lustig &#039;&#039;nicht&#039;&#039; in der &#039;&#039;Adresse&#039;&#039; enthalten.&lt;br /&gt;
* &amp;quot;Anderer Header &amp;quot;From&amp;quot; enthält nicht &#039;Wickie&#039;&amp;quot; - Ein Vergleich mit der &#039;&#039;kompletten Absender-Angabe&#039;&#039; wird durchgeführt&amp;lt;br&amp;gt;&#039;&#039;Susanne &amp;lt;wickie@example.org&amp;gt;&#039;&#039; aber auch &#039;&#039;Wickie &amp;lt;susanne@example.org&amp;gt;&#039;&#039; werden gefunden&lt;br /&gt;
* &amp;quot;Betreff enthält nicht &#039;Werbung&#039; - Das Wort Werbung darf nicht im Betreff enthalten sein.&lt;br /&gt;
&lt;br /&gt;
In den &#039;&#039;&#039;Filteraktionen&#039;&#039;&#039; wird die Aktion &amp;quot;Abwesenheitsmeldung&amp;quot; ausgewählt.&lt;br /&gt;
* &#039;&#039;&#039;Absender&#039;&#039;&#039;: Hat man mehrere Identitäten in Webmail angelegt, kann man hier aussuchen unter welchem Absender die Abwesenheitsmeldung geschickt werden soll.&lt;br /&gt;
* &#039;&#039;&#039;Alias&#039;&#039;&#039;: Die Vacation-Extension schickt Abwesenheitsmeldungen &#039;&#039;&#039;nur&#039;&#039;&#039; wenn die Mail an eine dem System für &#039;&#039;diesen&#039;&#039; Account bekannte Email-Adresse geschickt wurde. Im konkreten Fall bei der Erstellung über Roundcube müssen also für jede Email-Adresse Identitäten angelegt werden, also z.B. sowohl max.mustermann@example.org und maexchen@example.org. Diese müssen dann auch unter &amp;quot;Alias&amp;quot; explizit ausgewählt werden. Werden Emails an den Account mit einer anderen Empfänger-Adresse geschickt, erhalten diese &#039;&#039;&#039;keine&#039;&#039;&#039; Abwesenheitsmeldung. siehe auch [http://tools.ietf.org/html/rfc5230#section-4.5 RFC5230] Abschnitt 4.5&lt;br /&gt;
* &#039;&#039;&#039;Zeitraum&#039;&#039;&#039;: Sagt aus, nach wieviel Tagen ein Absender eine erneute Abwesenheitsmeldung erhält. Im Beispiel also z.B. nur einmal alle 3 Tage. Wenn der Absender dazwischen neue Emails versendet, erhält er keine neue Abwesenheitsmeldung. Nach 3 Tagen wird bei erneuten Emails wieder eine Abwesenheitsmeldung verschickt. Hierz speichert sich &amp;lt;tt&amp;gt;deliver&amp;lt;/tt&amp;gt; eine Liste der Empfänger.&lt;br /&gt;
* &#039;&#039;&#039;Betreff&#039;&#039;&#039;: Der Betreff der Abwesenheitsmeldung, z.B. &amp;quot;Abwesenheit - Urlaub&amp;quot;; der originale Betreff der Email kann zur Identifizierung angehängt werden.&amp;lt;br&amp;gt;Wird also automatisch auf eine Mail &amp;quot;Geburtstagseinladung&amp;quot; geantwortet, wäre der Betreff der Abwesenheitsmeldung &amp;quot;Abwesenheit - Urlaub Geburtstagseinladung&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;Nachricht&#039;&#039;&#039;: Der eigentliche Text der Abwesenheitsmeldung, z.B. Dauer der Abwesenheitsmeldung, Vertretungsregelung, Erreichbarkeit.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-07-reihenfolge-a.png|miniatur|300px|left|Reihenfolge Filter ändern über Pfeile]]&lt;br /&gt;
[[Bild:Sieve-07-reihenfolge-b.png|miniatur|300px|right|Nach Änderung der Reihenfolge]]&lt;br /&gt;
===== Reihenfolge von Filtern =====&lt;br /&gt;
&lt;br /&gt;
Insbesondere bei Abwesenheitsmeldungen ist die Reihenfolge der Filter wichtig. Im Beispiel links wird der Filter &amp;quot;osm&amp;quot; erst nach der Abwesenheitsmeldung angewandt, Mails, die durch diesen Filter nicht schon wegsortiert wurden, erhalten also eine Abwesenheitsmeldung. Wenn dies unerwünscht ist, muß der Filter &#039;&#039;&#039;vor&#039;&#039;&#039; den Filter der Abwesenheitsmeldung verschoben werden (über die Pfeile rechts neben des Filterliste).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
In (u.a.) folgenden Fällen werden &#039;&#039;&#039;Abwesenheitsmeldungen vom System nicht verschickt&#039;&#039;&#039;:&lt;br /&gt;
* Die Absenderadresse deutet auf eine Mailingliste hin, z.B. beginnt mit: &#039;&#039;mailer-daemon&#039;&#039;, &#039;&#039;listserv&#039;&#039;, &#039;&#039;majordomo&#039;&#039;, &#039;&#039;owner-&#039;&#039; oder enthält &#039;&#039;-request&#039;&#039;&lt;br /&gt;
* Es existiert ein Header &amp;quot;Precedence&amp;quot; der &#039;&#039;junk&#039;&#039;, &#039;&#039;bulk&#039;&#039; oder &#039;&#039;list&#039;&#039; enthält.&lt;br /&gt;
* Der Empfänger der Nachricht steht nicht in &#039;&#039;To&#039;&#039; oder &#039;&#039;Cc&#039;&#039;.&lt;br /&gt;
* Sender und Empfänger haben dieselbe Email-Adresse.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-08-kopiesenden.png|miniatur|600px|right|TEXT]]&lt;br /&gt;
&lt;br /&gt;
==== Kopie an anderen Empfänger versenden. ====&lt;br /&gt;
&lt;br /&gt;
Eine erhaltene Email soll an eine andere Email-Adresse (in Kopie) weitergeleitet werden, z.B. von der Privatadresse an die Geschäftsadresse.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Filterregel&#039;&#039;&#039;: In diesem Beispiel soll der lokale Teil der Absender-Adresse verglichen werden. &amp;quot;Absender&amp;quot; wählen, dann &amp;quot;weitere Optionen&amp;quot; &#039;&#039;&#039;(1)&#039;&#039;&#039; und unter &#039;&#039;Operatoren&#039;&#039; &#039;&#039;User-Teil gleich&#039;&#039;. &#039;&#039;&#039;(2)&#039;&#039;&#039;&amp;lt;br&amp;gt; Im Beispiel wurde der User-Teil mit &#039;&#039;susanne.musterfrau&#039;&#039; &#039;&#039;&#039;(3)&#039;&#039;&#039; angegeben. Zur Email-Adresse &#039;&#039;susanne.musterfrau@example.de&#039;&#039; wird ein Match gefunden für &#039;&#039;sara-susanne.musterfrau@example.org&#039;&#039; hingegen nicht, weil der lokale Teil der Email-Adresse nicht übereinstimmt.&lt;br /&gt;
* &#039;&#039;&#039;Filteraktionen&#039;&#039;&#039;: &amp;quot;Sende eine Kopie an&amp;quot; wählen &#039;&#039;&#039;(4)&#039;&#039;&#039; und eine Ziel-Adresse angeben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-09-filter-abschalten-a.png|miniatur|400px|left|Filter abschalten]]&lt;br /&gt;
[[Bild:Sieve-09-filter-abschalten-b.png|miniatur|300px|right|Filterübersicht im inaktivem Filter]]&lt;br /&gt;
==== Filter deaktivieren/aktivieren ====&lt;br /&gt;
&lt;br /&gt;
Soll ein Filter temporär deaktivitert werden, kann in der Filterbearbeitung &#039;&#039;&#039;Filterregel abschalten&#039;&#039;&#039; angeklickt werden. In der Filterübersicht ist der Filter dann als &#039;&#039;&amp;quot;(abgeschaltet)&amp;quot;&#039;&#039; markiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-10-nach-anwendung-filter.png|miniatur|600px|right|Nach dem Filtern]]&lt;br /&gt;
==== Nach dem Filtern ====&lt;br /&gt;
&lt;br /&gt;
Die im obigen Beispiel gezeigte Inbox mit über 200 Emails sieht nach Anwendung der Filter wie im nebenstehenden Bild aus.&lt;br /&gt;
&lt;br /&gt;
* Im Posteingang &#039;&#039;&#039;(1)&#039;&#039;&#039; ist nur noch eine private Email vorhanden&lt;br /&gt;
* Die Emails and die Mailinglisten wurden in die jeweiligen Ordner &#039;&#039;&#039;(2)&#039;&#039;&#039; einsortiert.&lt;br /&gt;
&lt;br /&gt;
=== Technisches ===&lt;br /&gt;
&lt;br /&gt;
==== Speicherort ====&lt;br /&gt;
&lt;br /&gt;
Roundcube speichert die erstellten Regeln unter &lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
~/Maildir/sieve/roundcube.sieve&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und verlinkt diese Filterdatei automatisch für die Benutzung mit dovecot:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@h01:~$ ls -al &lt;br /&gt;
drwxr-xr-x  5 xyz00-max xyz00  4096 Nov 16 07:28 .&lt;br /&gt;
drwxr-xr-x 28 xyz00-max xyz00  4096 Oct 22 23:06 ..&lt;br /&gt;
lrwxrwxrwx  1 xyz00-max xyz00    29 Nov 16 07:28 .dovecot.sieve -&amp;gt; Maildir/sieve/roundcube.sieve&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wurden von anderen Programmen -- oder manuell -- andere Filtersets angelegt, werden diese vom Plugin deaktiviert. Die ursprüngliche Filterdatei bleibt erhalten, aber obiger Symlink verweist dann auf die Roundcube-Filter.&lt;br /&gt;
&lt;br /&gt;
==== Manuelles Editieren ====&lt;br /&gt;
&lt;br /&gt;
Vom manuellen Bearbeiten der Filterdatei &amp;lt;tt&amp;gt;roundcube.sieve&amp;lt;/tt&amp;gt; wird abgeraten, da bei erneutem Einlesen durch das Roundcube-Plugin diese Regeln mit großer Wahrscheinlichkeit wieder automatisch umgeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Für komplexeres Filtern kann eine komplett manuelle Datei angelegt werden und entsprechend verlinkt werden. Siehe auch den Artikel zu [[Managesieve]].&lt;br /&gt;
&lt;br /&gt;
==== Links ====&lt;br /&gt;
&lt;br /&gt;
Einige Sieve-relevante Links, sind im entsprechenden [https://wiki.hostsharing.net/index.php?title=Managesieve#Links Managesieve Wiki-Artikel] angegeben: &lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;br /&gt;
[[Kategorie:Glossar]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Roundcube_-_Filter&amp;diff=7636</id>
		<title>Roundcube - Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Roundcube_-_Filter&amp;diff=7636"/>
		<updated>2026-09-03T12:17:01Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Reihenfolge von Filtern */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Roundcube - Filter ==&lt;br /&gt;
&lt;br /&gt;
Das Webmailprogramm [[Roundcube]] erlaubt Emails automatisch zu Filtern. Dieser Artikel beschreibt, wie mit der Erweiterung sieverules solche Filter definiert werden können.&lt;br /&gt;
&lt;br /&gt;
=== Allgemeines zum Filtern ===&lt;br /&gt;
&lt;br /&gt;
Über das Mailzustellungsprogramm Deliver ist es mit der Erweiterung [[Managesieve]] möglich Emails beim Eintreffen in der Mailbox zu Filtern. Die Filterung findet hierbei bereits auf dem Server statt, so daß der User nicht mit seinem Mailprogramm oder Webmailer eingeloggt sein muß.&lt;br /&gt;
&lt;br /&gt;
Hierbei ist es möglich u.a. folgende Aktionen durchzuführen&lt;br /&gt;
&lt;br /&gt;
* Mails in einen bestimmten Ordner abzuspeichern&lt;br /&gt;
* Mails an einen anderen Empfänger weiterzuleiten&lt;br /&gt;
* eine Abwesenheitsmeldung zu verschicken&lt;br /&gt;
* den Empfang einer Email abzulehnen&lt;br /&gt;
* eine Mail zu löschen&lt;br /&gt;
&lt;br /&gt;
Die Ausführung dieser Filteraktionen kann gesteuert werden z.B. basierend auf&lt;br /&gt;
&lt;br /&gt;
* dem Absender der eintreffenden Email&lt;br /&gt;
* des Titels oder Teilen hiervon&lt;br /&gt;
* dem Vorhandensein oder Nichtvorhandensein bestimmter Wörter im Text der Nachricht&lt;br /&gt;
* die Auswertung von zusätzlichen Mail-Headern.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-01-einstellungen.png|miniatur|250px|right|Einstellungen]]&lt;br /&gt;
Detaillierte Informationen können z.B. der [http://de.wikipedia.org/wiki/Sieve Wikipedia] oder unter [http://www.sieve.info sieve.info] entnommen werden. Im Hostsharing-Wiki unter [[Managesieve]] sind ebenfalls weitere Grundlageninformationen zu finden.&lt;br /&gt;
&lt;br /&gt;
=== Einrichtung ===&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn der Nutzer schon eine .forward mit z.b. procmail nutzt muss wie unter &lt;br /&gt;
[https://wiki.hostsharing.net/index.php?title=Managesieve#Zusammenarbeit_mit_Procmail Zusammenarbeit_mit_Procmail]&lt;br /&gt;
beschrieben ist beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Filter können unter &amp;lt;tt&amp;gt;Einstellungen&amp;lt;/tt&amp;gt; eingerichtet und verändert werden. Hierzu im Menu Einstellungen den Reiter ganz rechts &amp;lt;tt&amp;gt;Filter&amp;lt;/tt&amp;gt; auswählen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-02-mailuebersicht.png|center|none|frame|Ungefilterter Posteingang]]&lt;br /&gt;
Für die folgenden Beispiele wird davon ausgegangen, daß der Nutzer in seinem Posteingang ohne Filter die Situation, wie im Bild oben angezeigt vorfindet: Viele Emails aus (drei) Mailinglisten und eine private Email. Alle Mails sind in einem Ordner und erschweren das Finden der ggf. wichtigen privaten Email.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-03-neuer-filter.png|miniatur|250px|right|Neuen Filter anlegen]]&lt;br /&gt;
Zunächst soll ein neuer Filter angelegt werden, der die Emails der Mailingliste &amp;lt;tt&amp;gt;otrs-de&amp;lt;/tt&amp;gt; [http://doc.otrs.org/2.2/de/html/additional-resources-mailinglists.html] in einen eigenen Ordner verschiebt.&lt;br /&gt;
&lt;br /&gt;
Hierzu unter der (leeren) Filterliste auf das &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; zum Anlegen eines Neuen Filters klicken.&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-04-OTRS-filter.png|miniatur|600px|right|Anlegen eines Filters für eine Mailingliste]]&lt;br /&gt;
Im neu geöffneten Formular kann der neue Filter definiert werden.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Filternamen&#039;&#039;&#039; vergeben: zum Beispiel OTRS für die entsprechende Maillingliste (oder zur besseren späteren Erinnerung: &amp;quot;Mailingliste otrs-de&amp;quot;). &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;OTRS&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Filterregel&#039;&#039;&#039;: Hier wird definiert unter welchen Bedingungen der Filter angewandt werden soll.&amp;lt;br&amp;gt;Drei Optionen stehen zur Auswahl&lt;br /&gt;
** Irgendeine Bedingung muß erfüllt sein (ODER)&lt;br /&gt;
** Alle Bedingungen müssen erfüllt sein (UND) &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Auswählen&amp;lt;/span&amp;gt;&lt;br /&gt;
** Die Bedingung ist für alle Emails gültig (keine Bedingung notwendig)&lt;br /&gt;
* Die Definition der Filterregel beinhaltet das Auswahl eines Teils der Nachricht (z.B. Absender, Datum, Betreff, Text) und einem Wert, mit dem verglichen werden soll. In unserem Beispiel: &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;BETREFF enthält &amp;lt;nowiki&amp;gt;[otrs-de]&amp;lt;/nowiki&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Filteraktion&#039;&#039;&#039;: Die Aktion, die ausgeführt werden soll. &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Verschiebe Nachricht nach OTRS&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Bei Aktionen, die Nachrichten in andere Ordner verschieben oder kopieren werden die möglichen Ordner die zum Zeitpunkt der Filteranlage existieren in einem Drop-Down-Menu angezeigt.&lt;br /&gt;
* &#039;&#039;&#039;Speichern&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-05-hostsharing-filter.png|miniatur|600px|right|Filter für Mailingliste über Mail-Header und Ausnahme]]&lt;br /&gt;
=== Weitere Beispiele ===&lt;br /&gt;
&lt;br /&gt;
==== Maillinglisten Filter ====&lt;br /&gt;
&lt;br /&gt;
Im Beispiel rechts werden wieder die Emails einer Mailinglliste gefiltert. Hier handelt es sich um die &amp;lt;tt&amp;gt;Technik&amp;lt;/tt&amp;gt;-Liste von Hostsharing.&lt;br /&gt;
&lt;br /&gt;
Der Filter erhält folgende Kriterien:&lt;br /&gt;
* &#039;&#039;&#039;Filterregel&#039;&#039;&#039;: Der Filter wird &#039;&#039;&#039;nicht&#039;&#039;&#039; angewandt, wenn der Text der Nachricht das Wort &amp;quot;Festplattencrash&amp;quot; enthält, der Empfänger, solche Emails also in seinem Posteingang behalten möchte.&amp;lt;br&amp;gt;Darüber hinaus wird die Mailingliste identifiziert über den Mail-Header &amp;lt;tt&amp;gt;List-Id&amp;lt;/tt&amp;gt;. Solche zusätzlichen Mail-Header können über die Auswahl &amp;quot;Anderer Header&amp;quot; ausgewählt werden.&amp;lt;br&amp;gt;Beide Bedingungen müssen erfüllt sein (UND), also &amp;quot;trifft alle folgenden Regeln&amp;quot; auswählen.&lt;br /&gt;
* &#039;&#039;&#039;Filteraktion&#039;&#039;&#039;: Wie im ersten Beispiele wieder das Verschieben in einen Ordner, hier &amp;lt;tt&amp;gt;hostsharing&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-06-abwesenheitsmeldung-filter.png|miniatur|600px|right|Abwesenheitsmeldung]]&lt;br /&gt;
==== Abwesenheitsmeldung ====&lt;br /&gt;
&lt;br /&gt;
Nutzer möchten oft bei längerer Abwesenheit dem Absender einer Email mitteilen, daß sie die empfangene Email z.B. wegen Urlaubs nicht lesen können. Hierzu kann eine Abwesenheitsmeldung definiert werden, die automatisch eine Antwort-Email generiert mit einem vordefinierten Text.&lt;br /&gt;
&lt;br /&gt;
Im Beispiel sollen die Absender &amp;quot;peter.lustig&amp;quot; und &amp;quot;Wickie&amp;quot; keine Abwesenheitsmeldung erhalten, sowie bei Emails, die das Wort &amp;quot;Werbung&amp;quot; im Betreff enthalten auch keine Abwesenheitsmeldung verschickt werden.&lt;br /&gt;
* &amp;quot;Absender enthält nicht &#039;peter.lustig&#039;&amp;quot; - Ein Vergleich mit der Email-&#039;&#039;Adresse&#039;&#039; wird durchgeführt.&amp;lt;br&amp;gt;Peter &amp;lt;peter.lustig@example.org&amp;gt; - Hier ist peter.lustig in der Adresse enthalten&amp;lt;br&amp;gt;Peter.Lustig &amp;lt;peter@example.org&amp;gt; - Hier ist peter.lustig &#039;&#039;nicht&#039;&#039; in der &#039;&#039;Adresse&#039;&#039; enthalten.&lt;br /&gt;
* &amp;quot;Anderer Header &amp;quot;From&amp;quot; enthält nicht &#039;Wickie&#039;&amp;quot; - Ein Vergleich mit der &#039;&#039;kompletten Absender-Angabe&#039;&#039; wird durchgeführt&amp;lt;br&amp;gt;&#039;&#039;Susanne &amp;lt;wickie@example.org&amp;gt;&#039;&#039; aber auch &#039;&#039;Wickie &amp;lt;susanne@example.org&amp;gt;&#039;&#039; werden gefunden&lt;br /&gt;
* &amp;quot;Betreff enthält nicht &#039;Werbung&#039; - Das Wort Werbung darf nicht im Betreff enthalten sein.&lt;br /&gt;
&lt;br /&gt;
In den &#039;&#039;&#039;Filteraktionen&#039;&#039;&#039; wird die Aktion &amp;quot;Abwesenheitsmeldung&amp;quot; ausgewählt.&lt;br /&gt;
* &#039;&#039;&#039;Absender&#039;&#039;&#039;: Hat man mehrere Identitäten in Webmail angelegt, kann man hier aussuchen unter welchem Absender die Abwesenheitsmeldung geschickt werden soll.&lt;br /&gt;
* &#039;&#039;&#039;Alias&#039;&#039;&#039;: Die Vacation-Extension schickt Abwesenheitsmeldungen &#039;&#039;&#039;nur&#039;&#039;&#039; wenn die Mail an eine dem System für &#039;&#039;diesen&#039;&#039; Account bekannte Email-Adresse geschickt wurde. Im konkreten Fall bei der Erstellung über Roundcube müssen also für jede Email-Adresse Identitäten angelegt werden, also z.B. sowohl max.mustermann@example.org und maexchen@example.org. Diese müssen dann auch unter &amp;quot;Alias&amp;quot; explizit ausgewählt werden. Werden Emails an den Account mit einer anderen Empfänger-Adresse geschickt, erhalten diese &#039;&#039;&#039;keine&#039;&#039;&#039; Abwesenheitsmeldung. siehe auch [http://tools.ietf.org/html/rfc5230#section-4.5 RFC5230] Abschnitt 4.5&lt;br /&gt;
* &#039;&#039;&#039;Zeitraum&#039;&#039;&#039;: Sagt aus, nach wieviel Tagen ein Absender eine erneute Abwesenheitsmeldung erhält. Im Beispiel also z.B. nur einmal alle 3 Tage. Wenn der Absender dazwischen neue Emails versendet, erhält er keine neue Abwesenheitsmeldung. Nach 3 Tagen wird bei erneuten Emails wieder eine Abwesenheitsmeldung verschickt. Hierz speichert sich &amp;lt;tt&amp;gt;deliver&amp;lt;/tt&amp;gt; eine Liste der Empfänger.&lt;br /&gt;
* &#039;&#039;&#039;Betreff&#039;&#039;&#039;: Der Betreff der Abwesenheitsmeldung, z.B. &amp;quot;Abwesenheit - Urlaub&amp;quot;; der originale Betreff der Email kann zur Identifizierung angehängt werden.&amp;lt;br&amp;gt;Wird also automatisch auf eine Mail &amp;quot;Geburtstagseinladung&amp;quot; geantwortet, wäre der Betreff der Abwesenheitsmeldung &amp;quot;Abwesenheit - Urlaub Geburtstagseinladung&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;Nachricht&#039;&#039;&#039;: Der eigentliche Text der Abwesenheitsmeldung, z.B. Dauer der Abwesenheitsmeldung, Vertretungsregelung, Erreichbarkeit.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-07-reihenfolge-a.png|miniatur|300px|left|Reihenfolge Filter ändern über Pfeile]]&lt;br /&gt;
[[Bild:Sieve-07-reihenfolge-b.png|miniatur|300px|right|Nach Änderung der Reihenfolge]]&lt;br /&gt;
==== Reihenfolge von Filtern ====&lt;br /&gt;
&lt;br /&gt;
Insbesondere bei Abwesenheitsmeldungen ist die Reihenfolge der Filter wichtig. Im Beispiel links wird der Filter &amp;quot;osm&amp;quot; erst nach der Abwesenheitsmeldung angewandt, Mails, die durch diesen Filter nicht schon wegsortiert wurden, erhalten also eine Abwesenheitsmeldung. Wenn dies unerwünscht ist, muß der Filter &#039;&#039;&#039;vor&#039;&#039;&#039; den Filter der Abwesenheitsmeldung verschoben werden (über die Pfeile rechts neben des Filterliste).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
In (u.a.) folgenden Fällen werden &#039;&#039;&#039;Abwesenheitsmeldungen vom System nicht verschickt&#039;&#039;&#039;:&lt;br /&gt;
* Die Absenderadresse deutet auf eine Mailingliste hin, z.B. beginnt mit: &#039;&#039;mailer-daemon&#039;&#039;, &#039;&#039;listserv&#039;&#039;, &#039;&#039;majordomo&#039;&#039;, &#039;&#039;owner-&#039;&#039; oder enthält &#039;&#039;-request&#039;&#039;&lt;br /&gt;
* Es existiert ein Header &amp;quot;Precedence&amp;quot; der &#039;&#039;junk&#039;&#039;, &#039;&#039;bulk&#039;&#039; oder &#039;&#039;list&#039;&#039; enthält.&lt;br /&gt;
* Der Empfänger der Nachricht steht nicht in &#039;&#039;To&#039;&#039; oder &#039;&#039;Cc&#039;&#039;.&lt;br /&gt;
* Sender und Empfänger haben dieselbe Email-Adresse.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-08-kopiesenden.png|miniatur|600px|right|TEXT]]&lt;br /&gt;
&lt;br /&gt;
==== Kopie an anderen Empfänger versenden. ====&lt;br /&gt;
&lt;br /&gt;
Eine erhaltene Email soll an eine andere Email-Adresse (in Kopie) weitergeleitet werden, z.B. von der Privatadresse an die Geschäftsadresse.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Filterregel&#039;&#039;&#039;: In diesem Beispiel soll der lokale Teil der Absender-Adresse verglichen werden. &amp;quot;Absender&amp;quot; wählen, dann &amp;quot;weitere Optionen&amp;quot; &#039;&#039;&#039;(1)&#039;&#039;&#039; und unter &#039;&#039;Operatoren&#039;&#039; &#039;&#039;User-Teil gleich&#039;&#039;. &#039;&#039;&#039;(2)&#039;&#039;&#039;&amp;lt;br&amp;gt; Im Beispiel wurde der User-Teil mit &#039;&#039;susanne.musterfrau&#039;&#039; &#039;&#039;&#039;(3)&#039;&#039;&#039; angegeben. Zur Email-Adresse &#039;&#039;susanne.musterfrau@example.de&#039;&#039; wird ein Match gefunden für &#039;&#039;sara-susanne.musterfrau@example.org&#039;&#039; hingegen nicht, weil der lokale Teil der Email-Adresse nicht übereinstimmt.&lt;br /&gt;
* &#039;&#039;&#039;Filteraktionen&#039;&#039;&#039;: &amp;quot;Sende eine Kopie an&amp;quot; wählen &#039;&#039;&#039;(4)&#039;&#039;&#039; und eine Ziel-Adresse angeben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sieve-09-filter-abschalten-a.png|miniatur|400px|left|Filter abschalten]]&lt;br /&gt;
[[Bild:Sieve-09-filter-abschalten-b.png|miniatur|300px|right|Filterübersicht im inaktivem Filter]]&lt;br /&gt;
==== Filter deaktivieren/aktivieren ====&lt;br /&gt;
&lt;br /&gt;
Soll ein Filter temporär deaktivitert werden, kann in der Filterbearbeitung &#039;&#039;&#039;Filterregel abschalten&#039;&#039;&#039; angeklickt werden. In der Filterübersicht ist der Filter dann als &#039;&#039;&amp;quot;(abgeschaltet)&amp;quot;&#039;&#039; markiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear: both&amp;quot; /&amp;gt;&lt;br /&gt;
[[Bild:Sieve-10-nach-anwendung-filter.png|miniatur|600px|right|Nach dem Filtern]]&lt;br /&gt;
==== Nach dem Filtern ====&lt;br /&gt;
&lt;br /&gt;
Die im obigen Beispiel gezeigte Inbox mit über 200 Emails sieht nach Anwendung der Filter wie im nebenstehenden Bild aus.&lt;br /&gt;
&lt;br /&gt;
* Im Posteingang &#039;&#039;&#039;(1)&#039;&#039;&#039; ist nur noch eine private Email vorhanden&lt;br /&gt;
* Die Emails and die Mailinglisten wurden in die jeweiligen Ordner &#039;&#039;&#039;(2)&#039;&#039;&#039; einsortiert.&lt;br /&gt;
&lt;br /&gt;
=== Technisches ===&lt;br /&gt;
&lt;br /&gt;
==== Speicherort ====&lt;br /&gt;
&lt;br /&gt;
Roundcube speichert die erstellten Regeln unter &lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
~/Maildir/sieve/roundcube.sieve&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und verlinkt diese Filterdatei automatisch für die Benutzung mit dovecot:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@h01:~$ ls -al &lt;br /&gt;
drwxr-xr-x  5 xyz00-max xyz00  4096 Nov 16 07:28 .&lt;br /&gt;
drwxr-xr-x 28 xyz00-max xyz00  4096 Oct 22 23:06 ..&lt;br /&gt;
lrwxrwxrwx  1 xyz00-max xyz00    29 Nov 16 07:28 .dovecot.sieve -&amp;gt; Maildir/sieve/roundcube.sieve&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wurden von anderen Programmen -- oder manuell -- andere Filtersets angelegt, werden diese vom Plugin deaktiviert. Die ursprüngliche Filterdatei bleibt erhalten, aber obiger Symlink verweist dann auf die Roundcube-Filter.&lt;br /&gt;
&lt;br /&gt;
==== Manuelles Editieren ====&lt;br /&gt;
&lt;br /&gt;
Vom manuellen Bearbeiten der Filterdatei &amp;lt;tt&amp;gt;roundcube.sieve&amp;lt;/tt&amp;gt; wird abgeraten, da bei erneutem Einlesen durch das Roundcube-Plugin diese Regeln mit großer Wahrscheinlichkeit wieder automatisch umgeschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Für komplexeres Filtern kann eine komplett manuelle Datei angelegt werden und entsprechend verlinkt werden. Siehe auch den Artikel zu [[Managesieve]].&lt;br /&gt;
&lt;br /&gt;
==== Links ====&lt;br /&gt;
&lt;br /&gt;
Einige Sieve-relevante Links, sind im entsprechenden [https://wiki.hostsharing.net/index.php?title=Managesieve#Links Managesieve Wiki-Artikel] angegeben: &lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;br /&gt;
[[Kategorie:Glossar]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Login_mit_SSH&amp;diff=7635</id>
		<title>Login mit SSH</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Login_mit_SSH&amp;diff=7635"/>
		<updated>2026-09-02T09:02:56Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Login ohne Passwort */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Baustelle}}&lt;br /&gt;
&lt;br /&gt;
Um sich einloggen zu können, brauchst Du natürlich die Daten, die Dir von Hostsharing in einer Mail nach der Anmeldung zugeschickt wurden: &lt;br /&gt;
&lt;br /&gt;
Hostname: &#039;&#039;&#039;xyz00.hostsharing.net&#039;&#039;&#039; (wenn eine eigene Domain konnektiert ist auch &amp;lt;eigene-domain&amp;gt;.&amp;lt;tld&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Username: &#039;&#039;&#039;xyz00&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Passwort: &#039;&#039;&#039;(wie in der automatischen Mail mitgeteilt)&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei xyz00 handelt es sich um den Account des Paket-Admins. Initial ist für jedes neue Paket nur ein Admin-Account eingerichtet, dessen Benutzername die Form &#039;&#039;&#039;xyz00&#039;&#039;&#039; besitzt. &lt;br /&gt;
&lt;br /&gt;
Da dieser Account sehr viel Macht über das Paket hat, darf er nur über sichere Protokolle wie SSH benutzt werden. Unsichere Protokolle wie direktes FTP dürfen nicht verwendet werden, da diese die Passwörter im Klartext übertragen. Jeder Administrator auf der Übertragungsstrecke könnte mitlesen. &lt;br /&gt;
&lt;br /&gt;
Gleich vorab: Seine Website kann man später freilich über einen separaten Account per ftps, sftp, scp (und zur Not auch ftp) hochladen, doch dazu später mehr.&lt;br /&gt;
&lt;br /&gt;
Linux Systeme haben meist ssh, scp und sftp Clients vorinstalliert. Eine Freie Software zum sicheren Dateitransfer für Windows ist z.B. [http://winscp.net WinSCP] und ein Shell Zugang mit [http://www.chiark.greenend.org.uk/~sgtatham/putty/ PuTTY]. &lt;br /&gt;
&lt;br /&gt;
Nach der ggf. nötigen Installation eines ssh Clients, die hier nicht beschrieben werden, da sie nicht Hostsharing-spezifisch ist, kann der erste Login erfolgen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Login ==&lt;br /&gt;
&lt;br /&gt;
Mit OpenSSH ist der Aufruf auf der Kommandozeile z.B. folgender: &lt;br /&gt;
&lt;br /&gt;
 ssh xyz00@xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
Nach Aufbau der Verbindung wird dann das [[Passwort]] erfragt.&lt;br /&gt;
Danach erscheint in etwa folgende Bildschirmausgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Last login: Fri Apr 19 06:43:45 2002 from p5081f0c7.dip.t-dialin.net on pts/7&lt;br /&gt;
&lt;br /&gt;
Linux hopi 2.4.17 #2 SMP Thu Jan 17 14:35:38 CET 2002 i686 unknown&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+----------------------------------------------------------------+&lt;br /&gt;
| hopi.hostsharing.net |&lt;br /&gt;
| Bei Fragen oder Problemen bitte E-Mail an: |&lt;br /&gt;
| support@hostsharing.net (öffentliche Mailingliste) |&lt;br /&gt;
+----------------------------------------------------------------+&lt;br /&gt;
&lt;br /&gt;
Last login: Fri Apr 19 09:36:34 2002 from 62.156.160.59&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
xyz0@hopi:~$ █&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es macht durchaus Sinn, die ganz oben genannte &amp;quot;Last Login&amp;quot; Zeile zu prüfen, ob man dies auch selbst war (Uhrzeit und Provider), unten die &amp;quot;Last Login&amp;quot; Zeile gibt genau genommen das aktuelle Login aus, weil der Programmteil nach dem eigentlichen Login ausgeführt wird. &lt;br /&gt;
&lt;br /&gt;
Als nächstes ändern wir gleich unser [[Passwort]], da dieses schließlich unverschlüsselt per E-Mail versendet wurde. Dies geschieht unter UNIX mit dem Kommando passwd&lt;br /&gt;
&lt;br /&gt;
== Passwort ändern ==&lt;br /&gt;
&lt;br /&gt;
Eine Änderung des Passwortes geht dem Befehl passwd:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
xyz00@hopi:~$ passwd&lt;br /&gt;
&lt;br /&gt;
Changing password for xyz00&lt;br /&gt;
&lt;br /&gt;
(current) UNIX password: ALTESPASSWORT&lt;br /&gt;
&lt;br /&gt;
Enter new UNIX password: NEUESPASSWORT&lt;br /&gt;
&lt;br /&gt;
Retype new UNIX password: NEUESPASSWORT&lt;br /&gt;
&lt;br /&gt;
passwd: password updated successfully&lt;br /&gt;
&lt;br /&gt;
xyz00@hopi:~$ █&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Platzhalter &#039;&#039;&#039;NEUESPASSWORT&#039;&#039;&#039; und &#039;&#039;&#039;ALTESPASSWORT&#039;&#039;&#039; müssen dabei selbstverständlich gegen die entsprechenden [[Passworte]] ausgetauscht werden. Dabei sollte jedes Passwort mindestens 6 Zeichen lang sein, besser 8 Zeichen, und aus Buchstaben, Ziffern und ggf. Sonderzeichen bestehen. Allerdings sollte auf Umlaute verzichtet werden, da diese je nach verwendetem Zugangsweg nicht verwendet werden könnten. &lt;br /&gt;
&lt;br /&gt;
Ggf. kommt es zu Fehlermeldungen, z.B. wenn das neue [[Passwort]] zu simpel ist, oder bei der Wiederholung nicht identisch mit dem ersten Passwort ist. In dem Fall, den Vorgang einfach wiederholen. Solange das neue Passwort nicht erfolgreich übernommen wurde, bleibt das alte gültig. &lt;br /&gt;
&lt;br /&gt;
Es gibt User, denen der Paket-Admin nur das Recht eingeräumt hat, das eigene Passwort zu ändern, indem er ihnen die &amp;quot;Shell&amp;quot; /usr/bin/passwd zugewiesen hat. Diese User können durch einen Shell-Login nur ihr Passwort ändern, da das Programm passwd an Stelle einer Shell gestartet wird. Sie werden nach dem Einloggen automatisch auf diesen Dialog geführt.Mehr dazu unter [[User#Rechte]].&lt;br /&gt;
&lt;br /&gt;
==Sitzung beenden==&lt;br /&gt;
&lt;br /&gt;
Um die Sitzung zu beenden, sich also auszuloggen, gibt man exit ein. Das sieht dann so aus: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
xyz00@hopi:~$ exit &lt;br /&gt;
logout &lt;br /&gt;
Connection to xyz00.hostsharing.net closed.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Login mit Passwort ==&lt;br /&gt;
Um logins durch automatisierte Versuche zu erschweren sind auf den shared hosts Mechanismen in Betrieb, die ein Login mit Passwort erschweren, zum Beispiel durch ein Timeout, dass die Eingabe eines Passworts, wenn sie zu lange dauert, nicht funktioniert.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
(xyz00@xyz00.hostsharing.net) Password:&lt;br /&gt;
Connection closed by 2a01:37:1000::53df:4f85:0 port 22&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Man muss also das Passwort in der Zwischenablage haben, dann den Loginbefehl geben und dann sofort das Passwort eingeben. Das ist in vielerlei hinsicht unsicher, da die Zwischenablage evtl gespeichert wird. (ein passwort Manager wie keepassXC löscht die eigenen Abgelegten Werte per Default nach einigen Sekunden), diese Methode, weil es wirklich schnell gehen muss (wenige Sekunden zur Passworteingabe) kann auch zu anderen Fehler führen die dass Passwort offenlegen, z.B. weil es versehentlich in der Hektik in ein falsches Fenster gepostet wird. &lt;br /&gt;
&lt;br /&gt;
Eine andere Alternative ist sshpass:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sshpass -p your_password ssh xyz00@xyz00.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es spricht vieles dafür, den Zugang über SSH mit einem Schlüsselpaar zu konfigurieren.&lt;br /&gt;
&lt;br /&gt;
== Login mit SSH Key ==&lt;br /&gt;
&lt;br /&gt;
Es besteht die Möglichkeit, einen public SSH Key in den Benutzer hochzuladen. Dann kann die Anmeldung über den privaten Key erfolgen. Siehe auch zur Erstellung des Key Paares: [https://www.heise.de/tipps-tricks/SSH-Key-erstellen-so-geht-s-4400280.html]&lt;br /&gt;
&lt;br /&gt;
Der public SSH Key muss dann hier gespeichert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/.ssh&lt;br /&gt;
nano .ssh/authorized_keys&lt;br /&gt;
# hier den public Key einfügen, und speichern&lt;br /&gt;
chmod 600 .ssh/authorized_keys&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Manchmal schlägt bei Power-Usern die Anmeldung fehl, wenn zu viele SSH Keys zur Verfügung stehen, und die alle durchprobiert werden. Dann kommt nach einer gewissen Anzahl die Fehlermeldung: zu viele Anmeldungsversuche.&lt;br /&gt;
&lt;br /&gt;
Die Lösung: beim SSH Aufruf muss der richtige private Key referenziert werden, und die anderen Keys ignoriert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -p 22 -i /root/.ssh/id_ed25519 -o IdentitiesOnly=yes xyz00@xyz00.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zusätzliche Möglichkeiten ==&lt;br /&gt;
&lt;br /&gt;
=== Bestimmte Shell Kommandos automatisch ausführen ===&lt;br /&gt;
&lt;br /&gt;
Lege in dem Verzeichnis, in dem Du direkt nach dem Login landest, mit dem Editor Deiner Wahl die Datei .bash_profile mit folgendem Inhalt an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line&amp;gt;&lt;br /&gt;
# Get the aliases and functions&lt;br /&gt;
if [ -f ~/.bashrc ]; then&lt;br /&gt;
. ~/.bashrc&lt;br /&gt;
fi&lt;br /&gt;
# User specific environment and startup programs&lt;br /&gt;
PATH=$PATH:$HOME/bin&lt;br /&gt;
BASH_ENV=$HOME/.bashrc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und nun kannst du in der Datei .bashrc shell Kommandos eingeben. z.B.: quota -g&lt;br /&gt;
&lt;br /&gt;
=== Editor in der Shell einstellen ===&lt;br /&gt;
&lt;br /&gt;
1. manuell Einloggen und:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
VISUAL=nano&lt;br /&gt;
export VISUAL&lt;br /&gt;
EDITOR=nano&lt;br /&gt;
export EDITOR&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. in der bash geht es auch kürzer:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
export EDITOR=nano&lt;br /&gt;
export VISUAL=nano&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. automatisch bei jedem Login&lt;br /&gt;
Mit obigen Kommandos in der ~/.bash_profile-Datei.&lt;br /&gt;
&lt;br /&gt;
=== Als Paketadmin in einen Unterbenutzer wechseln ===&lt;br /&gt;
&lt;br /&gt;
Wenn du als Paketadmin xyz00 per SSH angemeldet bist, kannst du ohne Passwort in den Unterbenutzer xyz00-webseite wechseln:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -iu xyz00-webseite&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei Unix-Benutzern, die z.B. nur für Postfächer genutzt werden, ist als Shell nur passwd eingerichtet. Daher musst du bei sudo die gewünsche Shell angeben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -u xyz00-mail_klaus -s bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weiterführende Links==&lt;br /&gt;
&lt;br /&gt;
[[HS-Server:SSH-Hostkeys]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Einstieg bei Hostsharing]]&lt;br /&gt;
[[Kategorie:Glossar]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=WKD_einrichten&amp;diff=7634</id>
		<title>WKD einrichten</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=WKD_einrichten&amp;diff=7634"/>
		<updated>2026-09-02T06:54:11Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
Ein Web Key Verzeichnis (Web Key Directory, WKD) ermöglicht es auf eine einfache Weise, den aktuell gültigen öffentlichen Schlüssel (Public Key) für eine bestimmte E-Mail Adresse über HTTPS bereitzustellen und abzurufen.&lt;br /&gt;
&lt;br /&gt;
Es gibt die Möglichkeit, das WKD im Advanced- oder Direct-Methode einzurichten. Im Direct-Mode wird der Pfad .well-known direkt auf der Domain erwartet, im Advanced-Mode wird mit einer Subdomain openpgpkey gearbeitet. Da die Trennung von der Hauptanwendung der Domain im Advanced-Mode einfacher ist, und weil die Clients auch erst über den Advanced-Mode versuchen, die Schlüssel herunterzuladen, beschränken wir uns in dieser Anleitung auf den Advanced Mode.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen ==&lt;br /&gt;
&lt;br /&gt;
Es wird vorausgesetzt, dass bereits ein Schlüsselpaar (private/public) erzeugt wurde (z.B. mit &amp;lt;code&amp;gt;gpg --full-generate-key&amp;lt;/code&amp;gt;, oder mit Thunderbird, siehe unten in den Links).&lt;br /&gt;
&lt;br /&gt;
Es muss eine Domain openpgpkey.&amp;lt;MeineDomain&amp;gt;.de im HSAdmin angelegt werden.&lt;br /&gt;
&lt;br /&gt;
Der öffentliche Schlüssel muss in einer Textdatei im Domainbenutzer gespeichert sein. Diese Datei wird als Parameter für das Skript angeben.&lt;br /&gt;
&lt;br /&gt;
== Skript zur Einrichtung ==&lt;br /&gt;
&lt;br /&gt;
Dieses Skript &amp;lt;code&amp;gt;update_pgp_wkd.sh&amp;lt;/code&amp;gt; (Link zum Gist siehe unten) erledigt alles, was man braucht:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
if [ -z $1 ]&lt;br /&gt;
then&lt;br /&gt;
    echo &amp;quot;Bitte den Pfad für die Datei mit dem öffentlichen Key mitgeben: z.B. $0 ~/public.txt&amp;quot;&lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
publickeyfile=$(realpath $1)&lt;br /&gt;
&lt;br /&gt;
if [ ! -f $publickeyfile ]&lt;br /&gt;
then&lt;br /&gt;
    echo &amp;quot;Kann den öffentlichen Schlüssel nicht finden: $publickeyfile&amp;quot;&lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
DOMAIN=$(find ~/doms/openpgpkey.*/htdocs-ssl | head -n 1 | awk -F/ &#039;{ print $8 }&#039; | sed -e &#039;s/openpgpkey.//g&#039;)&lt;br /&gt;
&lt;br /&gt;
if [ -z $DOMAIN ]&lt;br /&gt;
then&lt;br /&gt;
    echo &amp;quot;Zuerst muss die subdomain openpgpkey.$DOMAIN im HSAdmin eingerichtet werden!&amp;quot;&lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
cd ~/doms/openpgpkey.$DOMAIN&lt;br /&gt;
cat &amp;gt; .htaccess  &amp;lt;&amp;lt;FINISH&lt;br /&gt;
ForceType application/octet-stream;&lt;br /&gt;
&amp;lt;IfModule mod_headers.c&amp;gt;&lt;br /&gt;
   Header set Access-Control-Allow-Origin &amp;quot;*&amp;quot;&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
FINISH&lt;br /&gt;
cd ~/doms/openpgpkey.$DOMAIN/htdocs-ssl/&lt;br /&gt;
rm -f .htaccess&lt;br /&gt;
mkdir -p .well-known/openpgpkey&lt;br /&gt;
cd .well-known&lt;br /&gt;
gpg --import &amp;lt; $publickeyfile&lt;br /&gt;
gpg --list-options show-only-fpr-mbox  -k &amp;quot;@$DOMAIN&amp;quot; | /usr/lib/gnupg/gpg-wks-client --install-key&lt;br /&gt;
touch openpgpkey/$DOMAIN/policy&lt;br /&gt;
chmod a+x openpgpkey/$DOMAIN/&lt;br /&gt;
chmod a+x openpgpkey/$DOMAIN/hu/&lt;br /&gt;
touch openpgpkey/$DOMAIN/hu/index.html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einrichtung bei Hostsharing ==&lt;br /&gt;
&lt;br /&gt;
Man ruft das Skript mit dem Pfad zur Datei mit dem öffentlichen Schlüssel als Parameter auf. Es wird die erste Domain gesucht, die mit &amp;quot;openpgpkey.&amp;quot; beginnt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
./update_pgp_wkd.sh ~/public.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man das Ergebnis mit dem Dienst auf metacode.biz testen, siehe Link unten.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [https://wiki.gnupg.org/WKD Offizielle Webseite]&lt;br /&gt;
* [https://wiki.gnupg.org/WKDHosting Offizielle Anleitung]&lt;br /&gt;
* [https://www.kuketz-blog.de/gnupg-web-key-directory-wkd-einrichten/ Kuketz Blog: GnuPG: Web Key Directory (WKD) einrichten]&lt;br /&gt;
* [https://www.heise.de/tipps-tricks/Thunderbird-PGP-Verschluesselung-fuer-E-Mails-einrichten-4561551.html Thunderbird: PGP-Verschlüsselung für E-Mails einrichten]&lt;br /&gt;
* [https://gist.github.com/tpokorra/84aef5f97981535b871fe9e4719e940d Gist: update_pgp_wkd.sh]&lt;br /&gt;
* Testen der eigenen Einrichtung: https://wkd.dp42.dev/ oder https://www.webkeydirectory.com/&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7633</id>
		<title>Wordpress</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7633"/>
		<updated>2026-08-30T20:58:34Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Umgang mit einem gehackten Wordpress */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Wordpress in 5 Minuten =&lt;br /&gt;
&lt;br /&gt;
Installiert wird Wordpress hier unter der Domain https://blog.example.org.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;blog.example.org&#039;&#039;&lt;br /&gt;
* MySQL-User &lt;br /&gt;
* MySQL Datenbank&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-blog&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Wordpress Blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;blog.example.org&#039;,user:&#039;xyz00-blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqluser.add({set:{name:&#039;xyz00_wpuser&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqldb.add({set:{name:&#039;xyz00_wpdb&#039;,owner:&#039;xyz00_wpuser&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wordpress installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-blog&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
  ssh -l xyz00-blog xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs-ssl&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/blog.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www&lt;br /&gt;
cd htdocs-ssl&lt;br /&gt;
rm .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wordpress downloaden &amp;amp; entpacken z.b. im htdocs-ssl Verzeichnis&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
wget -O - https://wordpress.org/latest.tar.gz |tar -xz --strip 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wordpress konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://blog.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
= Verschiedene Hinweise und Anleitungen =&lt;br /&gt;
== wp-cli installieren ==&lt;br /&gt;
&lt;br /&gt;
wp-cli ist das Kommandozeilen-Werkzeug für WordPress: https://wp-cli.org/de/&lt;br /&gt;
&lt;br /&gt;
Es kann so installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/bin&lt;br /&gt;
cd ~/bin&lt;br /&gt;
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar&lt;br /&gt;
chmod a+x wp-cli.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uraltes Wordpress aktualisieren ==&lt;br /&gt;
&lt;br /&gt;
Manche Wordpress Installationen sind so alt, dass wp-login nicht mehr funktioniert.&lt;br /&gt;
&lt;br /&gt;
Mit wp-cli kann Wordpress auf die aktuelle Version aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress # oder ~/doms/meinedomain.de/subs-ssl/www/ oder wo sonst Wordpress installiert ist&lt;br /&gt;
~/bin/wp-cli.phar core update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls nur eine Minor Version installiert werden soll:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core update --minor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update der Plugins und Themes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar plugin update --all&lt;br /&gt;
~/bin/wp-cli.phar theme update --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Umgang mit einem gehackten Wordpress ==&lt;br /&gt;
&lt;br /&gt;
Falls die Wordpress Instanz gehackt wurde, gibt es 2 Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
* Es kann die Webseite inkl. Dateien und Datenbank auf den Stand aus dem Backup vor dem Angriff zurückgesetzt werden, und muss dann umgehend aktualisiert werden. Bei diesem Vorgehen gehen die seitdem erfassten Beiträge verloren. Leider liegt der Zeitpunkt des Angriffs manchmal schon länger zurück.&lt;br /&gt;
* Ansonsten müssen die veränderten Dateien identifiziert und gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Das Identifizieren der veränderten Dateien kann mit folgenden Mitteln geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core verify-checksums --include-root --exclude=liesmich.html,readme.html&lt;br /&gt;
~/bin/wp-cli.phar plugin --skip-themes --skip-plugins verify-checksums --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in der wp-config.php sollte keine verdächtige Datei eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep include wp-config.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuletzt geänderte Dateien finden, im Beispiel der letzten 3 Tage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find -ctime -3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zeige Dateien, die schreibgeschützt sind:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find . -type f ! -perm -u=w&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lösche alle .htaccess Dateien mit einer speziellen md5sum:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
md5sum=025ee8275afa054097fc53508448f76a&lt;br /&gt;
find . -type f -name &amp;quot;.htaccess&amp;quot; -exec sh -c &#039;for f; do md5sum &amp;quot;$f&amp;quot; | grep -q &amp;quot;$md5sum&amp;quot; &amp;amp;&amp;amp; ls -la &amp;quot;$f&amp;quot;; done&#039; _ {} +&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Prüfe auch die Dateien im doms Verzeichnis (dort sollten keine php Dateien liegen, z.B. accesson.php oder so):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find ~/doms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien im uploads und cache Verzeichnis finden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find wp-content/uploads wp-content/cache -type f \&lt;br /&gt;
  \( -name &#039;*.php&#039; -o -name &#039;*.phtml&#039; -o -name &#039;*.phar&#039; -o -name &#039;*.ico&#039; \) -ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die Schadcode speziell kodiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -rl &amp;quot;eval(base64_decode\|eval(gzinflate\|eval(str_rot13\|eval(htmlspecialchars_decode&amp;quot; . --include=&amp;quot;*.php&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die versuchen, einen Benutzer mit administrator Rechten anzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -r &#039;\\&amp;quot;administrator\\&amp;quot;&#039; wp-content/languages/plugins/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datenbank sollten die Benutzer mit administrator Rechten kontrolliert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT m.meta_key, m.meta_value, u.id, u.user_login, u.user_email, u.display_name&lt;br /&gt;
FROM wp_usermeta AS m join wp_users AS u ON m.user_id = u.id&lt;br /&gt;
WHERE m.meta_key = &#039;wp_capabilities&#039; AND meta_value LIKE &#039;%administrator%&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Passwörter der Administratoren müssen zurückgesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
~/bin/wp-cli.phar user reset-password --show-password --skip-email meinadmin&lt;br /&gt;
~/bin/wp-cli.phar user reset-password irgendeinadmin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Authentication Unique Keys and Salts in der wp-config.php sollten zurückgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
== Einen Admin Benutzer hinzufügen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du die Pflege einer WordPress Instanz übernehmen sollst, aber noch keinen Admin Benutzer hast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/bin/wp-cli.phar user create meinuser admin@example.org --role=administrator&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend kann der Benutzer auch wieder gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar user delete meinuser&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neue Domain umziehen ==&lt;br /&gt;
Meistens muss nichts weiter geändert werden als die Home und die SITE_URL Option. &lt;br /&gt;
&lt;br /&gt;
Einfach zu ändern geht das indem man sich via phpmyadmin.hostsharing.net in den Datenbank User des Wordpress einloggt und sich die Tabelle wp_options ansieht. Dort müssen die Zeilen mit `siteurl` und `home` an die neuen URLs angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man das auch über das wp-config.php machen. Meistens gibt es die beiden Einträge noch nicht, einfach an die passende Stelle für die Custom Config neu eintragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
define(&#039;WP_HOME&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
define(&#039;WP_SITEURL&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle mal noch auf alte Domain Einträge zu untersuchen und ggf zu ersetzen. &lt;br /&gt;
Das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%https://old-domain.de%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neuen User / Server umziehen / Uploads auf Storage auslagern == &lt;br /&gt;
&lt;br /&gt;
Meistens muss dafür keine weitere Änderung vorgenommen werden. Manchmal haben vorherige Anbieter einen alternativen Upload Pfad gesetzt. Das zeigt sich dadurch das man angeblich keine Schreibberechtigungen hätte beim Hochladen von z.B. Bildern. &lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit was dort kaputt sein könnte ist, das die Option `upload_path` noch auf einen alten Pfad vom alten Anbieter gesetzt wurde. Diese Option ist auch zu gebrauchen wenn der häufiger doch mal recht schnell wachsende Uploads Ordner auf den Storage und nicht auf die SSD ausgelagert werden soll. &lt;br /&gt;
&lt;br /&gt;
In der wp_options DB-Tabelle muss entsprechend die Variable `upload_path` angepasst werden. z.B. für den User xyz00-wordpress zu /home/storage/xyz00/users/wordpress/uploads&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle noch mal auf den Alten Pfad zu untersuchen und ggf. anzupassen, das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%/old/path/%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Du solltest einen persistenten Objekt-Cache verwenden&amp;quot;, sollte [[Redis#Redis_installieren|Redis installiert]] werden. Es reicht, wenn Redis auf einem Unix-Socket läuft, es muss nicht auf einem Port laufen.&lt;br /&gt;
&lt;br /&gt;
In der wp-config.php sollte dann (relativ weit oben) eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;WP_REDIS_SCHEME&#039;, &#039;unix&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PATH&#039;, &#039;/home/pacs/xyz00/users/service/redis/var/redis-server.sock&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PASSWORD&#039;, &#039;topsecret&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann z.B. das Plugin &amp;quot;Redis Object Cache&amp;quot; von Till Küss installiert werden: https://de.wordpress.org/plugins/redis-cache/&lt;br /&gt;
&lt;br /&gt;
Danach lässt sich der Object Cache unter &amp;quot;Einstellungen / Redis&amp;quot; aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Seiten Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Seiten-Cache wurde nicht erkannt, ...&amp;quot;, kann das Plugin WP Super Cache von Automattic installiert werden: https://wordpress.org/plugins/wp-super-cache/&lt;br /&gt;
&lt;br /&gt;
Der Cache muss dann in den Einstellungen des Plugins aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
*[https://wordpress.org/ Offizielle Webseite von Wordpress]&lt;br /&gt;
*[https://wp-cli.org/de/ WP-CLI ist das Kommandozeilen-Werkzeug für WordPress]&lt;br /&gt;
*[https://github.com/tpokorra/Hostsharing-Ansible-Wordpress Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Blog]]&lt;br /&gt;
[[Kategorie:CMS]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7632</id>
		<title>Wordpress</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7632"/>
		<updated>2026-08-30T20:23:44Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Umgang mit einem gehackten Wordpress */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Wordpress in 5 Minuten =&lt;br /&gt;
&lt;br /&gt;
Installiert wird Wordpress hier unter der Domain https://blog.example.org.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;blog.example.org&#039;&#039;&lt;br /&gt;
* MySQL-User &lt;br /&gt;
* MySQL Datenbank&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-blog&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Wordpress Blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;blog.example.org&#039;,user:&#039;xyz00-blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqluser.add({set:{name:&#039;xyz00_wpuser&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqldb.add({set:{name:&#039;xyz00_wpdb&#039;,owner:&#039;xyz00_wpuser&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wordpress installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-blog&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
  ssh -l xyz00-blog xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs-ssl&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/blog.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www&lt;br /&gt;
cd htdocs-ssl&lt;br /&gt;
rm .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wordpress downloaden &amp;amp; entpacken z.b. im htdocs-ssl Verzeichnis&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
wget -O - https://wordpress.org/latest.tar.gz |tar -xz --strip 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wordpress konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://blog.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
= Verschiedene Hinweise und Anleitungen =&lt;br /&gt;
== wp-cli installieren ==&lt;br /&gt;
&lt;br /&gt;
wp-cli ist das Kommandozeilen-Werkzeug für WordPress: https://wp-cli.org/de/&lt;br /&gt;
&lt;br /&gt;
Es kann so installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/bin&lt;br /&gt;
cd ~/bin&lt;br /&gt;
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar&lt;br /&gt;
chmod a+x wp-cli.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uraltes Wordpress aktualisieren ==&lt;br /&gt;
&lt;br /&gt;
Manche Wordpress Installationen sind so alt, dass wp-login nicht mehr funktioniert.&lt;br /&gt;
&lt;br /&gt;
Mit wp-cli kann Wordpress auf die aktuelle Version aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress # oder ~/doms/meinedomain.de/subs-ssl/www/ oder wo sonst Wordpress installiert ist&lt;br /&gt;
~/bin/wp-cli.phar core update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls nur eine Minor Version installiert werden soll:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core update --minor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update der Plugins und Themes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar plugin update --all&lt;br /&gt;
~/bin/wp-cli.phar theme update --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Umgang mit einem gehackten Wordpress ==&lt;br /&gt;
&lt;br /&gt;
Falls die Wordpress Instanz gehackt wurde, gibt es 2 Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
* Es kann die Webseite inkl. Dateien und Datenbank auf den Stand aus dem Backup vor dem Angriff zurückgesetzt werden, und muss dann umgehend aktualisiert werden. Bei diesem Vorgehen gehen die seitdem erfassten Beiträge verloren. Leider liegt der Zeitpunkt des Angriffs manchmal schon länger zurück.&lt;br /&gt;
* Ansonsten müssen die veränderten Dateien identifiziert und gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Das Identifizieren der veränderten Dateien kann mit folgenden Mitteln geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core verify-checksums --include-root --exclude=liesmich.html,readme.html&lt;br /&gt;
~/bin/wp-cli.phar plugin --skip-themes --skip-plugins verify-checksums --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in der wp-config.php sollte keine verdächtige Datei eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep include wp-config.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuletzt geänderte Dateien finden, im Beispiel der letzten 3 Tage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find -ctime -3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zeige Dateien, die schreibgeschützt sind:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find . -type f ! -perm -u=w&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lösche alle .htaccess Dateien mit einer speziellen md5sum:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
md5sum=025ee8275afa054097fc53508448f76a&lt;br /&gt;
find . -type f -name &amp;quot;.htaccess&amp;quot; -exec sh -c &#039;for f; do md5sum &amp;quot;$f&amp;quot; | grep -q &amp;quot;$md5sum&amp;quot; &amp;amp;&amp;amp; ls -la &amp;quot;$f&amp;quot;; done&#039; _ {} +&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Prüfe auch die Dateien im doms Verzeichnis (dort sollten keine php Dateien liegen, z.B. accesson.php oder so):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find ~/doms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien im uploads und cache Verzeichnis finden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find wp-content/uploads wp-content/cache -type f \&lt;br /&gt;
  \( -name &#039;*.php&#039; -o -name &#039;*.phtml&#039; -o -name &#039;*.phar&#039; -o -name &#039;*.ico&#039; \) -ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die Schadcode speziell kodiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -rl &amp;quot;eval(base64_decode\|eval(gzinflate\|eval(str_rot13\|eval(htmlspecialchars_decode&amp;quot; . --include=&amp;quot;*.php&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die versuchen, einen Benutzer mit administrator Rechten anzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -r &#039;\\&amp;quot;administrator\\&amp;quot;&#039; wp-content/languages/plugins/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datenbank sollten die Benutzer mit administrator Rechten kontrolliert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT m.meta_key, m.meta_value, u.id, u.user_login, u.user_email, u.display_name&lt;br /&gt;
FROM wp_usermeta AS m join wp_users AS u ON m.user_id = u.id&lt;br /&gt;
WHERE m.meta_key = &#039;wp_capabilities&#039; AND meta_value LIKE &#039;%administrator%&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Passwörter der Administratoren sollten zurückgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Die Authentication Unique Keys and Salts in der wp-config.php sollten zurückgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
== Einen Admin Benutzer hinzufügen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du die Pflege einer WordPress Instanz übernehmen sollst, aber noch keinen Admin Benutzer hast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/bin/wp-cli.phar user create meinuser admin@example.org --role=administrator&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend kann der Benutzer auch wieder gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar user delete meinuser&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neue Domain umziehen ==&lt;br /&gt;
Meistens muss nichts weiter geändert werden als die Home und die SITE_URL Option. &lt;br /&gt;
&lt;br /&gt;
Einfach zu ändern geht das indem man sich via phpmyadmin.hostsharing.net in den Datenbank User des Wordpress einloggt und sich die Tabelle wp_options ansieht. Dort müssen die Zeilen mit `siteurl` und `home` an die neuen URLs angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man das auch über das wp-config.php machen. Meistens gibt es die beiden Einträge noch nicht, einfach an die passende Stelle für die Custom Config neu eintragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
define(&#039;WP_HOME&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
define(&#039;WP_SITEURL&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle mal noch auf alte Domain Einträge zu untersuchen und ggf zu ersetzen. &lt;br /&gt;
Das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%https://old-domain.de%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neuen User / Server umziehen / Uploads auf Storage auslagern == &lt;br /&gt;
&lt;br /&gt;
Meistens muss dafür keine weitere Änderung vorgenommen werden. Manchmal haben vorherige Anbieter einen alternativen Upload Pfad gesetzt. Das zeigt sich dadurch das man angeblich keine Schreibberechtigungen hätte beim Hochladen von z.B. Bildern. &lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit was dort kaputt sein könnte ist, das die Option `upload_path` noch auf einen alten Pfad vom alten Anbieter gesetzt wurde. Diese Option ist auch zu gebrauchen wenn der häufiger doch mal recht schnell wachsende Uploads Ordner auf den Storage und nicht auf die SSD ausgelagert werden soll. &lt;br /&gt;
&lt;br /&gt;
In der wp_options DB-Tabelle muss entsprechend die Variable `upload_path` angepasst werden. z.B. für den User xyz00-wordpress zu /home/storage/xyz00/users/wordpress/uploads&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle noch mal auf den Alten Pfad zu untersuchen und ggf. anzupassen, das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%/old/path/%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Du solltest einen persistenten Objekt-Cache verwenden&amp;quot;, sollte [[Redis#Redis_installieren|Redis installiert]] werden. Es reicht, wenn Redis auf einem Unix-Socket läuft, es muss nicht auf einem Port laufen.&lt;br /&gt;
&lt;br /&gt;
In der wp-config.php sollte dann (relativ weit oben) eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;WP_REDIS_SCHEME&#039;, &#039;unix&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PATH&#039;, &#039;/home/pacs/xyz00/users/service/redis/var/redis-server.sock&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PASSWORD&#039;, &#039;topsecret&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann z.B. das Plugin &amp;quot;Redis Object Cache&amp;quot; von Till Küss installiert werden: https://de.wordpress.org/plugins/redis-cache/&lt;br /&gt;
&lt;br /&gt;
Danach lässt sich der Object Cache unter &amp;quot;Einstellungen / Redis&amp;quot; aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Seiten Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Seiten-Cache wurde nicht erkannt, ...&amp;quot;, kann das Plugin WP Super Cache von Automattic installiert werden: https://wordpress.org/plugins/wp-super-cache/&lt;br /&gt;
&lt;br /&gt;
Der Cache muss dann in den Einstellungen des Plugins aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
*[https://wordpress.org/ Offizielle Webseite von Wordpress]&lt;br /&gt;
*[https://wp-cli.org/de/ WP-CLI ist das Kommandozeilen-Werkzeug für WordPress]&lt;br /&gt;
*[https://github.com/tpokorra/Hostsharing-Ansible-Wordpress Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Blog]]&lt;br /&gt;
[[Kategorie:CMS]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7631</id>
		<title>Wordpress</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7631"/>
		<updated>2026-08-30T20:21:56Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Umgang mit einem gehackten Wordpress */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Wordpress in 5 Minuten =&lt;br /&gt;
&lt;br /&gt;
Installiert wird Wordpress hier unter der Domain https://blog.example.org.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;blog.example.org&#039;&#039;&lt;br /&gt;
* MySQL-User &lt;br /&gt;
* MySQL Datenbank&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-blog&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Wordpress Blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;blog.example.org&#039;,user:&#039;xyz00-blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqluser.add({set:{name:&#039;xyz00_wpuser&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqldb.add({set:{name:&#039;xyz00_wpdb&#039;,owner:&#039;xyz00_wpuser&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wordpress installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-blog&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
  ssh -l xyz00-blog xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs-ssl&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/blog.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www&lt;br /&gt;
cd htdocs-ssl&lt;br /&gt;
rm .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wordpress downloaden &amp;amp; entpacken z.b. im htdocs-ssl Verzeichnis&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
wget -O - https://wordpress.org/latest.tar.gz |tar -xz --strip 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wordpress konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://blog.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
= Verschiedene Hinweise und Anleitungen =&lt;br /&gt;
== wp-cli installieren ==&lt;br /&gt;
&lt;br /&gt;
wp-cli ist das Kommandozeilen-Werkzeug für WordPress: https://wp-cli.org/de/&lt;br /&gt;
&lt;br /&gt;
Es kann so installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/bin&lt;br /&gt;
cd ~/bin&lt;br /&gt;
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar&lt;br /&gt;
chmod a+x wp-cli.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uraltes Wordpress aktualisieren ==&lt;br /&gt;
&lt;br /&gt;
Manche Wordpress Installationen sind so alt, dass wp-login nicht mehr funktioniert.&lt;br /&gt;
&lt;br /&gt;
Mit wp-cli kann Wordpress auf die aktuelle Version aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress # oder ~/doms/meinedomain.de/subs-ssl/www/ oder wo sonst Wordpress installiert ist&lt;br /&gt;
~/bin/wp-cli.phar core update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls nur eine Minor Version installiert werden soll:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core update --minor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update der Plugins und Themes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar plugin update --all&lt;br /&gt;
~/bin/wp-cli.phar theme update --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Umgang mit einem gehackten Wordpress ==&lt;br /&gt;
&lt;br /&gt;
Falls die Wordpress Instanz gehackt wurde, gibt es 2 Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
* Es kann die Webseite inkl. Dateien und Datenbank auf den Stand aus dem Backup vor dem Angriff zurückgesetzt werden, und muss dann umgehend aktualisiert werden. Bei diesem Vorgehen gehen die seitdem erfassten Beiträge verloren. Leider liegt der Zeitpunkt des Angriffs manchmal schon länger zurück.&lt;br /&gt;
* Ansonsten müssen die veränderten Dateien identifiziert und gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Das Identifizieren der veränderten Dateien kann mit folgenden Mitteln geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core verify-checksums --include-root --exclude=liesmich.html,readme.html&lt;br /&gt;
~/bin/wp-cli.phar plugin --skip-themes --skip-plugins verify-checksums --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in der wp-config.php sollte keine verdächtige Datei eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep include wp-config.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuletzt geänderte Dateien finden, im Beispiel der letzten 3 Tage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find -ctime -3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zeige Dateien, die schreibgeschützt sind:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find . -type f ! -perm -u=w&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lösche alle .htaccess Dateien mit einer speziellen md5sum:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
md5sum=025ee8275afa054097fc53508448f76a&lt;br /&gt;
find . -type f -name &amp;quot;.htaccess&amp;quot; -exec sh -c &#039;for f; do md5sum &amp;quot;$f&amp;quot; | grep -q &amp;quot;$md5sum&amp;quot; &amp;amp;&amp;amp; ls -la &amp;quot;$f&amp;quot;; done&#039; _ {} +&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Prüfe auch die Dateien im doms Verzeichnis (dort sollten keine php Dateien liegen, z.B. accesson.php oder so):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find ~/doms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien im uploads und cache Verzeichnis finden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find wp-content/uploads wp-content/cache -type f \&lt;br /&gt;
  \( -name &#039;*.php&#039; -o -name &#039;*.phtml&#039; -o -name &#039;*.phar&#039; -o -name &#039;*.ico&#039; \) -ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die Schadcode speziell kodiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -rl &amp;quot;eval(base64_decode\|eval(gzinflate\|eval(str_rot13\|eval(htmlspecialchars_decode&amp;quot; . --include=&amp;quot;*.php&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die versuchen, einen Benutzer mit administrator Rechten anzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -r &#039;\\&amp;quot;administrator\\&amp;quot;&#039; wp-content/languages/plugins/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datenbank sollten die Benutzer mit administrator Rechten kontrolliert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT m.meta_key, m.meta_value, u.id, u.user_login, u.user_email, u.display_name&lt;br /&gt;
FROM wp_usermeta AS m join wp_users AS u ON m.user_id = u.id&lt;br /&gt;
WHERE m.meta_key = &#039;wp_capabilities&#039; AND meta_value LIKE &#039;%administrator%&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einen Admin Benutzer hinzufügen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du die Pflege einer WordPress Instanz übernehmen sollst, aber noch keinen Admin Benutzer hast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/bin/wp-cli.phar user create meinuser admin@example.org --role=administrator&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend kann der Benutzer auch wieder gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar user delete meinuser&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neue Domain umziehen ==&lt;br /&gt;
Meistens muss nichts weiter geändert werden als die Home und die SITE_URL Option. &lt;br /&gt;
&lt;br /&gt;
Einfach zu ändern geht das indem man sich via phpmyadmin.hostsharing.net in den Datenbank User des Wordpress einloggt und sich die Tabelle wp_options ansieht. Dort müssen die Zeilen mit `siteurl` und `home` an die neuen URLs angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man das auch über das wp-config.php machen. Meistens gibt es die beiden Einträge noch nicht, einfach an die passende Stelle für die Custom Config neu eintragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
define(&#039;WP_HOME&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
define(&#039;WP_SITEURL&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle mal noch auf alte Domain Einträge zu untersuchen und ggf zu ersetzen. &lt;br /&gt;
Das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%https://old-domain.de%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neuen User / Server umziehen / Uploads auf Storage auslagern == &lt;br /&gt;
&lt;br /&gt;
Meistens muss dafür keine weitere Änderung vorgenommen werden. Manchmal haben vorherige Anbieter einen alternativen Upload Pfad gesetzt. Das zeigt sich dadurch das man angeblich keine Schreibberechtigungen hätte beim Hochladen von z.B. Bildern. &lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit was dort kaputt sein könnte ist, das die Option `upload_path` noch auf einen alten Pfad vom alten Anbieter gesetzt wurde. Diese Option ist auch zu gebrauchen wenn der häufiger doch mal recht schnell wachsende Uploads Ordner auf den Storage und nicht auf die SSD ausgelagert werden soll. &lt;br /&gt;
&lt;br /&gt;
In der wp_options DB-Tabelle muss entsprechend die Variable `upload_path` angepasst werden. z.B. für den User xyz00-wordpress zu /home/storage/xyz00/users/wordpress/uploads&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle noch mal auf den Alten Pfad zu untersuchen und ggf. anzupassen, das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%/old/path/%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Du solltest einen persistenten Objekt-Cache verwenden&amp;quot;, sollte [[Redis#Redis_installieren|Redis installiert]] werden. Es reicht, wenn Redis auf einem Unix-Socket läuft, es muss nicht auf einem Port laufen.&lt;br /&gt;
&lt;br /&gt;
In der wp-config.php sollte dann (relativ weit oben) eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;WP_REDIS_SCHEME&#039;, &#039;unix&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PATH&#039;, &#039;/home/pacs/xyz00/users/service/redis/var/redis-server.sock&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PASSWORD&#039;, &#039;topsecret&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann z.B. das Plugin &amp;quot;Redis Object Cache&amp;quot; von Till Küss installiert werden: https://de.wordpress.org/plugins/redis-cache/&lt;br /&gt;
&lt;br /&gt;
Danach lässt sich der Object Cache unter &amp;quot;Einstellungen / Redis&amp;quot; aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Seiten Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Seiten-Cache wurde nicht erkannt, ...&amp;quot;, kann das Plugin WP Super Cache von Automattic installiert werden: https://wordpress.org/plugins/wp-super-cache/&lt;br /&gt;
&lt;br /&gt;
Der Cache muss dann in den Einstellungen des Plugins aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
*[https://wordpress.org/ Offizielle Webseite von Wordpress]&lt;br /&gt;
*[https://wp-cli.org/de/ WP-CLI ist das Kommandozeilen-Werkzeug für WordPress]&lt;br /&gt;
*[https://github.com/tpokorra/Hostsharing-Ansible-Wordpress Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Blog]]&lt;br /&gt;
[[Kategorie:CMS]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7630</id>
		<title>Wordpress</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7630"/>
		<updated>2026-08-30T19:58:16Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Umgang mit einem gehackten Wordpress */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Wordpress in 5 Minuten =&lt;br /&gt;
&lt;br /&gt;
Installiert wird Wordpress hier unter der Domain https://blog.example.org.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;blog.example.org&#039;&#039;&lt;br /&gt;
* MySQL-User &lt;br /&gt;
* MySQL Datenbank&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-blog&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Wordpress Blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;blog.example.org&#039;,user:&#039;xyz00-blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqluser.add({set:{name:&#039;xyz00_wpuser&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqldb.add({set:{name:&#039;xyz00_wpdb&#039;,owner:&#039;xyz00_wpuser&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wordpress installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-blog&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
  ssh -l xyz00-blog xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs-ssl&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/blog.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www&lt;br /&gt;
cd htdocs-ssl&lt;br /&gt;
rm .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wordpress downloaden &amp;amp; entpacken z.b. im htdocs-ssl Verzeichnis&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
wget -O - https://wordpress.org/latest.tar.gz |tar -xz --strip 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wordpress konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://blog.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
= Verschiedene Hinweise und Anleitungen =&lt;br /&gt;
== wp-cli installieren ==&lt;br /&gt;
&lt;br /&gt;
wp-cli ist das Kommandozeilen-Werkzeug für WordPress: https://wp-cli.org/de/&lt;br /&gt;
&lt;br /&gt;
Es kann so installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/bin&lt;br /&gt;
cd ~/bin&lt;br /&gt;
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar&lt;br /&gt;
chmod a+x wp-cli.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uraltes Wordpress aktualisieren ==&lt;br /&gt;
&lt;br /&gt;
Manche Wordpress Installationen sind so alt, dass wp-login nicht mehr funktioniert.&lt;br /&gt;
&lt;br /&gt;
Mit wp-cli kann Wordpress auf die aktuelle Version aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress # oder ~/doms/meinedomain.de/subs-ssl/www/ oder wo sonst Wordpress installiert ist&lt;br /&gt;
~/bin/wp-cli.phar core update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls nur eine Minor Version installiert werden soll:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core update --minor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update der Plugins und Themes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar plugin update --all&lt;br /&gt;
~/bin/wp-cli.phar theme update --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Umgang mit einem gehackten Wordpress ==&lt;br /&gt;
&lt;br /&gt;
Falls die Wordpress Instanz gehackt wurde, gibt es 2 Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
* Es kann die Webseite inkl. Dateien und Datenbank auf den Stand aus dem Backup vor dem Angriff zurückgesetzt werden, und muss dann umgehend aktualisiert werden. Bei diesem Vorgehen gehen die seitdem erfassten Beiträge verloren. Leider liegt der Zeitpunkt des Angriffs manchmal schon länger zurück.&lt;br /&gt;
* Ansonsten müssen die veränderten Dateien identifiziert und gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Das Identifizieren der veränderten Dateien kann mit folgenden Mitteln geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core verify-checksums --include-root --exclude=liesmich.html,readme.html&lt;br /&gt;
~/bin/wp-cli.phar plugin --skip-themes --skip-plugins verify-checksums --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in der wp-config.php sollte keine verdächtige Datei eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep include wp-config.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuletzt geänderte Dateien finden, im Beispiel der letzten 3 Tage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find -ctime -3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zeige Dateien, die schreibgeschützt sind:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find . -type f ! -perm -u=w&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lösche alle .htaccess Dateien mit einer speziellen md5sum:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
md5sum=025ee8275afa054097fc53508448f76a&lt;br /&gt;
find . -type f -name &amp;quot;.htaccess&amp;quot; -exec sh -c &#039;for f; do md5sum &amp;quot;$f&amp;quot; | grep -q &amp;quot;$md5sum&amp;quot; &amp;amp;&amp;amp; ls -la &amp;quot;$f&amp;quot;; done&#039; _ {} +&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien im uploads und cache Verzeichnis finden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find wp-content/uploads wp-content/cache -type f \&lt;br /&gt;
  \( -name &#039;*.php&#039; -o -name &#039;*.phtml&#039; -o -name &#039;*.phar&#039; -o -name &#039;*.ico&#039; \) -ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die Schadcode speziell kodiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -rl &amp;quot;eval(base64_decode\|eval(gzinflate\|eval(str_rot13\|eval(htmlspecialchars_decode&amp;quot; . --include=&amp;quot;*.php&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die versuchen, einen Benutzer mit administrator Rechten anzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -r &#039;\\&amp;quot;administrator\\&amp;quot;&#039; wp-content/languages/plugins/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datenbank sollten die Benutzer mit administrator Rechten kontrolliert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT m.meta_key, m.meta_value, u.id, u.user_login, u.user_email, u.display_name&lt;br /&gt;
FROM wp_usermeta AS m join wp_users AS u ON m.user_id = u.id&lt;br /&gt;
WHERE m.meta_key = &#039;wp_capabilities&#039; AND meta_value LIKE &#039;%administrator%&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einen Admin Benutzer hinzufügen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du die Pflege einer WordPress Instanz übernehmen sollst, aber noch keinen Admin Benutzer hast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/bin/wp-cli.phar user create meinuser admin@example.org --role=administrator&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend kann der Benutzer auch wieder gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar user delete meinuser&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neue Domain umziehen ==&lt;br /&gt;
Meistens muss nichts weiter geändert werden als die Home und die SITE_URL Option. &lt;br /&gt;
&lt;br /&gt;
Einfach zu ändern geht das indem man sich via phpmyadmin.hostsharing.net in den Datenbank User des Wordpress einloggt und sich die Tabelle wp_options ansieht. Dort müssen die Zeilen mit `siteurl` und `home` an die neuen URLs angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man das auch über das wp-config.php machen. Meistens gibt es die beiden Einträge noch nicht, einfach an die passende Stelle für die Custom Config neu eintragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
define(&#039;WP_HOME&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
define(&#039;WP_SITEURL&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle mal noch auf alte Domain Einträge zu untersuchen und ggf zu ersetzen. &lt;br /&gt;
Das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%https://old-domain.de%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neuen User / Server umziehen / Uploads auf Storage auslagern == &lt;br /&gt;
&lt;br /&gt;
Meistens muss dafür keine weitere Änderung vorgenommen werden. Manchmal haben vorherige Anbieter einen alternativen Upload Pfad gesetzt. Das zeigt sich dadurch das man angeblich keine Schreibberechtigungen hätte beim Hochladen von z.B. Bildern. &lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit was dort kaputt sein könnte ist, das die Option `upload_path` noch auf einen alten Pfad vom alten Anbieter gesetzt wurde. Diese Option ist auch zu gebrauchen wenn der häufiger doch mal recht schnell wachsende Uploads Ordner auf den Storage und nicht auf die SSD ausgelagert werden soll. &lt;br /&gt;
&lt;br /&gt;
In der wp_options DB-Tabelle muss entsprechend die Variable `upload_path` angepasst werden. z.B. für den User xyz00-wordpress zu /home/storage/xyz00/users/wordpress/uploads&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle noch mal auf den Alten Pfad zu untersuchen und ggf. anzupassen, das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%/old/path/%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Du solltest einen persistenten Objekt-Cache verwenden&amp;quot;, sollte [[Redis#Redis_installieren|Redis installiert]] werden. Es reicht, wenn Redis auf einem Unix-Socket läuft, es muss nicht auf einem Port laufen.&lt;br /&gt;
&lt;br /&gt;
In der wp-config.php sollte dann (relativ weit oben) eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;WP_REDIS_SCHEME&#039;, &#039;unix&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PATH&#039;, &#039;/home/pacs/xyz00/users/service/redis/var/redis-server.sock&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PASSWORD&#039;, &#039;topsecret&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann z.B. das Plugin &amp;quot;Redis Object Cache&amp;quot; von Till Küss installiert werden: https://de.wordpress.org/plugins/redis-cache/&lt;br /&gt;
&lt;br /&gt;
Danach lässt sich der Object Cache unter &amp;quot;Einstellungen / Redis&amp;quot; aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Seiten Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Seiten-Cache wurde nicht erkannt, ...&amp;quot;, kann das Plugin WP Super Cache von Automattic installiert werden: https://wordpress.org/plugins/wp-super-cache/&lt;br /&gt;
&lt;br /&gt;
Der Cache muss dann in den Einstellungen des Plugins aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
*[https://wordpress.org/ Offizielle Webseite von Wordpress]&lt;br /&gt;
*[https://wp-cli.org/de/ WP-CLI ist das Kommandozeilen-Werkzeug für WordPress]&lt;br /&gt;
*[https://github.com/tpokorra/Hostsharing-Ansible-Wordpress Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Blog]]&lt;br /&gt;
[[Kategorie:CMS]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7629</id>
		<title>Wordpress</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7629"/>
		<updated>2026-08-30T19:42:54Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Umgang mit einem gehackten Wordpress */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Wordpress in 5 Minuten =&lt;br /&gt;
&lt;br /&gt;
Installiert wird Wordpress hier unter der Domain https://blog.example.org.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;blog.example.org&#039;&#039;&lt;br /&gt;
* MySQL-User &lt;br /&gt;
* MySQL Datenbank&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-blog&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Wordpress Blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;blog.example.org&#039;,user:&#039;xyz00-blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqluser.add({set:{name:&#039;xyz00_wpuser&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqldb.add({set:{name:&#039;xyz00_wpdb&#039;,owner:&#039;xyz00_wpuser&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wordpress installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-blog&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
  ssh -l xyz00-blog xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs-ssl&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/blog.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www&lt;br /&gt;
cd htdocs-ssl&lt;br /&gt;
rm .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wordpress downloaden &amp;amp; entpacken z.b. im htdocs-ssl Verzeichnis&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
wget -O - https://wordpress.org/latest.tar.gz |tar -xz --strip 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wordpress konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://blog.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
= Verschiedene Hinweise und Anleitungen =&lt;br /&gt;
== wp-cli installieren ==&lt;br /&gt;
&lt;br /&gt;
wp-cli ist das Kommandozeilen-Werkzeug für WordPress: https://wp-cli.org/de/&lt;br /&gt;
&lt;br /&gt;
Es kann so installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/bin&lt;br /&gt;
cd ~/bin&lt;br /&gt;
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar&lt;br /&gt;
chmod a+x wp-cli.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uraltes Wordpress aktualisieren ==&lt;br /&gt;
&lt;br /&gt;
Manche Wordpress Installationen sind so alt, dass wp-login nicht mehr funktioniert.&lt;br /&gt;
&lt;br /&gt;
Mit wp-cli kann Wordpress auf die aktuelle Version aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress # oder ~/doms/meinedomain.de/subs-ssl/www/ oder wo sonst Wordpress installiert ist&lt;br /&gt;
~/bin/wp-cli.phar core update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls nur eine Minor Version installiert werden soll:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core update --minor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update der Plugins und Themes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar plugin update --all&lt;br /&gt;
~/bin/wp-cli.phar theme update --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Umgang mit einem gehackten Wordpress ==&lt;br /&gt;
&lt;br /&gt;
Falls die Wordpress Instanz gehackt wurde, gibt es 2 Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
* Es kann die Webseite inkl. Dateien und Datenbank auf den Stand aus dem Backup vor dem Angriff zurückgesetzt werden, und muss dann umgehend aktualisiert werden. Bei diesem Vorgehen gehen die seitdem erfassten Beiträge verloren. Leider liegt der Zeitpunkt des Angriffs manchmal schon länger zurück.&lt;br /&gt;
* Ansonsten müssen die veränderten Dateien identifiziert und gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Das Identifizieren der veränderten Dateien kann mit folgenden Mitteln geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core verify-checksums --include-root --exclude=liesmich.html,readme.html&lt;br /&gt;
~/bin/wp-cli.phar plugin --skip-themes --skip-plugins verify-checksums --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in der wp-config.php sollte keine verdächtige Datei eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep include wp-config.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuletzt geänderte Dateien finden, im Beispiel der letzten 3 Tage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find -ctime -3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zeige Dateien, die schreibgeschützt sind:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find . -type f ! -perm -u=w&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lösche alle .htaccess Dateien mit einer speziellen md5sum:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
md5sum=025ee8275afa054097fc53508448f76a&lt;br /&gt;
find . -type f -name &amp;quot;.htaccess&amp;quot; -exec sh -c &#039;for f; do md5sum &amp;quot;$f&amp;quot; | grep -q &amp;quot;$md5sum&amp;quot; &amp;amp;&amp;amp; ls -la &amp;quot;$f&amp;quot;; done&#039; _ {} +&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien im uploads und cache Verzeichnis finden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find wp-content/uploads wp-content/cache -type f \&lt;br /&gt;
  \( -name &#039;*.php&#039; -o -name &#039;*.phtml&#039; -o -name &#039;*.phar&#039; -o -name &#039;*.ico&#039; \) -ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die Schadcode speziell kodiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -rl &amp;quot;eval(base64_decode\|eval(gzinflate\|eval(str_rot13\|eval(htmlspecialchars_decode&amp;quot; . --include=&amp;quot;*.php&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die versuchen, einen Benutzer mit administrator Rechten anzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -r &#039;\\&amp;quot;administrator\\&amp;quot;&#039; wp-content/languages/plugins/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datenbank sollten die Benutzer mit administrator Rechten kontrolliert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT m.meta_key, m.meta_value, u.id, u.user_login, u.user_email, u.display_name&lt;br /&gt;
FROM wp_usermeta AS m join wp_users AS u ON m.user_id = u.id&lt;br /&gt;
WHERE meta_value LIKE &#039;%administrator%&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einen Admin Benutzer hinzufügen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du die Pflege einer WordPress Instanz übernehmen sollst, aber noch keinen Admin Benutzer hast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/bin/wp-cli.phar user create meinuser admin@example.org --role=administrator&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend kann der Benutzer auch wieder gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar user delete meinuser&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neue Domain umziehen ==&lt;br /&gt;
Meistens muss nichts weiter geändert werden als die Home und die SITE_URL Option. &lt;br /&gt;
&lt;br /&gt;
Einfach zu ändern geht das indem man sich via phpmyadmin.hostsharing.net in den Datenbank User des Wordpress einloggt und sich die Tabelle wp_options ansieht. Dort müssen die Zeilen mit `siteurl` und `home` an die neuen URLs angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man das auch über das wp-config.php machen. Meistens gibt es die beiden Einträge noch nicht, einfach an die passende Stelle für die Custom Config neu eintragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
define(&#039;WP_HOME&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
define(&#039;WP_SITEURL&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle mal noch auf alte Domain Einträge zu untersuchen und ggf zu ersetzen. &lt;br /&gt;
Das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%https://old-domain.de%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neuen User / Server umziehen / Uploads auf Storage auslagern == &lt;br /&gt;
&lt;br /&gt;
Meistens muss dafür keine weitere Änderung vorgenommen werden. Manchmal haben vorherige Anbieter einen alternativen Upload Pfad gesetzt. Das zeigt sich dadurch das man angeblich keine Schreibberechtigungen hätte beim Hochladen von z.B. Bildern. &lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit was dort kaputt sein könnte ist, das die Option `upload_path` noch auf einen alten Pfad vom alten Anbieter gesetzt wurde. Diese Option ist auch zu gebrauchen wenn der häufiger doch mal recht schnell wachsende Uploads Ordner auf den Storage und nicht auf die SSD ausgelagert werden soll. &lt;br /&gt;
&lt;br /&gt;
In der wp_options DB-Tabelle muss entsprechend die Variable `upload_path` angepasst werden. z.B. für den User xyz00-wordpress zu /home/storage/xyz00/users/wordpress/uploads&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle noch mal auf den Alten Pfad zu untersuchen und ggf. anzupassen, das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%/old/path/%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Du solltest einen persistenten Objekt-Cache verwenden&amp;quot;, sollte [[Redis#Redis_installieren|Redis installiert]] werden. Es reicht, wenn Redis auf einem Unix-Socket läuft, es muss nicht auf einem Port laufen.&lt;br /&gt;
&lt;br /&gt;
In der wp-config.php sollte dann (relativ weit oben) eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;WP_REDIS_SCHEME&#039;, &#039;unix&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PATH&#039;, &#039;/home/pacs/xyz00/users/service/redis/var/redis-server.sock&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PASSWORD&#039;, &#039;topsecret&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann z.B. das Plugin &amp;quot;Redis Object Cache&amp;quot; von Till Küss installiert werden: https://de.wordpress.org/plugins/redis-cache/&lt;br /&gt;
&lt;br /&gt;
Danach lässt sich der Object Cache unter &amp;quot;Einstellungen / Redis&amp;quot; aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Seiten Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Seiten-Cache wurde nicht erkannt, ...&amp;quot;, kann das Plugin WP Super Cache von Automattic installiert werden: https://wordpress.org/plugins/wp-super-cache/&lt;br /&gt;
&lt;br /&gt;
Der Cache muss dann in den Einstellungen des Plugins aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
*[https://wordpress.org/ Offizielle Webseite von Wordpress]&lt;br /&gt;
*[https://wp-cli.org/de/ WP-CLI ist das Kommandozeilen-Werkzeug für WordPress]&lt;br /&gt;
*[https://github.com/tpokorra/Hostsharing-Ansible-Wordpress Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Blog]]&lt;br /&gt;
[[Kategorie:CMS]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7628</id>
		<title>Wordpress</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7628"/>
		<updated>2026-08-27T04:12:42Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Uraltes Wordpress aktualisieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Wordpress in 5 Minuten =&lt;br /&gt;
&lt;br /&gt;
Installiert wird Wordpress hier unter der Domain https://blog.example.org.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;blog.example.org&#039;&#039;&lt;br /&gt;
* MySQL-User &lt;br /&gt;
* MySQL Datenbank&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-blog&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Wordpress Blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;blog.example.org&#039;,user:&#039;xyz00-blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqluser.add({set:{name:&#039;xyz00_wpuser&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqldb.add({set:{name:&#039;xyz00_wpdb&#039;,owner:&#039;xyz00_wpuser&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wordpress installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-blog&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
  ssh -l xyz00-blog xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs-ssl&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/blog.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www&lt;br /&gt;
cd htdocs-ssl&lt;br /&gt;
rm .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wordpress downloaden &amp;amp; entpacken z.b. im htdocs-ssl Verzeichnis&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
wget -O - https://wordpress.org/latest.tar.gz |tar -xz --strip 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wordpress konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://blog.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
= Verschiedene Hinweise und Anleitungen =&lt;br /&gt;
== wp-cli installieren ==&lt;br /&gt;
&lt;br /&gt;
wp-cli ist das Kommandozeilen-Werkzeug für WordPress: https://wp-cli.org/de/&lt;br /&gt;
&lt;br /&gt;
Es kann so installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/bin&lt;br /&gt;
cd ~/bin&lt;br /&gt;
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar&lt;br /&gt;
chmod a+x wp-cli.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uraltes Wordpress aktualisieren ==&lt;br /&gt;
&lt;br /&gt;
Manche Wordpress Installationen sind so alt, dass wp-login nicht mehr funktioniert.&lt;br /&gt;
&lt;br /&gt;
Mit wp-cli kann Wordpress auf die aktuelle Version aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress # oder ~/doms/meinedomain.de/subs-ssl/www/ oder wo sonst Wordpress installiert ist&lt;br /&gt;
~/bin/wp-cli.phar core update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls nur eine Minor Version installiert werden soll:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core update --minor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update der Plugins und Themes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar plugin update --all&lt;br /&gt;
~/bin/wp-cli.phar theme update --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Umgang mit einem gehackten Wordpress ==&lt;br /&gt;
&lt;br /&gt;
Falls die Wordpress Instanz gehackt wurde, gibt es 2 Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
* Es kann die Webseite inkl. Dateien und Datenbank auf den Stand aus dem Backup vor dem Angriff zurückgesetzt werden, und muss dann umgehend aktualisiert werden. Bei diesem Vorgehen gehen die seitdem erfassten Beiträge verloren. Leider liegt der Zeitpunkt des Angriffs manchmal schon länger zurück.&lt;br /&gt;
* Ansonsten müssen die veränderten Dateien identifiziert und gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Das Identifizieren der veränderten Dateien kann mit folgenden Mitteln geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core verify-checksums --include-root --exclude=liesmich.html,readme.html&lt;br /&gt;
~/bin/wp-cli.phar plugin --skip-themes --skip-plugins verify-checksums --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in der wp-config.php sollte keine verdächtige Datei eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep include wp-config.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuletzt geänderte Dateien finden, im Beispiel der letzten 3 Tage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find -ctime -3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien im uploads und cache Verzeichnis finden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find wp-content/uploads wp-content/cache -type f \&lt;br /&gt;
  \( -name &#039;*.php&#039; -o -name &#039;*.phtml&#039; -o -name &#039;*.phar&#039; -o -name &#039;*.ico&#039; \) -ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die Schadcode speziell kodiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -rl &amp;quot;eval(base64_decode\|eval(gzinflate\|eval(str_rot13\|eval(htmlspecialchars_decode&amp;quot; . --include=&amp;quot;*.php&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die versuchen, einen Benutzer mit administrator Rechten anzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -r &#039;\\&amp;quot;administrator\\&amp;quot;&#039; wp-content/languages/plugins/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datenbank sollten die Benutzer mit administrator Rechten kontrolliert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT m.meta_key, m.meta_value, u.id, u.user_login, u.user_email, u.display_name&lt;br /&gt;
FROM wp_usermeta AS m join wp_users AS u ON m.user_id = u.id&lt;br /&gt;
WHERE meta_value LIKE &#039;%administrator%&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einen Admin Benutzer hinzufügen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du die Pflege einer WordPress Instanz übernehmen sollst, aber noch keinen Admin Benutzer hast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/bin/wp-cli.phar user create meinuser admin@example.org --role=administrator&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend kann der Benutzer auch wieder gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar user delete meinuser&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neue Domain umziehen ==&lt;br /&gt;
Meistens muss nichts weiter geändert werden als die Home und die SITE_URL Option. &lt;br /&gt;
&lt;br /&gt;
Einfach zu ändern geht das indem man sich via phpmyadmin.hostsharing.net in den Datenbank User des Wordpress einloggt und sich die Tabelle wp_options ansieht. Dort müssen die Zeilen mit `siteurl` und `home` an die neuen URLs angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man das auch über das wp-config.php machen. Meistens gibt es die beiden Einträge noch nicht, einfach an die passende Stelle für die Custom Config neu eintragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
define(&#039;WP_HOME&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
define(&#039;WP_SITEURL&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle mal noch auf alte Domain Einträge zu untersuchen und ggf zu ersetzen. &lt;br /&gt;
Das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%https://old-domain.de%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neuen User / Server umziehen / Uploads auf Storage auslagern == &lt;br /&gt;
&lt;br /&gt;
Meistens muss dafür keine weitere Änderung vorgenommen werden. Manchmal haben vorherige Anbieter einen alternativen Upload Pfad gesetzt. Das zeigt sich dadurch das man angeblich keine Schreibberechtigungen hätte beim Hochladen von z.B. Bildern. &lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit was dort kaputt sein könnte ist, das die Option `upload_path` noch auf einen alten Pfad vom alten Anbieter gesetzt wurde. Diese Option ist auch zu gebrauchen wenn der häufiger doch mal recht schnell wachsende Uploads Ordner auf den Storage und nicht auf die SSD ausgelagert werden soll. &lt;br /&gt;
&lt;br /&gt;
In der wp_options DB-Tabelle muss entsprechend die Variable `upload_path` angepasst werden. z.B. für den User xyz00-wordpress zu /home/storage/xyz00/users/wordpress/uploads&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle noch mal auf den Alten Pfad zu untersuchen und ggf. anzupassen, das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%/old/path/%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Du solltest einen persistenten Objekt-Cache verwenden&amp;quot;, sollte [[Redis#Redis_installieren|Redis installiert]] werden. Es reicht, wenn Redis auf einem Unix-Socket läuft, es muss nicht auf einem Port laufen.&lt;br /&gt;
&lt;br /&gt;
In der wp-config.php sollte dann (relativ weit oben) eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;WP_REDIS_SCHEME&#039;, &#039;unix&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PATH&#039;, &#039;/home/pacs/xyz00/users/service/redis/var/redis-server.sock&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PASSWORD&#039;, &#039;topsecret&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann z.B. das Plugin &amp;quot;Redis Object Cache&amp;quot; von Till Küss installiert werden: https://de.wordpress.org/plugins/redis-cache/&lt;br /&gt;
&lt;br /&gt;
Danach lässt sich der Object Cache unter &amp;quot;Einstellungen / Redis&amp;quot; aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Seiten Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Seiten-Cache wurde nicht erkannt, ...&amp;quot;, kann das Plugin WP Super Cache von Automattic installiert werden: https://wordpress.org/plugins/wp-super-cache/&lt;br /&gt;
&lt;br /&gt;
Der Cache muss dann in den Einstellungen des Plugins aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
*[https://wordpress.org/ Offizielle Webseite von Wordpress]&lt;br /&gt;
*[https://wp-cli.org/de/ WP-CLI ist das Kommandozeilen-Werkzeug für WordPress]&lt;br /&gt;
*[https://github.com/tpokorra/Hostsharing-Ansible-Wordpress Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Blog]]&lt;br /&gt;
[[Kategorie:CMS]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7627</id>
		<title>Wordpress</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7627"/>
		<updated>2026-08-27T04:09:58Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Uraltes Wordpress aktualisieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Wordpress in 5 Minuten =&lt;br /&gt;
&lt;br /&gt;
Installiert wird Wordpress hier unter der Domain https://blog.example.org.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;blog.example.org&#039;&#039;&lt;br /&gt;
* MySQL-User &lt;br /&gt;
* MySQL Datenbank&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-blog&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Wordpress Blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;blog.example.org&#039;,user:&#039;xyz00-blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqluser.add({set:{name:&#039;xyz00_wpuser&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqldb.add({set:{name:&#039;xyz00_wpdb&#039;,owner:&#039;xyz00_wpuser&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wordpress installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-blog&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
  ssh -l xyz00-blog xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs-ssl&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/blog.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www&lt;br /&gt;
cd htdocs-ssl&lt;br /&gt;
rm .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wordpress downloaden &amp;amp; entpacken z.b. im htdocs-ssl Verzeichnis&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
wget -O - https://wordpress.org/latest.tar.gz |tar -xz --strip 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wordpress konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://blog.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
= Verschiedene Hinweise und Anleitungen =&lt;br /&gt;
== wp-cli installieren ==&lt;br /&gt;
&lt;br /&gt;
wp-cli ist das Kommandozeilen-Werkzeug für WordPress: https://wp-cli.org/de/&lt;br /&gt;
&lt;br /&gt;
Es kann so installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/bin&lt;br /&gt;
cd ~/bin&lt;br /&gt;
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar&lt;br /&gt;
chmod a+x wp-cli.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uraltes Wordpress aktualisieren ==&lt;br /&gt;
&lt;br /&gt;
Manche Wordpress Installationen sind so alt, dass wp-login nicht mehr funktioniert.&lt;br /&gt;
&lt;br /&gt;
Mit wp-cli kann Wordpress auf die aktuelle Version aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress # oder ~/doms/meinedomain.de/subs-ssl/www/ oder wo sonst Wordpress installiert ist&lt;br /&gt;
~/bin/wp-cli.phar core update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls nur eine Minor Version installiert werden soll:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core update --minor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Umgang mit einem gehackten Wordpress ==&lt;br /&gt;
&lt;br /&gt;
Falls die Wordpress Instanz gehackt wurde, gibt es 2 Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
* Es kann die Webseite inkl. Dateien und Datenbank auf den Stand aus dem Backup vor dem Angriff zurückgesetzt werden, und muss dann umgehend aktualisiert werden. Bei diesem Vorgehen gehen die seitdem erfassten Beiträge verloren. Leider liegt der Zeitpunkt des Angriffs manchmal schon länger zurück.&lt;br /&gt;
* Ansonsten müssen die veränderten Dateien identifiziert und gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Das Identifizieren der veränderten Dateien kann mit folgenden Mitteln geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core verify-checksums --include-root --exclude=liesmich.html,readme.html&lt;br /&gt;
~/bin/wp-cli.phar plugin --skip-themes --skip-plugins verify-checksums --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in der wp-config.php sollte keine verdächtige Datei eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep include wp-config.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuletzt geänderte Dateien finden, im Beispiel der letzten 3 Tage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find -ctime -3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien im uploads und cache Verzeichnis finden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find wp-content/uploads wp-content/cache -type f \&lt;br /&gt;
  \( -name &#039;*.php&#039; -o -name &#039;*.phtml&#039; -o -name &#039;*.phar&#039; -o -name &#039;*.ico&#039; \) -ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die Schadcode speziell kodiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -rl &amp;quot;eval(base64_decode\|eval(gzinflate\|eval(str_rot13\|eval(htmlspecialchars_decode&amp;quot; . --include=&amp;quot;*.php&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die versuchen, einen Benutzer mit administrator Rechten anzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -r &#039;\\&amp;quot;administrator\\&amp;quot;&#039; wp-content/languages/plugins/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datenbank sollten die Benutzer mit administrator Rechten kontrolliert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT m.meta_key, m.meta_value, u.id, u.user_login, u.user_email, u.display_name&lt;br /&gt;
FROM wp_usermeta AS m join wp_users AS u ON m.user_id = u.id&lt;br /&gt;
WHERE meta_value LIKE &#039;%administrator%&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einen Admin Benutzer hinzufügen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du die Pflege einer WordPress Instanz übernehmen sollst, aber noch keinen Admin Benutzer hast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/bin/wp-cli.phar user create meinuser admin@example.org --role=administrator&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend kann der Benutzer auch wieder gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar user delete meinuser&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neue Domain umziehen ==&lt;br /&gt;
Meistens muss nichts weiter geändert werden als die Home und die SITE_URL Option. &lt;br /&gt;
&lt;br /&gt;
Einfach zu ändern geht das indem man sich via phpmyadmin.hostsharing.net in den Datenbank User des Wordpress einloggt und sich die Tabelle wp_options ansieht. Dort müssen die Zeilen mit `siteurl` und `home` an die neuen URLs angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man das auch über das wp-config.php machen. Meistens gibt es die beiden Einträge noch nicht, einfach an die passende Stelle für die Custom Config neu eintragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
define(&#039;WP_HOME&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
define(&#039;WP_SITEURL&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle mal noch auf alte Domain Einträge zu untersuchen und ggf zu ersetzen. &lt;br /&gt;
Das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%https://old-domain.de%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neuen User / Server umziehen / Uploads auf Storage auslagern == &lt;br /&gt;
&lt;br /&gt;
Meistens muss dafür keine weitere Änderung vorgenommen werden. Manchmal haben vorherige Anbieter einen alternativen Upload Pfad gesetzt. Das zeigt sich dadurch das man angeblich keine Schreibberechtigungen hätte beim Hochladen von z.B. Bildern. &lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit was dort kaputt sein könnte ist, das die Option `upload_path` noch auf einen alten Pfad vom alten Anbieter gesetzt wurde. Diese Option ist auch zu gebrauchen wenn der häufiger doch mal recht schnell wachsende Uploads Ordner auf den Storage und nicht auf die SSD ausgelagert werden soll. &lt;br /&gt;
&lt;br /&gt;
In der wp_options DB-Tabelle muss entsprechend die Variable `upload_path` angepasst werden. z.B. für den User xyz00-wordpress zu /home/storage/xyz00/users/wordpress/uploads&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle noch mal auf den Alten Pfad zu untersuchen und ggf. anzupassen, das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%/old/path/%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Du solltest einen persistenten Objekt-Cache verwenden&amp;quot;, sollte [[Redis#Redis_installieren|Redis installiert]] werden. Es reicht, wenn Redis auf einem Unix-Socket läuft, es muss nicht auf einem Port laufen.&lt;br /&gt;
&lt;br /&gt;
In der wp-config.php sollte dann (relativ weit oben) eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;WP_REDIS_SCHEME&#039;, &#039;unix&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PATH&#039;, &#039;/home/pacs/xyz00/users/service/redis/var/redis-server.sock&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PASSWORD&#039;, &#039;topsecret&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann z.B. das Plugin &amp;quot;Redis Object Cache&amp;quot; von Till Küss installiert werden: https://de.wordpress.org/plugins/redis-cache/&lt;br /&gt;
&lt;br /&gt;
Danach lässt sich der Object Cache unter &amp;quot;Einstellungen / Redis&amp;quot; aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Seiten Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Seiten-Cache wurde nicht erkannt, ...&amp;quot;, kann das Plugin WP Super Cache von Automattic installiert werden: https://wordpress.org/plugins/wp-super-cache/&lt;br /&gt;
&lt;br /&gt;
Der Cache muss dann in den Einstellungen des Plugins aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
*[https://wordpress.org/ Offizielle Webseite von Wordpress]&lt;br /&gt;
*[https://wp-cli.org/de/ WP-CLI ist das Kommandozeilen-Werkzeug für WordPress]&lt;br /&gt;
*[https://github.com/tpokorra/Hostsharing-Ansible-Wordpress Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Blog]]&lt;br /&gt;
[[Kategorie:CMS]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7626</id>
		<title>Wordpress</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7626"/>
		<updated>2026-08-26T18:08:55Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Umgang mit einem gehackten Wordpress */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Wordpress in 5 Minuten =&lt;br /&gt;
&lt;br /&gt;
Installiert wird Wordpress hier unter der Domain https://blog.example.org.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;blog.example.org&#039;&#039;&lt;br /&gt;
* MySQL-User &lt;br /&gt;
* MySQL Datenbank&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-blog&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Wordpress Blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;blog.example.org&#039;,user:&#039;xyz00-blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqluser.add({set:{name:&#039;xyz00_wpuser&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqldb.add({set:{name:&#039;xyz00_wpdb&#039;,owner:&#039;xyz00_wpuser&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wordpress installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-blog&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
  ssh -l xyz00-blog xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs-ssl&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/blog.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www&lt;br /&gt;
cd htdocs-ssl&lt;br /&gt;
rm .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wordpress downloaden &amp;amp; entpacken z.b. im htdocs-ssl Verzeichnis&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
wget -O - https://wordpress.org/latest.tar.gz |tar -xz --strip 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wordpress konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://blog.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
= Verschiedene Hinweise und Anleitungen =&lt;br /&gt;
== wp-cli installieren ==&lt;br /&gt;
&lt;br /&gt;
wp-cli ist das Kommandozeilen-Werkzeug für WordPress: https://wp-cli.org/de/&lt;br /&gt;
&lt;br /&gt;
Es kann so installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/bin&lt;br /&gt;
cd ~/bin&lt;br /&gt;
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar&lt;br /&gt;
chmod a+x wp-cli.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uraltes Wordpress aktualisieren ==&lt;br /&gt;
&lt;br /&gt;
Manche Wordpress Installationen sind so alt, dass wp-login nicht mehr funktioniert.&lt;br /&gt;
&lt;br /&gt;
Mit wp-cli kann Wordpress auf die aktuelle Version aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress # oder ~/doms/meinedomain.de/subs-ssl/www/ oder wo sonst Wordpress installiert ist&lt;br /&gt;
~/bin/wp-cli.phar core update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Umgang mit einem gehackten Wordpress ==&lt;br /&gt;
&lt;br /&gt;
Falls die Wordpress Instanz gehackt wurde, gibt es 2 Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
* Es kann die Webseite inkl. Dateien und Datenbank auf den Stand aus dem Backup vor dem Angriff zurückgesetzt werden, und muss dann umgehend aktualisiert werden. Bei diesem Vorgehen gehen die seitdem erfassten Beiträge verloren. Leider liegt der Zeitpunkt des Angriffs manchmal schon länger zurück.&lt;br /&gt;
* Ansonsten müssen die veränderten Dateien identifiziert und gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Das Identifizieren der veränderten Dateien kann mit folgenden Mitteln geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core verify-checksums --include-root --exclude=liesmich.html,readme.html&lt;br /&gt;
~/bin/wp-cli.phar plugin --skip-themes --skip-plugins verify-checksums --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in der wp-config.php sollte keine verdächtige Datei eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep include wp-config.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuletzt geänderte Dateien finden, im Beispiel der letzten 3 Tage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find -ctime -3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien im uploads und cache Verzeichnis finden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find wp-content/uploads wp-content/cache -type f \&lt;br /&gt;
  \( -name &#039;*.php&#039; -o -name &#039;*.phtml&#039; -o -name &#039;*.phar&#039; -o -name &#039;*.ico&#039; \) -ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die Schadcode speziell kodiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -rl &amp;quot;eval(base64_decode\|eval(gzinflate\|eval(str_rot13\|eval(htmlspecialchars_decode&amp;quot; . --include=&amp;quot;*.php&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die versuchen, einen Benutzer mit administrator Rechten anzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -r &#039;\\&amp;quot;administrator\\&amp;quot;&#039; wp-content/languages/plugins/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datenbank sollten die Benutzer mit administrator Rechten kontrolliert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT m.meta_key, m.meta_value, u.id, u.user_login, u.user_email, u.display_name&lt;br /&gt;
FROM wp_usermeta AS m join wp_users AS u ON m.user_id = u.id&lt;br /&gt;
WHERE meta_value LIKE &#039;%administrator%&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einen Admin Benutzer hinzufügen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du die Pflege einer WordPress Instanz übernehmen sollst, aber noch keinen Admin Benutzer hast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/bin/wp-cli.phar user create meinuser admin@example.org --role=administrator&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend kann der Benutzer auch wieder gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar user delete meinuser&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neue Domain umziehen ==&lt;br /&gt;
Meistens muss nichts weiter geändert werden als die Home und die SITE_URL Option. &lt;br /&gt;
&lt;br /&gt;
Einfach zu ändern geht das indem man sich via phpmyadmin.hostsharing.net in den Datenbank User des Wordpress einloggt und sich die Tabelle wp_options ansieht. Dort müssen die Zeilen mit `siteurl` und `home` an die neuen URLs angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man das auch über das wp-config.php machen. Meistens gibt es die beiden Einträge noch nicht, einfach an die passende Stelle für die Custom Config neu eintragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
define(&#039;WP_HOME&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
define(&#039;WP_SITEURL&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle mal noch auf alte Domain Einträge zu untersuchen und ggf zu ersetzen. &lt;br /&gt;
Das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%https://old-domain.de%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neuen User / Server umziehen / Uploads auf Storage auslagern == &lt;br /&gt;
&lt;br /&gt;
Meistens muss dafür keine weitere Änderung vorgenommen werden. Manchmal haben vorherige Anbieter einen alternativen Upload Pfad gesetzt. Das zeigt sich dadurch das man angeblich keine Schreibberechtigungen hätte beim Hochladen von z.B. Bildern. &lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit was dort kaputt sein könnte ist, das die Option `upload_path` noch auf einen alten Pfad vom alten Anbieter gesetzt wurde. Diese Option ist auch zu gebrauchen wenn der häufiger doch mal recht schnell wachsende Uploads Ordner auf den Storage und nicht auf die SSD ausgelagert werden soll. &lt;br /&gt;
&lt;br /&gt;
In der wp_options DB-Tabelle muss entsprechend die Variable `upload_path` angepasst werden. z.B. für den User xyz00-wordpress zu /home/storage/xyz00/users/wordpress/uploads&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle noch mal auf den Alten Pfad zu untersuchen und ggf. anzupassen, das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%/old/path/%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Du solltest einen persistenten Objekt-Cache verwenden&amp;quot;, sollte [[Redis#Redis_installieren|Redis installiert]] werden. Es reicht, wenn Redis auf einem Unix-Socket läuft, es muss nicht auf einem Port laufen.&lt;br /&gt;
&lt;br /&gt;
In der wp-config.php sollte dann (relativ weit oben) eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;WP_REDIS_SCHEME&#039;, &#039;unix&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PATH&#039;, &#039;/home/pacs/xyz00/users/service/redis/var/redis-server.sock&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PASSWORD&#039;, &#039;topsecret&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann z.B. das Plugin &amp;quot;Redis Object Cache&amp;quot; von Till Küss installiert werden: https://de.wordpress.org/plugins/redis-cache/&lt;br /&gt;
&lt;br /&gt;
Danach lässt sich der Object Cache unter &amp;quot;Einstellungen / Redis&amp;quot; aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Seiten Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Seiten-Cache wurde nicht erkannt, ...&amp;quot;, kann das Plugin WP Super Cache von Automattic installiert werden: https://wordpress.org/plugins/wp-super-cache/&lt;br /&gt;
&lt;br /&gt;
Der Cache muss dann in den Einstellungen des Plugins aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
*[https://wordpress.org/ Offizielle Webseite von Wordpress]&lt;br /&gt;
*[https://wp-cli.org/de/ WP-CLI ist das Kommandozeilen-Werkzeug für WordPress]&lt;br /&gt;
*[https://github.com/tpokorra/Hostsharing-Ansible-Wordpress Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Blog]]&lt;br /&gt;
[[Kategorie:CMS]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=ListMonk_installieren&amp;diff=7625</id>
		<title>ListMonk installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=ListMonk_installieren&amp;diff=7625"/>
		<updated>2026-08-21T10:06:48Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Installation mit Ansible Skript */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== ListMonk ==&lt;br /&gt;
ListMonk [https://listmonk.app/] ist ein Newsletter-Manager zum Selbsthosten, und steht unter der Open Source Lizenz AGPLv3.&lt;br /&gt;
&lt;br /&gt;
Monk hat in diesem Fall nichts mit einem Mönch zu tun, sondern ist eine versteckte Anspielung auf Monkey, da ListMonk eine Alternative zu MailChimp (Chimpanse) ist.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039; Listmonk wirbt damit, [https://github.com/knadh/listmonk/blob/master/README.md Newsletter- und Mailinglisten-Manager] zu sein. Laut [https://github.com/knadh/listmonk/issues/1355 Fehlerbericht] ist das Tool aber lediglich für Einweg-Kommunikation (Newsletter) vorgesehen.&lt;br /&gt;
&lt;br /&gt;
== Zur Technik ==&lt;br /&gt;
ListMonk ist in Go geschrieben, und wird als ein einziges Binary (Programm) installiert. Man muss im Shared Webspace bei Hostsharing einen Service dazu buchen, oder man setzt es auf einem Managed Server von Hostsharing ein.&lt;br /&gt;
&lt;br /&gt;
Im Hintergrund wird PostgreSQL als Datenbank benutzt.&lt;br /&gt;
&lt;br /&gt;
ListMonk bietet Anmeldungen per Double-Opt-In, und es gibt auch eine API für die Integration mit CRM/ERP Systemen (https://listmonk.app/docs/apis/apis/).&lt;br /&gt;
&lt;br /&gt;
== Zur Installation ==&lt;br /&gt;
Die Installation ist recht einfach: https://listmonk.app/docs/installation/&lt;br /&gt;
&lt;br /&gt;
* Das Programm beispielsweise [https://github.com/knadh/listmonk/releases auf Github herunterladen] und entpacken&lt;br /&gt;
* Vorher den Hostsharing Service um eine freie Port Nummer fragen.&lt;br /&gt;
* Eine Datenbank anlegen&lt;br /&gt;
* Mit [[systemd]] wird das Programm als Dienst gestartet. Hierzu wird das Verzeichnis &amp;lt;code&amp;gt;~/.config/systemd/user/&amp;lt;/code&amp;gt; erstellt und eine .service Datei angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Listmonk&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
Restart=on-abort&lt;br /&gt;
WorkingDirectory=/home/pacs/xyz00/users/newsletter&lt;br /&gt;
# --config mit vollständigem Pfad zum Configfile falls nicht im WorkingDirectory&lt;br /&gt;
ExecStart=/home/pacs/xyz00/users/newsletter/bin/listmonk&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start und aktivieren von Autostart mittels &amp;lt;code&amp;gt;systemctl enable --now --user listmonk&amp;lt;/code&amp;gt;&lt;br /&gt;
* Beispiel Webserver--Konfiguration unter &amp;lt;code&amp;gt;doms/meine-domain/htdocs-ssl/.htaccess&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot; line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
# Port entsprechend der config.toml nach Absprache mit Service s.o.&lt;br /&gt;
RewriteRule ^(.*) http://127.0.0.1:9000/$1 [proxy,last]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Installation mit Ansible Skript ===&lt;br /&gt;
Es gibt ein Ansible Skript für Hostsharing [https://codeberg.org/tpokorra/hs.ansible.app.listmonk], das die Installation automatisiert vornimmt, und schon den SMTP und POP Zugang konfiguriert.&lt;br /&gt;
&lt;br /&gt;
Dort kann man sicherlich auch Feinheiten der Installation abschauen, wenn man ListMonk manuell installieren will.&lt;br /&gt;
&lt;br /&gt;
== Zur Bedienung ==&lt;br /&gt;
&lt;br /&gt;
Hier ist ein Bildschirmfoto zur Einrichtung von SMTP für den Versand der E-Mails:&lt;br /&gt;
&lt;br /&gt;
[[Datei:ListMonk SMTPSetup.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hier ist ein Bildschirmfoto zur Generierung des Formulars zur Anmeldung für einen Newsletter:&lt;br /&gt;
&lt;br /&gt;
[[Datei:ListMonk SubscriptionForm.png]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://listmonk.app/ Projektseite&lt;br /&gt;
* https://github.com/knadh/listmonk ListMonk auf Github&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible.app.listmonk Ansible Rolle für Hostsharing&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:Newsletterversand]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7624</id>
		<title>Wordpress</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7624"/>
		<updated>2026-08-20T10:46:09Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Gehackte Dateien identifizieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Wordpress in 5 Minuten =&lt;br /&gt;
&lt;br /&gt;
Installiert wird Wordpress hier unter der Domain https://blog.example.org.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;blog.example.org&#039;&#039;&lt;br /&gt;
* MySQL-User &lt;br /&gt;
* MySQL Datenbank&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-blog&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Wordpress Blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;blog.example.org&#039;,user:&#039;xyz00-blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqluser.add({set:{name:&#039;xyz00_wpuser&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqldb.add({set:{name:&#039;xyz00_wpdb&#039;,owner:&#039;xyz00_wpuser&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wordpress installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-blog&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
  ssh -l xyz00-blog xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs-ssl&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/blog.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www&lt;br /&gt;
cd htdocs-ssl&lt;br /&gt;
rm .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wordpress downloaden &amp;amp; entpacken z.b. im htdocs-ssl Verzeichnis&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
wget -O - https://wordpress.org/latest.tar.gz |tar -xz --strip 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wordpress konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://blog.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
= Verschiedene Hinweise und Anleitungen =&lt;br /&gt;
== wp-cli installieren ==&lt;br /&gt;
&lt;br /&gt;
wp-cli ist das Kommandozeilen-Werkzeug für WordPress: https://wp-cli.org/de/&lt;br /&gt;
&lt;br /&gt;
Es kann so installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/bin&lt;br /&gt;
cd ~/bin&lt;br /&gt;
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar&lt;br /&gt;
chmod a+x wp-cli.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uraltes Wordpress aktualisieren ==&lt;br /&gt;
&lt;br /&gt;
Manche Wordpress Installationen sind so alt, dass wp-login nicht mehr funktioniert.&lt;br /&gt;
&lt;br /&gt;
Mit wp-cli kann Wordpress auf die aktuelle Version aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress # oder ~/doms/meinedomain.de/subs-ssl/www/ oder wo sonst Wordpress installiert ist&lt;br /&gt;
~/bin/wp-cli.phar core update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Umgang mit einem gehackten Wordpress ==&lt;br /&gt;
&lt;br /&gt;
Falls die Wordpress Instanz gehackt wurde, gibt es 2 Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
* Es kann die Webseite inkl. Dateien und Datenbank auf den Stand aus dem Backup vor dem Angriff zurückgesetzt werden, und muss dann umgehend aktualisiert werden. Bei diesem Vorgehen gehen die seitdem erfassten Beiträge verloren. Leider liegt der Zeitpunkt des Angriffs manchmal schon länger zurück.&lt;br /&gt;
* Ansonsten müssen die veränderten Dateien identifiziert und gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Das Identifizieren der veränderten Dateien kann mit folgenden Mitteln geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core verify-checksums&lt;br /&gt;
~/bin/wp-cli.phar plugin --skip-themes --skip-plugins verify-checksums --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in der wp-config.php sollte keine verdächtige Datei eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep include wp-config.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuletzt geänderte Dateien finden, im Beispiel der letzten 3 Tage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find -ctime -3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien im uploads und cache Verzeichnis finden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find wp-content/uploads wp-content/cache -type f \&lt;br /&gt;
  \( -name &#039;*.php&#039; -o -name &#039;*.phtml&#039; -o -name &#039;*.phar&#039; -o -name &#039;*.ico&#039; \) -ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die Schadcode speziell kodiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -rl &amp;quot;eval(base64_decode\|eval(gzinflate\|eval(str_rot13\|eval(htmlspecialchars_decode&amp;quot; . --include=&amp;quot;*.php&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die versuchen, einen Benutzer mit administrator Rechten anzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -r &#039;\\&amp;quot;administrator\\&amp;quot;&#039; wp-content/languages/plugins/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datenbank sollten die Benutzer mit administrator Rechten kontrolliert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT m.meta_key, m.meta_value, u.id, u.user_login, u.user_email, u.display_name&lt;br /&gt;
FROM wp_usermeta AS m join wp_users AS u ON m.user_id = u.id&lt;br /&gt;
WHERE meta_value LIKE &#039;%administrator%&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einen Admin Benutzer hinzufügen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du die Pflege einer WordPress Instanz übernehmen sollst, aber noch keinen Admin Benutzer hast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/bin/wp-cli.phar user create meinuser admin@example.org --role=administrator&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend kann der Benutzer auch wieder gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar user delete meinuser&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neue Domain umziehen ==&lt;br /&gt;
Meistens muss nichts weiter geändert werden als die Home und die SITE_URL Option. &lt;br /&gt;
&lt;br /&gt;
Einfach zu ändern geht das indem man sich via phpmyadmin.hostsharing.net in den Datenbank User des Wordpress einloggt und sich die Tabelle wp_options ansieht. Dort müssen die Zeilen mit `siteurl` und `home` an die neuen URLs angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man das auch über das wp-config.php machen. Meistens gibt es die beiden Einträge noch nicht, einfach an die passende Stelle für die Custom Config neu eintragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
define(&#039;WP_HOME&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
define(&#039;WP_SITEURL&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle mal noch auf alte Domain Einträge zu untersuchen und ggf zu ersetzen. &lt;br /&gt;
Das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%https://old-domain.de%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neuen User / Server umziehen / Uploads auf Storage auslagern == &lt;br /&gt;
&lt;br /&gt;
Meistens muss dafür keine weitere Änderung vorgenommen werden. Manchmal haben vorherige Anbieter einen alternativen Upload Pfad gesetzt. Das zeigt sich dadurch das man angeblich keine Schreibberechtigungen hätte beim Hochladen von z.B. Bildern. &lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit was dort kaputt sein könnte ist, das die Option `upload_path` noch auf einen alten Pfad vom alten Anbieter gesetzt wurde. Diese Option ist auch zu gebrauchen wenn der häufiger doch mal recht schnell wachsende Uploads Ordner auf den Storage und nicht auf die SSD ausgelagert werden soll. &lt;br /&gt;
&lt;br /&gt;
In der wp_options DB-Tabelle muss entsprechend die Variable `upload_path` angepasst werden. z.B. für den User xyz00-wordpress zu /home/storage/xyz00/users/wordpress/uploads&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle noch mal auf den Alten Pfad zu untersuchen und ggf. anzupassen, das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%/old/path/%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Du solltest einen persistenten Objekt-Cache verwenden&amp;quot;, sollte [[Redis#Redis_installieren|Redis installiert]] werden. Es reicht, wenn Redis auf einem Unix-Socket läuft, es muss nicht auf einem Port laufen.&lt;br /&gt;
&lt;br /&gt;
In der wp-config.php sollte dann (relativ weit oben) eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;WP_REDIS_SCHEME&#039;, &#039;unix&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PATH&#039;, &#039;/home/pacs/xyz00/users/service/redis/var/redis-server.sock&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PASSWORD&#039;, &#039;topsecret&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann z.B. das Plugin &amp;quot;Redis Object Cache&amp;quot; von Till Küss installiert werden: https://de.wordpress.org/plugins/redis-cache/&lt;br /&gt;
&lt;br /&gt;
Danach lässt sich der Object Cache unter &amp;quot;Einstellungen / Redis&amp;quot; aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Seiten Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Seiten-Cache wurde nicht erkannt, ...&amp;quot;, kann das Plugin WP Super Cache von Automattic installiert werden: https://wordpress.org/plugins/wp-super-cache/&lt;br /&gt;
&lt;br /&gt;
Der Cache muss dann in den Einstellungen des Plugins aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
*[https://wordpress.org/ Offizielle Webseite von Wordpress]&lt;br /&gt;
*[https://wp-cli.org/de/ WP-CLI ist das Kommandozeilen-Werkzeug für WordPress]&lt;br /&gt;
*[https://github.com/tpokorra/Hostsharing-Ansible-Wordpress Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Blog]]&lt;br /&gt;
[[Kategorie:CMS]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7623</id>
		<title>Wordpress</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7623"/>
		<updated>2026-08-20T10:45:31Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Gehackte Dateien identifizieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Wordpress in 5 Minuten =&lt;br /&gt;
&lt;br /&gt;
Installiert wird Wordpress hier unter der Domain https://blog.example.org.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;blog.example.org&#039;&#039;&lt;br /&gt;
* MySQL-User &lt;br /&gt;
* MySQL Datenbank&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-blog&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Wordpress Blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;blog.example.org&#039;,user:&#039;xyz00-blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqluser.add({set:{name:&#039;xyz00_wpuser&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqldb.add({set:{name:&#039;xyz00_wpdb&#039;,owner:&#039;xyz00_wpuser&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wordpress installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-blog&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
  ssh -l xyz00-blog xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs-ssl&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/blog.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www&lt;br /&gt;
cd htdocs-ssl&lt;br /&gt;
rm .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wordpress downloaden &amp;amp; entpacken z.b. im htdocs-ssl Verzeichnis&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
wget -O - https://wordpress.org/latest.tar.gz |tar -xz --strip 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wordpress konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://blog.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
= Verschiedene Hinweise und Anleitungen =&lt;br /&gt;
== wp-cli installieren ==&lt;br /&gt;
&lt;br /&gt;
wp-cli ist das Kommandozeilen-Werkzeug für WordPress: https://wp-cli.org/de/&lt;br /&gt;
&lt;br /&gt;
Es kann so installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/bin&lt;br /&gt;
cd ~/bin&lt;br /&gt;
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar&lt;br /&gt;
chmod a+x wp-cli.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uraltes Wordpress aktualisieren ==&lt;br /&gt;
&lt;br /&gt;
Manche Wordpress Installationen sind so alt, dass wp-login nicht mehr funktioniert.&lt;br /&gt;
&lt;br /&gt;
Mit wp-cli kann Wordpress auf die aktuelle Version aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress # oder ~/doms/meinedomain.de/subs-ssl/www/ oder wo sonst Wordpress installiert ist&lt;br /&gt;
~/bin/wp-cli.phar core update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gehackte Dateien identifizieren ==&lt;br /&gt;
&lt;br /&gt;
Falls die Wordpress Instanz gehackt wurde, gibt es 2 Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
* Es kann die Webseite inkl. Dateien und Datenbank auf den Stand aus dem Backup vor dem Angriff zurückgesetzt werden, und muss dann umgehend aktualisiert werden. Bei diesem Vorgehen gehen die seitdem erfassten Beiträge verloren. Leider liegt der Zeitpunkt des Angriffs manchmal schon länger zurück.&lt;br /&gt;
* Ansonsten müssen die veränderten Dateien identifiziert und gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Das Identifizieren der veränderten Dateien kann mit folgenden Mitteln geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core verify-checksums&lt;br /&gt;
~/bin/wp-cli.phar plugin --skip-themes --skip-plugins verify-checksums --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in der wp-config.php sollte keine verdächtige Datei eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep include wp-config.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuletzt geänderte Dateien finden, im Beispiel der letzten 3 Tage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find -ctime -3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien im uploads und cache Verzeichnis finden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find wp-content/uploads wp-content/cache -type f \&lt;br /&gt;
  \( -name &#039;*.php&#039; -o -name &#039;*.phtml&#039; -o -name &#039;*.phar&#039; -o -name &#039;*.ico&#039; \) -ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die Schadcode speziell kodiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -rl &amp;quot;eval(base64_decode\|eval(gzinflate\|eval(str_rot13\|eval(htmlspecialchars_decode&amp;quot; . --include=&amp;quot;*.php&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die versuchen, einen Benutzer mit administrator Rechten anzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -r &#039;\\&amp;quot;administrator\\&amp;quot;&#039; wp-content/languages/plugins/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datenbank sollten die Benutzer mit administrator Rechten kontrolliert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT m.meta_key, m.meta_value, u.id, u.user_login, u.user_email, u.display_name&lt;br /&gt;
FROM wp_usermeta AS m join wp_users AS u ON m.user_id = u.id&lt;br /&gt;
WHERE meta_value LIKE &#039;%administrator%&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einen Admin Benutzer hinzufügen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du die Pflege einer WordPress Instanz übernehmen sollst, aber noch keinen Admin Benutzer hast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/bin/wp-cli.phar user create meinuser admin@example.org --role=administrator&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend kann der Benutzer auch wieder gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar user delete meinuser&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neue Domain umziehen ==&lt;br /&gt;
Meistens muss nichts weiter geändert werden als die Home und die SITE_URL Option. &lt;br /&gt;
&lt;br /&gt;
Einfach zu ändern geht das indem man sich via phpmyadmin.hostsharing.net in den Datenbank User des Wordpress einloggt und sich die Tabelle wp_options ansieht. Dort müssen die Zeilen mit `siteurl` und `home` an die neuen URLs angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man das auch über das wp-config.php machen. Meistens gibt es die beiden Einträge noch nicht, einfach an die passende Stelle für die Custom Config neu eintragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
define(&#039;WP_HOME&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
define(&#039;WP_SITEURL&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle mal noch auf alte Domain Einträge zu untersuchen und ggf zu ersetzen. &lt;br /&gt;
Das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%https://old-domain.de%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neuen User / Server umziehen / Uploads auf Storage auslagern == &lt;br /&gt;
&lt;br /&gt;
Meistens muss dafür keine weitere Änderung vorgenommen werden. Manchmal haben vorherige Anbieter einen alternativen Upload Pfad gesetzt. Das zeigt sich dadurch das man angeblich keine Schreibberechtigungen hätte beim Hochladen von z.B. Bildern. &lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit was dort kaputt sein könnte ist, das die Option `upload_path` noch auf einen alten Pfad vom alten Anbieter gesetzt wurde. Diese Option ist auch zu gebrauchen wenn der häufiger doch mal recht schnell wachsende Uploads Ordner auf den Storage und nicht auf die SSD ausgelagert werden soll. &lt;br /&gt;
&lt;br /&gt;
In der wp_options DB-Tabelle muss entsprechend die Variable `upload_path` angepasst werden. z.B. für den User xyz00-wordpress zu /home/storage/xyz00/users/wordpress/uploads&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle noch mal auf den Alten Pfad zu untersuchen und ggf. anzupassen, das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%/old/path/%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Du solltest einen persistenten Objekt-Cache verwenden&amp;quot;, sollte [[Redis#Redis_installieren|Redis installiert]] werden. Es reicht, wenn Redis auf einem Unix-Socket läuft, es muss nicht auf einem Port laufen.&lt;br /&gt;
&lt;br /&gt;
In der wp-config.php sollte dann (relativ weit oben) eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;WP_REDIS_SCHEME&#039;, &#039;unix&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PATH&#039;, &#039;/home/pacs/xyz00/users/service/redis/var/redis-server.sock&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PASSWORD&#039;, &#039;topsecret&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann z.B. das Plugin &amp;quot;Redis Object Cache&amp;quot; von Till Küss installiert werden: https://de.wordpress.org/plugins/redis-cache/&lt;br /&gt;
&lt;br /&gt;
Danach lässt sich der Object Cache unter &amp;quot;Einstellungen / Redis&amp;quot; aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Seiten Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Seiten-Cache wurde nicht erkannt, ...&amp;quot;, kann das Plugin WP Super Cache von Automattic installiert werden: https://wordpress.org/plugins/wp-super-cache/&lt;br /&gt;
&lt;br /&gt;
Der Cache muss dann in den Einstellungen des Plugins aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
*[https://wordpress.org/ Offizielle Webseite von Wordpress]&lt;br /&gt;
*[https://wp-cli.org/de/ WP-CLI ist das Kommandozeilen-Werkzeug für WordPress]&lt;br /&gt;
*[https://github.com/tpokorra/Hostsharing-Ansible-Wordpress Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Blog]]&lt;br /&gt;
[[Kategorie:CMS]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7622</id>
		<title>Wordpress</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7622"/>
		<updated>2026-08-20T08:01:11Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Gehackte Dateien identifizieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Wordpress in 5 Minuten =&lt;br /&gt;
&lt;br /&gt;
Installiert wird Wordpress hier unter der Domain https://blog.example.org.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;blog.example.org&#039;&#039;&lt;br /&gt;
* MySQL-User &lt;br /&gt;
* MySQL Datenbank&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-blog&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Wordpress Blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;blog.example.org&#039;,user:&#039;xyz00-blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqluser.add({set:{name:&#039;xyz00_wpuser&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqldb.add({set:{name:&#039;xyz00_wpdb&#039;,owner:&#039;xyz00_wpuser&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wordpress installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-blog&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
  ssh -l xyz00-blog xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs-ssl&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/blog.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www&lt;br /&gt;
cd htdocs-ssl&lt;br /&gt;
rm .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wordpress downloaden &amp;amp; entpacken z.b. im htdocs-ssl Verzeichnis&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
wget -O - https://wordpress.org/latest.tar.gz |tar -xz --strip 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wordpress konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://blog.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
= Verschiedene Hinweise und Anleitungen =&lt;br /&gt;
== wp-cli installieren ==&lt;br /&gt;
&lt;br /&gt;
wp-cli ist das Kommandozeilen-Werkzeug für WordPress: https://wp-cli.org/de/&lt;br /&gt;
&lt;br /&gt;
Es kann so installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/bin&lt;br /&gt;
cd ~/bin&lt;br /&gt;
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar&lt;br /&gt;
chmod a+x wp-cli.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uraltes Wordpress aktualisieren ==&lt;br /&gt;
&lt;br /&gt;
Manche Wordpress Installationen sind so alt, dass wp-login nicht mehr funktioniert.&lt;br /&gt;
&lt;br /&gt;
Mit wp-cli kann Wordpress auf die aktuelle Version aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress # oder ~/doms/meinedomain.de/subs-ssl/www/ oder wo sonst Wordpress installiert ist&lt;br /&gt;
~/bin/wp-cli.phar core update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gehackte Dateien identifizieren ==&lt;br /&gt;
&lt;br /&gt;
Falls die Wordpress Instanz gehackt wurde, müssen die veränderten Dateien identifiziert und gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Das geht wieder mit wp-cli.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core verify-checksums&lt;br /&gt;
~/bin/wp-cli.phar plugin --skip-themes --skip-plugins verify-checksums --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in der wp-config.php sollte keine verdächtige Datei eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep include wp-config.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuletzt geänderte Dateien finden, im Beispiel der letzten 3 Tage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find -ctime -3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien im uploads und cache Verzeichnis finden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find wp-content/uploads wp-content/cache -type f \&lt;br /&gt;
  \( -name &#039;*.php&#039; -o -name &#039;*.phtml&#039; -o -name &#039;*.phar&#039; -o -name &#039;*.ico&#039; \) -ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die Schadcode speziell kodiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -rl &amp;quot;eval(base64_decode\|eval(gzinflate\|eval(str_rot13\|eval(htmlspecialchars_decode&amp;quot; . --include=&amp;quot;*.php&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die versuchen, einen Benutzer mit administrator Rechten anzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -r &#039;\\&amp;quot;administrator\\&amp;quot;&#039; wp-content/languages/plugins/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datenbank sollten die Benutzer mit administrator Rechten kontrolliert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT m.meta_key, m.meta_value, u.id, u.user_login, u.user_email, u.display_name&lt;br /&gt;
FROM wp_usermeta AS m join wp_users AS u ON m.user_id = u.id&lt;br /&gt;
WHERE meta_value LIKE &#039;%administrator%&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einen Admin Benutzer hinzufügen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du die Pflege einer WordPress Instanz übernehmen sollst, aber noch keinen Admin Benutzer hast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/bin/wp-cli.phar user create meinuser admin@example.org --role=administrator&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend kann der Benutzer auch wieder gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar user delete meinuser&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neue Domain umziehen ==&lt;br /&gt;
Meistens muss nichts weiter geändert werden als die Home und die SITE_URL Option. &lt;br /&gt;
&lt;br /&gt;
Einfach zu ändern geht das indem man sich via phpmyadmin.hostsharing.net in den Datenbank User des Wordpress einloggt und sich die Tabelle wp_options ansieht. Dort müssen die Zeilen mit `siteurl` und `home` an die neuen URLs angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man das auch über das wp-config.php machen. Meistens gibt es die beiden Einträge noch nicht, einfach an die passende Stelle für die Custom Config neu eintragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
define(&#039;WP_HOME&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
define(&#039;WP_SITEURL&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle mal noch auf alte Domain Einträge zu untersuchen und ggf zu ersetzen. &lt;br /&gt;
Das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%https://old-domain.de%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neuen User / Server umziehen / Uploads auf Storage auslagern == &lt;br /&gt;
&lt;br /&gt;
Meistens muss dafür keine weitere Änderung vorgenommen werden. Manchmal haben vorherige Anbieter einen alternativen Upload Pfad gesetzt. Das zeigt sich dadurch das man angeblich keine Schreibberechtigungen hätte beim Hochladen von z.B. Bildern. &lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit was dort kaputt sein könnte ist, das die Option `upload_path` noch auf einen alten Pfad vom alten Anbieter gesetzt wurde. Diese Option ist auch zu gebrauchen wenn der häufiger doch mal recht schnell wachsende Uploads Ordner auf den Storage und nicht auf die SSD ausgelagert werden soll. &lt;br /&gt;
&lt;br /&gt;
In der wp_options DB-Tabelle muss entsprechend die Variable `upload_path` angepasst werden. z.B. für den User xyz00-wordpress zu /home/storage/xyz00/users/wordpress/uploads&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle noch mal auf den Alten Pfad zu untersuchen und ggf. anzupassen, das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%/old/path/%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Du solltest einen persistenten Objekt-Cache verwenden&amp;quot;, sollte [[Redis#Redis_installieren|Redis installiert]] werden. Es reicht, wenn Redis auf einem Unix-Socket läuft, es muss nicht auf einem Port laufen.&lt;br /&gt;
&lt;br /&gt;
In der wp-config.php sollte dann (relativ weit oben) eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;WP_REDIS_SCHEME&#039;, &#039;unix&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PATH&#039;, &#039;/home/pacs/xyz00/users/service/redis/var/redis-server.sock&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PASSWORD&#039;, &#039;topsecret&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann z.B. das Plugin &amp;quot;Redis Object Cache&amp;quot; von Till Küss installiert werden: https://de.wordpress.org/plugins/redis-cache/&lt;br /&gt;
&lt;br /&gt;
Danach lässt sich der Object Cache unter &amp;quot;Einstellungen / Redis&amp;quot; aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Seiten Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Seiten-Cache wurde nicht erkannt, ...&amp;quot;, kann das Plugin WP Super Cache von Automattic installiert werden: https://wordpress.org/plugins/wp-super-cache/&lt;br /&gt;
&lt;br /&gt;
Der Cache muss dann in den Einstellungen des Plugins aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
*[https://wordpress.org/ Offizielle Webseite von Wordpress]&lt;br /&gt;
*[https://wp-cli.org/de/ WP-CLI ist das Kommandozeilen-Werkzeug für WordPress]&lt;br /&gt;
*[https://github.com/tpokorra/Hostsharing-Ansible-Wordpress Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Blog]]&lt;br /&gt;
[[Kategorie:CMS]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7621</id>
		<title>Wordpress</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Wordpress&amp;diff=7621"/>
		<updated>2026-08-20T06:02:18Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Gehackte Dateien identifizieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Wordpress in 5 Minuten =&lt;br /&gt;
&lt;br /&gt;
Installiert wird Wordpress hier unter der Domain https://blog.example.org.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;hsadmin&#039;&#039;, zum Beispiel mit &#039;&#039;hsscript&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;hsadmin&#039;&#039;-Shell starten mit:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
hsscript -u xyz00 -i&lt;br /&gt;
Password: ********&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann nacheinander anlegen:&lt;br /&gt;
&lt;br /&gt;
* Linux User als Domain-Administrator&lt;br /&gt;
* Subdomain &#039;&#039;blog.example.org&#039;&#039;&lt;br /&gt;
* MySQL-User &lt;br /&gt;
* MySQL Datenbank&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@hsadmin&amp;gt; user.add({set:{name:&#039;xyz00-blog&#039;,password:&#039;geheim&#039;,shell:&#039;/bin/bash&#039;,comment:&#039;Wordpress Blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; domain.add({set:{name:&#039;blog.example.org&#039;,user:&#039;xyz00-blog&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqluser.add({set:{name:&#039;xyz00_wpuser&#039;,password:&#039;geheim&#039;}})&lt;br /&gt;
xyz00@hsadmin&amp;gt; mysqldb.add({set:{name:&#039;xyz00_wpdb&#039;,owner:&#039;xyz00_wpuser&#039;}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wordpress installieren ==&lt;br /&gt;
&lt;br /&gt;
Anmelden als Linux-User &#039;&#039;xyz00-blog&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
  ssh -l xyz00-blog xyz00.hostsharing.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;htdocs-ssl&#039;&#039; Verzeichnis vorbereiten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd doms/blog.example.org&lt;br /&gt;
rm -rf subs/www subs-ssl/www&lt;br /&gt;
cd htdocs-ssl&lt;br /&gt;
rm .htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wordpress downloaden &amp;amp; entpacken z.b. im htdocs-ssl Verzeichnis&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
wget -O - https://wordpress.org/latest.tar.gz |tar -xz --strip 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wordpress konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Im Browser auf die Seite &lt;br /&gt;
http://blog.example.org gehen und den Anweisungen folgen.&lt;br /&gt;
&lt;br /&gt;
= Verschiedene Hinweise und Anleitungen =&lt;br /&gt;
== wp-cli installieren ==&lt;br /&gt;
&lt;br /&gt;
wp-cli ist das Kommandozeilen-Werkzeug für WordPress: https://wp-cli.org/de/&lt;br /&gt;
&lt;br /&gt;
Es kann so installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/bin&lt;br /&gt;
cd ~/bin&lt;br /&gt;
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar&lt;br /&gt;
chmod a+x wp-cli.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uraltes Wordpress aktualisieren ==&lt;br /&gt;
&lt;br /&gt;
Manche Wordpress Installationen sind so alt, dass wp-login nicht mehr funktioniert.&lt;br /&gt;
&lt;br /&gt;
Mit wp-cli kann Wordpress auf die aktuelle Version aktualisiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress # oder ~/doms/meinedomain.de/subs-ssl/www/ oder wo sonst Wordpress installiert ist&lt;br /&gt;
~/bin/wp-cli.phar core update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gehackte Dateien identifizieren ==&lt;br /&gt;
&lt;br /&gt;
Falls die Wordpress Instanz gehackt wurde, müssen die veränderten Dateien identifiziert und gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Das geht wieder mit wp-cli.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar core verify-checksums&lt;br /&gt;
~/bin/wp-cli.phar plugin --skip-themes --skip-plugins verify-checksums --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in der wp-config.php sollte keine verdächtige Datei eingebunden werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep include wp-config.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuletzt geänderte Dateien finden, im Beispiel der letzten 3 Tage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find -ctime -3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien im uploads und cache Verzeichnis finden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
find wp-content/uploads wp-content/cache -type f \&lt;br /&gt;
  \( -name &#039;*.php&#039; -o -name &#039;*.phtml&#039; -o -name &#039;*.phar&#039; -o -name &#039;*.ico&#039; \) -ls&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verdächtige Dateien finden, die versuchen, einen Benutzer mit administrator Rechten anzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
grep -r &#039;\\&amp;quot;administrator\\&amp;quot;&#039; wp-content/languages/plugins/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Datenbank sollten die Benutzer mit administrator Rechten kontrolliert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT m.meta_key, m.meta_value, u.id, u.user_login, u.user_email, u.display_name&lt;br /&gt;
FROM wp_usermeta AS m join wp_users AS u ON m.user_id = u.id&lt;br /&gt;
WHERE meta_value LIKE &#039;%administrator%&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einen Admin Benutzer hinzufügen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du die Pflege einer WordPress Instanz übernehmen sollst, aber noch keinen Admin Benutzer hast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
&lt;br /&gt;
~/bin/wp-cli.phar user create meinuser admin@example.org --role=administrator&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend kann der Benutzer auch wieder gelöscht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/wordpress&lt;br /&gt;
~/bin/wp-cli.phar user delete meinuser&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neue Domain umziehen ==&lt;br /&gt;
Meistens muss nichts weiter geändert werden als die Home und die SITE_URL Option. &lt;br /&gt;
&lt;br /&gt;
Einfach zu ändern geht das indem man sich via phpmyadmin.hostsharing.net in den Datenbank User des Wordpress einloggt und sich die Tabelle wp_options ansieht. Dort müssen die Zeilen mit `siteurl` und `home` an die neuen URLs angepasst werden. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man das auch über das wp-config.php machen. Meistens gibt es die beiden Einträge noch nicht, einfach an die passende Stelle für die Custom Config neu eintragen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
define(&#039;WP_HOME&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
define(&#039;WP_SITEURL&#039;,&#039;https://www.new-domain.de/&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle mal noch auf alte Domain Einträge zu untersuchen und ggf zu ersetzen. &lt;br /&gt;
Das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%https://old-domain.de%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bestehendes Wordpress auf neuen User / Server umziehen / Uploads auf Storage auslagern == &lt;br /&gt;
&lt;br /&gt;
Meistens muss dafür keine weitere Änderung vorgenommen werden. Manchmal haben vorherige Anbieter einen alternativen Upload Pfad gesetzt. Das zeigt sich dadurch das man angeblich keine Schreibberechtigungen hätte beim Hochladen von z.B. Bildern. &lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit was dort kaputt sein könnte ist, das die Option `upload_path` noch auf einen alten Pfad vom alten Anbieter gesetzt wurde. Diese Option ist auch zu gebrauchen wenn der häufiger doch mal recht schnell wachsende Uploads Ordner auf den Storage und nicht auf die SSD ausgelagert werden soll. &lt;br /&gt;
&lt;br /&gt;
In der wp_options DB-Tabelle muss entsprechend die Variable `upload_path` angepasst werden. z.B. für den User xyz00-wordpress zu /home/storage/xyz00/users/wordpress/uploads&lt;br /&gt;
&lt;br /&gt;
Generell lohnt es sich die wp_options Tabelle noch mal auf den Alten Pfad zu untersuchen und ggf. anzupassen, das geht z.B. so: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=sql&amp;gt;&lt;br /&gt;
SELECT * FROM wp_options WHERE option_value LIKE &amp;quot;%/old/path/%&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Du solltest einen persistenten Objekt-Cache verwenden&amp;quot;, sollte [[Redis#Redis_installieren|Redis installiert]] werden. Es reicht, wenn Redis auf einem Unix-Socket läuft, es muss nicht auf einem Port laufen.&lt;br /&gt;
&lt;br /&gt;
In der wp-config.php sollte dann (relativ weit oben) eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
define(&#039;WP_REDIS_SCHEME&#039;, &#039;unix&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PATH&#039;, &#039;/home/pacs/xyz00/users/service/redis/var/redis-server.sock&#039;);&lt;br /&gt;
define(&#039;WP_REDIS_PASSWORD&#039;, &#039;topsecret&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann z.B. das Plugin &amp;quot;Redis Object Cache&amp;quot; von Till Küss installiert werden: https://de.wordpress.org/plugins/redis-cache/&lt;br /&gt;
&lt;br /&gt;
Danach lässt sich der Object Cache unter &amp;quot;Einstellungen / Redis&amp;quot; aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Seiten Cache einrichten ==&lt;br /&gt;
&lt;br /&gt;
Falls bei dem Bericht über den Zustand der Webseite dieser Eintrag erscheint: &amp;quot;Seiten-Cache wurde nicht erkannt, ...&amp;quot;, kann das Plugin WP Super Cache von Automattic installiert werden: https://wordpress.org/plugins/wp-super-cache/&lt;br /&gt;
&lt;br /&gt;
Der Cache muss dann in den Einstellungen des Plugins aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
*[https://wordpress.org/ Offizielle Webseite von Wordpress]&lt;br /&gt;
*[https://wp-cli.org/de/ WP-CLI ist das Kommandozeilen-Werkzeug für WordPress]&lt;br /&gt;
*[https://github.com/tpokorra/Hostsharing-Ansible-Wordpress Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Blog]]&lt;br /&gt;
[[Kategorie:CMS]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Speicherbelegung&amp;diff=7619</id>
		<title>Speicherbelegung</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Speicherbelegung&amp;diff=7619"/>
		<updated>2026-08-19T07:27:30Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Unvermutete Speicherbelegung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Paketspeicher ==&lt;br /&gt;
&lt;br /&gt;
Der im gesamten Paket zur Verfügung stehende bzw genutzte Speicher kann wie folgt abgefragt werden: &lt;br /&gt;
&lt;br /&gt;
Einloggen als Paketadmin &lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gruen||xyz00@h01:~$ pac-du-quota}}&lt;br /&gt;
Es wird der Speicherplatz (NVMe SSD) und der Zusatz-Speicherplatz (HDD) angezeigt.&lt;br /&gt;
&lt;br /&gt;
oder &lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gruen||xyz00@h01:~$ quota -gs}}&lt;br /&gt;
(g &amp;gt; wir nutzen Gruppenquota, s &amp;gt; für Ausgabe in MB). Die Felder bedeuten:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 0em 0em 0em 2em; font-size:1em;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:orange;&amp;quot;&lt;br /&gt;
!Feld !! Bedeutung&lt;br /&gt;
|- style=&amp;quot;background-color:#CAE1FF;&amp;quot;&lt;br /&gt;
|blocks	|| KB belegt&lt;br /&gt;
|- style=&amp;quot;background-color:#B9D3EE;&amp;quot;&lt;br /&gt;
|quota || normales (gebuchtes) Limit in KB; &amp;quot;soft quota&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#CAE1FF;&amp;quot;&lt;br /&gt;
|limit || maximales (temporär toleriertes) Limit in KB; &amp;quot;hard quota&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#B9D3EE;&amp;quot;&lt;br /&gt;
|grace || Anzahl der Tage, die man noch über &amp;quot;quota&amp;quot; bleiben darf (ist nur gesetzt, wenn blocks&amp;gt;quota)&lt;br /&gt;
|- style=&amp;quot;background-color:#CAE1FF;&amp;quot;&lt;br /&gt;
|files ||Anzahl der INodes (entspricht nicht immer, aber fast einem File. Lediglich Hardlinks verbrauchen nur einen INode pro &amp;quot;realer&amp;quot; Datei)&lt;br /&gt;
|- style=&amp;quot;background-color:#B9D3EE;&amp;quot;&lt;br /&gt;
|quota ||normales Limit der INode-Anzahl&lt;br /&gt;
|- style=&amp;quot;background-color:#CAE1FF;&amp;quot;&lt;br /&gt;
|limit ||maximales Limit der INode-Anzahl&lt;br /&gt;
|- style=&amp;quot;background-color:#B9D3EE;&amp;quot;&lt;br /&gt;
|grace || Anzahl der Tage, die man noch über &amp;quot;INode-quota&amp;quot; bleiben darf (ist nur gesetzt, wenn quota überschritten ist)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Um zu prüfen, ob ein Paket die Quota bald erreicht oder schon überschritten hat, muss man &#039;&#039;&#039;blocks&#039;&#039;&#039; mit  &#039;&#039;&#039;quota&#039;&#039;&#039; in Verhältnis setzen. Wenn &#039;&#039;&#039;blocks &amp;gt; quota&#039;&#039;&#039;, beginnt die &#039;&#039;grace period&#039;&#039;, während der ein weiterer Anstieg des Speicherverbrauchs noch toleriert wird. In jedem Fall gilt &#039;&#039;&#039;blocks &amp;lt; limit&#039;&#039;&#039;: die &amp;quot;hard quota&amp;quot; kann nicht überschritten werden und liegt z.B. bei 150% der &amp;quot;soft quota&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Der genutzte Speicher nur für den Paketadmin selbst kann mit &#039;&#039;&#039;du&#039;&#039;&#039; abgefragt werden: Einloggen als Paket-Admin und &#039;&#039;&#039;du -h&#039;&#039;&#039; eingeben. Der Befehl listet die aktuellen Größen der einzelnen Verzeichnisse auf und am Ende den gesamt belegten Plattenplatz in MB.&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gruen||&#039;&#039;&#039;Achtung:&#039;&#039;&#039; Die Auflistung (mit &#039;&#039;&#039;du&#039;&#039;&#039;) erfolgt ohne den Speicherplatz der User, für deren Verzeichnisse der Paketadmin kein Zugriffsrecht hat, ohne Dateien in /tmp/ und ohne Datenbanken!}}&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle unser Danke an die Mitglieder Andreas Loesch und Timotheus Pokorra die das hervorragende Skript &#039;pac-du-quota&#039; bereit gestellt haben.&lt;br /&gt;
&lt;br /&gt;
== Unvermutete Speicherbelegung ==&lt;br /&gt;
&lt;br /&gt;
Manchmal wunderst du dich, welche Dateien deinen Speicherplatz belegen?&lt;br /&gt;
&lt;br /&gt;
du und pac-du-quota zeigen nur die Dateien im Home Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
Manche Anwendungen legen im /tmp Verzeichnis für deinen Benutzer Dateien an.&lt;br /&gt;
&lt;br /&gt;
Diese Dateien findest du mit diesem Befehl, für deinen aktuellen Benutzer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00-meinbenutzer@hxy:~$ find /tmp/user/$UID&lt;br /&gt;
xyz00-meinbenutzer@hxy:~$ ls -lat /tmp | grep xyz00&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls eine Datei fntxyzabc heißt, kann so erfahren werden, welcher Prozess die Datei geschrieben hat:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00-meinbenutzer@hxy:~$ lsof /tmp/fntxyzabc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Warnung bei Erreichen des Quotas ==&lt;br /&gt;
&lt;br /&gt;
=== Warnungen beim Paketspeicher ===&lt;br /&gt;
&lt;br /&gt;
Wenn die Speicherbelegung (Soft- oder Hard-Quota) beim Paketspeicher überschritten wird, bekommen die dafür eingetragenen E-Mail-Adressen (siehe Ansprechpartner, OPERATIONS_ALERT) jeden Morgen eine E-Mail mit einem Warn-Hinweis.&lt;br /&gt;
&lt;br /&gt;
=== Speicherbelegung von einzelnen Benutzern prüfen ===&lt;br /&gt;
&lt;br /&gt;
Diese automatische E-Mail berücksichtigt nicht die Quotas der einzelnen Benutzer/Postfächer.&lt;br /&gt;
&lt;br /&gt;
Dafür kann das folgende Python-Skript genutzt werden: https://codeberg.org/tpokorra/hostsharing-scripts/src/branch/main/check-userquota.py&lt;br /&gt;
&lt;br /&gt;
Es sollte im bin Verzeichnis des Paketnutzers (/home/pacs/xyz00/bin) gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
Es muss mit einem Timer eingerichtet werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@h00:~$ cat .config/systemd/user/check-userquota.timer &lt;br /&gt;
[Unit]&lt;br /&gt;
Description=check user quota&lt;br /&gt;
&lt;br /&gt;
[Timer]&lt;br /&gt;
OnCalendar=00:55:00&lt;br /&gt;
RandomizedDelaySec=3 minutes&lt;br /&gt;
Persistent=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=timers.target&lt;br /&gt;
&lt;br /&gt;
xyz00@h00:~$ cat .config/systemd/user/check-userquota.service &lt;br /&gt;
[Unit]&lt;br /&gt;
Description=check user quotas&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Environment=&amp;quot;MAILTO=monitoring@meinedomain.de&amp;quot;&lt;br /&gt;
ExecStart=%h/bin/check-userquota.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aktivieren des Timers mit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user enable check-userquota.timer --now&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:Pakete bei HS]]&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Container&amp;diff=7618</id>
		<title>Container</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Container&amp;diff=7618"/>
		<updated>2026-08-19T04:39:42Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Tunnel zur Managed Datenbank einrichten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Übersicht ==&lt;br /&gt;
&lt;br /&gt;
Es gibt die Möglichkeit, einen Container Server mit Docker oder mit Podman zu buchen.&lt;br /&gt;
&lt;br /&gt;
Dies ist eine Managed Umgebung, also ohne Root-Rechte, wo Docker bzw. Podman rootless ausgeführt werden.&lt;br /&gt;
&lt;br /&gt;
Falls vom Installationsskript einer Anwendung Root-Rechte erforderlich sind, kann entweder versucht werden, dies anzupassen, oder es kann ein Cloud Server gebucht werden, wo der Benutzer Root-Rechte hat.&lt;br /&gt;
&lt;br /&gt;
== Erste Schritte ==&lt;br /&gt;
&lt;br /&gt;
Bei der Bestellung des Container Servers sollte direkt der Public SSH Key mitgegeben werden, am besten bereits nach dem Ed25519-Standard, siehe auch [https://www.heise.de/tipps-tricks/SSH-Key-erstellen-so-geht-s-4400280.html].&lt;br /&gt;
&lt;br /&gt;
Der Zugriff erfolgt über den Benutzer tallyman über SSH auf den Container Server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
ssh tallyman@vm4xxx.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um einen &amp;quot;Hello World&amp;quot; Docker Container zu starten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
tallyman@vm4xxx:~$ docker run hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Entsprechend sieht der Befehl für Podman aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
tallyman@vm4xxx:~$ podman run hello-world&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfreiche Befehle für Docker ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
# in einem Ordner ausführen, wo eine Datei mit dem Namen docker-compose.yml liegt, um die Umgebung zu bauen und zu starten:&lt;br /&gt;
docker compose up --detach&lt;br /&gt;
&lt;br /&gt;
# zeige alle laufenden Container&lt;br /&gt;
docker ps -a&lt;br /&gt;
&lt;br /&gt;
# zeige die Logs eines Containers&lt;br /&gt;
docker logs mein-container&lt;br /&gt;
&lt;br /&gt;
# wechsle in eine Shell im Container&lt;br /&gt;
docker exec -t -i mein-container /bin/sh&lt;br /&gt;
&lt;br /&gt;
# Images aktualisieren&lt;br /&gt;
docker compose pull&lt;br /&gt;
&lt;br /&gt;
# Containerumgebung stoppen und löschen&lt;br /&gt;
docker compose down&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfreiche Befehle für Podman ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
== Integration in Hostsharing Managed Platform ==&lt;br /&gt;
&lt;br /&gt;
=== Subdomain einrichten ===&lt;br /&gt;
&lt;br /&gt;
Wir haben bereits die Hauptdomain bei Hostsharing gebucht.&lt;br /&gt;
&lt;br /&gt;
Nun soll unsere Anwendung auf dem Container Server auf einer Subdomain laufen.&lt;br /&gt;
&lt;br /&gt;
Wir benutzen einen Caddy Container, um Letsencrypt bereitszustellen (siehe in den Beispielen unten).&lt;br /&gt;
&lt;br /&gt;
Auf der Managed Umgebung müssen wir das Zonefile anpassen, um die Subdomain per A und AAAA Eintrag auf den Container Server zu verweisen.&lt;br /&gt;
&lt;br /&gt;
Mit dem Befehl &amp;lt;code&amp;gt;dig&amp;lt;/code&amp;gt; ermitteln wir die ipv4 und ipv6 Adressen unseres Container Servers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
dig -t A +short vm4xxx.hostsharing.net&lt;br /&gt;
dig -t AAAA +short vm4xxx.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf der Managed Umgebung, legen wir ein Zonefile an. Siehe auch die Anleitung im Handbuch: https://www.hostsharing.net/doc/managed-operations-platform/zonefile/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doms/meinedomain.de/etc/pri.meinedomain.de&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=text&amp;gt;&lt;br /&gt;
{DEFAULT_ZONEFILE}&lt;br /&gt;
&lt;br /&gt;
meinesubdomain      IN A       83.223.xx.xxx&lt;br /&gt;
meinesubdomain      IN AAAA    2a01:xx:xxxx::xxxx:xxxx:0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tunnel zur Managed Datenbank einrichten ===&lt;br /&gt;
&lt;br /&gt;
Wir lassen die Anwendung auf dem Container Server laufen. Dort kann natürlich auch die Datenbank laufen, in einem eigenen Container.&lt;br /&gt;
&lt;br /&gt;
Wir haben aber auch Datenbanken in der Managed Umgebung von Hostsharing, mit allen Vorteilen (regelmäßiges Backup, usw.).&lt;br /&gt;
&lt;br /&gt;
Wenn wir eine managed Datenbank aus der Managed Umgebung auf dem Container Server einbinden wollen, sind folgende Schritte notwendig:&lt;br /&gt;
&lt;br /&gt;
* Es muss ein Tunnel eingerichtet werden, damit die Datenbank vom Container Server aus erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
Datei .config/systemd/user/sshtunnel.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=SSH Tunnel zu Managed Webspace&lt;br /&gt;
After=network.target&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Environment=&amp;quot;LOCAL_ADDR=localhost&amp;quot;&lt;br /&gt;
Environment=&amp;quot;LOCAL_PORT=5432&amp;quot;&lt;br /&gt;
Environment=&amp;quot;REMOTE_PORT=5432&amp;quot;&lt;br /&gt;
Environment=&amp;quot;TARGET=xyz00-myuser@xyz00.hostsharing.net&amp;quot;&lt;br /&gt;
ExecStart=/usr/bin/ssh -NT -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -L ${LOCAL_ADDR}:${LOCAL_PORT}:localhost:${REMOTE_PORT} ${TARGET}&lt;br /&gt;
&lt;br /&gt;
RestartSec=5&lt;br /&gt;
Restart=always&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=multi-user.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Dienst entsprechend starten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user enable sshtunnel --now&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* TODO: Anpassungen an Docker Compose. Beispiel&lt;br /&gt;
&lt;br /&gt;
== Docker fernsteuern ==&lt;br /&gt;
Es besteht die Möglichkeit, über SSH den Docker Socket von außen zu erreichen. Damit wird es möglich, über eine IDE wie z.B. Intellij IDEA die Docker Container zu starten und zu stoppen.&lt;br /&gt;
&lt;br /&gt;
Um das auszuprobieren, können diese Befehle ausgeführt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -nNT -L $(pwd)/docker.sock:/var/run/docker.sock tallyman@vmxxxx.hostsharing.net&lt;br /&gt;
export DOCKER_HOST=unix://$(pwd)/docker.sock&lt;br /&gt;
docker ps -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun sollten die aktuell laufenden Container gelistet werden.&lt;br /&gt;
&lt;br /&gt;
== Beispiel Anwendungen ==&lt;br /&gt;
=== Container Umgebung mit Nginx und Certbot ===&lt;br /&gt;
TODO siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/nginx-certbot&lt;br /&gt;
=== Container Umgebung mit Caddy und Python Anwendung ===&lt;br /&gt;
TODO siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/caddy-test&lt;br /&gt;
&lt;br /&gt;
=== Nextcloud High Performance Backend mit Caddy ===&lt;br /&gt;
* Docker Compose: siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/nextcloud-high_performance_backend&lt;br /&gt;
* Siehe auch dort die [https://codeberg.org/tpokorra/hs.compose/src/branch/main/nextcloud-high_performance_backend#readme README Datei], was für die Einrichtung erforderlich ist.&lt;br /&gt;
&lt;br /&gt;
=== OnlyOffice Documentserver ===&lt;br /&gt;
TODO siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/onlyoffice-document_server&lt;br /&gt;
&lt;br /&gt;
== Backups in Volumes einpflegen ==&lt;br /&gt;
&lt;br /&gt;
Auf Anfrage stellen wir einen read-only Snapshot bereit, der unter anderem Docker-Volumes, Container und Compose-Dateien enthält. &lt;br /&gt;
&lt;br /&gt;
Da Docker nicht direkt mit den User- und Gruppen-IDs des tallyman-Users arbeitet, sondern interne Sub-User- und Sub-Group-IDs verwendet, können diese Daten nicht unmittelbar zurückkopiert werden. Für die Wiederherstellung ist daher ein kurzer Zwischenschritt erforderlich.&lt;br /&gt;
&lt;br /&gt;
Hinweis: selbstverständlich helfen wir auf Anfrage auch dabei, die Dateien wieder in das laufende System zu migrieren.&lt;br /&gt;
&lt;br /&gt;
=== Beispiel: das pgdata Verzeichnis eines PostgreSQL Containers tauschen ===&lt;br /&gt;
&lt;br /&gt;
==== Wo liegt das Volume auf dem Dateisystem? ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
docker ps -a # wie lautet der Containername?&lt;br /&gt;
docker inspect --format &#039;{{ range .Mounts }}{{ if eq .Type &amp;quot;volume&amp;quot; }}{{ .Source }}{{ &amp;quot;\n&amp;quot; }}{{ end }}{{ end }}&#039; postgres-1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In unserem Fall sehen wir den Pfad: &amp;lt;code&amp;gt;/home/tallyman/.local/share/docker/volumes/8c73a862eaf1fc3dee55a2f29b6f3d3dd68e3049da58a21a5f73010e7233190c/_data&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Den betroffenen Container abschalten ====&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel entscheiden wir uns dafür, die Container vollständig zu stoppen.&lt;br /&gt;
Der Grund dafür ist, dass es je nach Image nicht immer eindeutig ist, wie der darin laufende Prozess korrekt gestoppt und wieder gestartet werden sollte.&lt;br /&gt;
&lt;br /&gt;
Alternativ könnten wir das Backup also auch direkt in das Volume kopieren und im bestehenden Container eine Shell öffnen, um die Dateien an die richtige Stelle zu verschieben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
docker ps -a # wie lautet der Containername?&lt;br /&gt;
docker stop app-1&lt;br /&gt;
docker stop postgres-1&lt;br /&gt;
&lt;br /&gt;
# oder über die Service-Namen aus der compose.yaml&lt;br /&gt;
docker compose stop app &lt;br /&gt;
docker compose stop postgres &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== In eine temporäre Subshell wechseln ====&lt;br /&gt;
Hier nutzen wir eine Abkürzung und lassen Docker einen temporären Container starten, der unseren Ordner als Volume einbindet.&lt;br /&gt;
So erhalten wir eine Shell im passenden Userid/Gruppenid-Kontext und können direkt mit den Dateien im Volume arbeiten, ohne den eigentlichen Service-Container starten, oder als root arbeiten zu müssen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
export VOL=&amp;quot;.local/share/docker/volumes&amp;quot;&lt;br /&gt;
docker run --rm -it -v &amp;quot;$VOL:/data&amp;quot; bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir wechseln nun in das oben definierte Volume. Das Beispiel geht davon aus, dass das bereitgestellte Backupverzeichnis &amp;quot;pgdata2&amp;quot; genannt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
cd data&lt;br /&gt;
mv pgdata pgdata.old&lt;br /&gt;
mv pgdata2 pgdata&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Falls wir zusätzliche Pakete brauchen, nutzt das – auf Alpine basierte – Bash image den Paketmanager `apk`. Beispiel: ncdu installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
~$ apk add ncdu&lt;br /&gt;
(1/1) Installing ncdu (1.22-r0)&lt;br /&gt;
Executing busybox-1.37.0-r30.trigger&lt;br /&gt;
OK: 8726 KiB in 20 packages&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Den Container wieder starten ====&lt;br /&gt;
&lt;br /&gt;
Wir verlassen den Container mittels &amp;lt;code&amp;gt;exit&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; oder über die Tastenkombination &amp;lt;code&amp;gt;STRG+D&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
docker start postgres-1&lt;br /&gt;
docker start app-1&lt;br /&gt;
&lt;br /&gt;
# oder über die Service-Namen aus der compose.yaml&lt;br /&gt;
docker compose start app &lt;br /&gt;
docker compose start postgres &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiel: eine Subshell mit Hilfe eine Containerprozesses starten ===&lt;br /&gt;
Für Debugging kann es nützlich sein, direkt mit allen vorinstallierten Tools im Containerserver mit Daten der Volumes zu agieren. Hier sind zwei Wege um eine Subshell ohne extra(!) Container zu starten:&lt;br /&gt;
&lt;br /&gt;
==== Mit Hilfe eines beliebigen laufenden Containers: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
docker ps&lt;br /&gt;
docker inspect --format &#039;{{.State.Pid}}&#039; app-1&lt;br /&gt;
nsenter -U -t 2586740 -- bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== TODO ====&lt;br /&gt;
Funktionierende subshell (mit nötigen Berechtigungen) mittels unshare oder nsenter&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7617</id>
		<title>Discourse installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7617"/>
		<updated>2026-08-06T09:21:20Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Erforderliche Anpassungen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Textkasten|gelb|Für Managed Server|Ein funktionierender Discourse-Server erfordert mehrere laufende Server-Dienste. Für den Betrieb ist ein Managed Server sinnvoll.}}&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|rot|Support von der Discourse-Community|Die Discourse-Entwickler haben sich entschieden, nur eine mehr oder weniger genormte Installationsmethode (via docker) zu unterstützen. Dies ist so auf der hostsharing-Architektur aufgrund mehrerer Bedenken und Überlegungen nicht möglich. Die Community ist durchaus hilfreich, geht aber davon aus, dass quasi alle Nutzer* eine &amp;quot;supported&amp;quot;e Installation durchgeführt haben. Wenn man in entsprechenden Kanälen nach Hilfe fragt, sollte man unbedingt erwähnen, dass man discourse selber anhand dieser hier lesbaren Anleitung installiert hat, um bereits entsprechenden Kommentaren und Nachfragen vorzugreifen.}}&lt;br /&gt;
&lt;br /&gt;
== Über ==&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel wird die Installation von discourse, Version 2.1.0 (September 2018) beschrieben.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von HSAdmin wird angelegt:&lt;br /&gt;
# Ein User als Service-User mit &#039;&#039;/bin/bash&#039;&#039; als Shell, zum Beispiel Beispiel: &#039;&#039;xyz00-discourse&#039;&#039;&lt;br /&gt;
# Eine Domain mit &#039;&#039;xyz00-discourse&#039; als Domain-Administrator, zum Beispiel &#039;&#039;beispiel.discussion&#039;&#039;&lt;br /&gt;
# Einen Postgresql-User &#039;&#039;xyz00_discourseuser&#039;&#039; mit Passwort &#039;&#039;meinPasswort&#039;&#039;&lt;br /&gt;
# Eine Postgresql-Datenbank &#039;&#039;xyz00_discoursedb&#039;&#039; mit Datenbank-Owner &#039;&#039;xyz00_discourseuser&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verwendete IP-Ports der Server-Dienste:&lt;br /&gt;
# Redis: localhost:32002&lt;br /&gt;
# Discourse-Web: localhost:13000&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der PostgreSQL Datenbank ==&lt;br /&gt;
&lt;br /&gt;
Es müssen noch Erweiterungen für Postgresql installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA public;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration des Redis Server ==&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gelb|Firewall/Redis Port|Leider unterstützt discourse nicht die Kommunikation mit Redis über Unix-Sockets. Dementsprechend muss der für Redis konfigurierte Port von dem hostsharing-Support in der Firewall freigegeben werden.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd&lt;br /&gt;
mkdir redis/etc redis/lib redis/log redis/run&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/redis/etc/redis.conf&#039;&#039; mit folgendem Inhalt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
daemonize no&lt;br /&gt;
pidfile /home/pacs/xyz00/users/discourse/redis/run/redis-server.pid&lt;br /&gt;
port 32002&lt;br /&gt;
tcp-backlog 128&lt;br /&gt;
bind 127.0.0.1&lt;br /&gt;
timeout 300&lt;br /&gt;
loglevel notice&lt;br /&gt;
logfile /home/pacs/xyz00/users/discourse/redis/log/redis.log&lt;br /&gt;
databases 16&lt;br /&gt;
save 900 1&lt;br /&gt;
save 300 10&lt;br /&gt;
save 60 10000&lt;br /&gt;
slave-serve-stale-data yes&lt;br /&gt;
appendonly no&lt;br /&gt;
dbfilename dump.rdb&lt;br /&gt;
dir /home/pacs/xyz00/users/discourse/redis/lib&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für Discourse 3.x gilt: &amp;quot;Discourse requires Redis 6.2.0 or up&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Für Debian Buster und Bullseye ist daher das Installieren eines neueren Binaries erforderlich. Bei Debian Bookwork ist bereits Redis 7.0 enthalten (siehe https://packages.debian.org/search?keywords=redis-server).&lt;br /&gt;
&lt;br /&gt;
Hier steht ein entsprechendes Binary für Debian Buster zur Verfügung, das mit dem Public Key von Timotheus geprüft werden kann:&lt;br /&gt;
&lt;br /&gt;
* https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
* Prüfsignatur: https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz.sig&lt;br /&gt;
&lt;br /&gt;
Prüfen der Signatur:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gpg --verify redis-server-6.2.12-debian-buster.tar.gz.sig redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Binary muss nach &amp;lt;code&amp;gt;$HOME/bin&amp;lt;/code&amp;gt; verschoben werden, und entsprechend beim Starten des Dienstes eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
== Installation von Ruby ==&lt;br /&gt;
&lt;br /&gt;
Als User &#039;&#039;xyz00-discourse&#039;&#039;:  Installation von Ruby mit &#039;&#039;rbenv&#039;&#039; mit folgenden Befehlen:&lt;br /&gt;
&lt;br /&gt;
Zunächst &#039;&#039;rbenv&#039;&#039; and &#039;&#039;ruby-build&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/rbenv.git ~/.rbenv&lt;br /&gt;
cd ~/.rbenv &amp;amp;&amp;amp; src/configure &amp;amp;&amp;amp; make -C src&lt;br /&gt;
echo &#039;export PATH=&amp;quot;$HOME/.rbenv/bin:$PATH&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
echo &#039;eval &amp;quot;$(rbenv init -)&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
starte neue Shell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
exec bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Überprüfe rbenv-Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
type rbenv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installiere ruby-build als rbenv-Plugin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun kann die benötigte Ruby-Version installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
rbenv install 2.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation von Discourse selber ==&lt;br /&gt;
&lt;br /&gt;
Weiterhin Als User &#039;&#039;xyz00-discourse&#039;&#039;:  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~&lt;br /&gt;
git clone https://github.com/discourse/discourse.git discourse&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die stabile Version auschecken:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git checkout stable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ruby Pakete installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gem install bundler&lt;br /&gt;
bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without development test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der Discourse Software ==&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/discourse/config/discourse.conf&#039;&#039; anhand der Beispiel-Datei:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
cp config/discourse_defaults.conf config/discourse.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anpassen folgender Inhalte:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
db_host = 127.0.0.1&lt;br /&gt;
db_port = 5432&lt;br /&gt;
#db_backup_port = 5432 #(auskommentieren)&lt;br /&gt;
db_name = xyz00_discoursedb&lt;br /&gt;
db_username = xyz00_discourseuser&lt;br /&gt;
db_password = &amp;quot;&amp;quot; #db password&lt;br /&gt;
hostname = &amp;quot;discourse.xyz00&amp;quot; # hostname&lt;br /&gt;
smtp_address = localhost&lt;br /&gt;
smtp_enable_start_tls = false&lt;br /&gt;
smtp_openssl_verify_mode = &#039;none&#039;&lt;br /&gt;
developer_emails = # your email-address&lt;br /&gt;
redis_host = 127.0.0.1&lt;br /&gt;
redis_port = 32002&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===TODO: Secrets setzen! ===&lt;br /&gt;
Die Zufallswerte für die Variablen SECRET_KEY_BASE und OTP_SECRET erzeugt man durch zwei Aufrufe des Kommandos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rake secret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq für Hintergrund-Aufgaben konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;config/sidekiq.conf&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wichtig: development auf production ändern.&lt;br /&gt;
&lt;br /&gt;
Mit diesem Dienst werden z.B. die E-Mails zur Aktivierung oder zum Passwort Reset verschickt.&lt;br /&gt;
&lt;br /&gt;
=== Problem mit Content Security Policy ===&lt;br /&gt;
&lt;br /&gt;
Um ein Problem mit Content Security Policy zu lösen, weil manche Dateien über http nachgeladen werden, muss in der Datei &amp;lt;code&amp;gt;config/site_settings.yml&amp;lt;/code&amp;gt; der Default Wert für force_https auf True gesetzt werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
force_https:&lt;br /&gt;
    default: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Problem beim Aufsetzen der Datenbank vermeiden ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;→ Notiz Mai 2024:&#039;&#039;&#039; dies scheint aktuell nicht aufzutreten. &lt;br /&gt;
&lt;br /&gt;
Aus irgendeinem Grund wird beim Initialisieren der Datenbank versucht, den TYPE hotlinked_media_status zweimal in der Datenbank anzulegen. Der Grund ist nicht ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Es kann folgende Änderung an der Datei &amp;lt;code&amp;gt;db/migrate/20220428094026_create_post_hotlinked_media.rb&amp;lt;/code&amp;gt; vorgenommen werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
reversible do |dir|&lt;br /&gt;
  dir.up { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DO $$ BEGIN CREATE TYPE hotlinked_media_status AS ENUM(&#039;downloaded&#039;, &#039;too_large&#039;, &#039;download_failed&#039;, &#039;upload_create_failed&#039;); EXCEPTION WHEN duplicate_object THEN null; END $$;&lt;br /&gt;
    SQL&lt;br /&gt;
  dir.down { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DROP TYPE hotlinked_media_status&lt;br /&gt;
    SQL&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Initialisieren der Datenbank ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
export SAFETY_ASSURED=1&lt;br /&gt;
# In Version 2.0.4 funktioniert db:migrate noch, ansonsten db:schema:load und seed nutzen!&lt;br /&gt;
# In Version 3.0.3 funktioniert db:migrate auch noch, db:schema:load ging nicht weil die Datei structure.sql fehlte&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:schema:load&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:seed&lt;br /&gt;
RAILS_ENV=production bundle exec rails db:migrate&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kompilieren der Assets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rails assets:precompile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration des Web-Servers (am Beispiel Puma)  ===&lt;br /&gt;
&lt;br /&gt;
Die Datei &#039;&#039;config/puma.conf&#039;&#039; anpassen (hier nur Änderungen angezeigt):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini&amp;gt;&lt;br /&gt;
APP_ROOT = &#039;/home/pacs/xyz00/users/discourse/discourse&#039;&lt;br /&gt;
daemonize false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starten der Dienste  ==&lt;br /&gt;
&lt;br /&gt;
Zum Start aller notwendigen Dienste sollte systemd benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Dateien müssen nach &amp;lt;code&amp;gt;.config/systemd/user/&amp;lt;/code&amp;gt; kopiert werden (überlange Zeilen werden hier im Wiki umgebrochen)&lt;br /&gt;
&lt;br /&gt;
redis.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Redis User Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/var/redis&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
ExecStart=%h/bin/redis-server %h/etc/redis.conf&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sidekiq.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Sidekiq Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;DB_POOL=8&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec sidekiq -C %h/discourse/config/sidekiq.yml&lt;br /&gt;
StandardOutput=append:%h/var/log/sidekiq.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
discourse.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Web Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;WEB_CONCURRENCY=2&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MAX_THREADS=5&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec puma -C config/puma.rb -e production -b tcp://127.0.0.1:13000&lt;br /&gt;
StandardOutput=append:%h/var/log/puma.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einrichten des Apache VHost ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/doms/beispiel.discuss&lt;br /&gt;
rm -rf htdocs-ssl subs/www subs-ssl/www&lt;br /&gt;
ln -s ~/live/public htdocs-ssl&lt;br /&gt;
touch htdocs-ssl/.htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann die &#039;&#039;htdocs-ssl/.htaccess&#039;&#039; (durch das gelinkte Verzeichnis entspricht das dem Pfad /home/pacs/xyz00/users/discourse/discourse/public/.htaccess ) mit dem Editor der Wahl öffnen und folgende Konfiguration einfügen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
  &lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RewriteRule .* http://127.0.0.1:13000%{REQUEST_URI} [proxy,last]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wartung ==&lt;br /&gt;
=== Backup ===&lt;br /&gt;
&lt;br /&gt;
Discourse macht selbstätig backups und legt diese unter &#039;public/backups&#039; ab. Enthalten ist ein Datenbank-Dump und die hochgeladenen Dateien.&lt;br /&gt;
&lt;br /&gt;
Im Admin-Bereich lassen sich backups auch manuell antreten.&lt;br /&gt;
&lt;br /&gt;
=== Admin Benutzer einladen ===&lt;br /&gt;
&lt;br /&gt;
Manchmal brauchen wir einen neuen Admin Benutzer, den wir von der Kommandozeile aus einladen möchten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd /discourse&lt;br /&gt;
RAILS_ENV=production rake admin:invite[admin@example.org]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Import aus mbox Archiven ===&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel ein Mailman2 Archiv zu importieren, wo die Nachrichten als .mbox Datei vorliegen, sind folgende Schritte nötig:&lt;br /&gt;
&lt;br /&gt;
Vorbereitungen an Discourse:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
bundle config set frozen false&lt;br /&gt;
IMPORT=1 bundle install&lt;br /&gt;
bundle config set frozen true&lt;br /&gt;
nano script/import_scripts/mbox/settings.yml&lt;br /&gt;
#  dort ändern:&lt;br /&gt;
#    data_dir: /home/pacs/xyz00/users/discourse/list-archiv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hochladen der Mailinglisten-Archive:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/list-archiv&lt;br /&gt;
# dort muss es Unterordner mit dem Namen der gewünschten Kategorie geben,&lt;br /&gt;
# und die mbox Datei muss auch diesen Namen haben, z.B.:&lt;br /&gt;
# ~/list-archiv/beispiel/beispiel.mbox&lt;br /&gt;
# ~/list-archiv/example/example.mbox&lt;br /&gt;
# um die Beiträge in den entsprechenden Kategorien beispiel und example einzufügen.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durchführen des Imports:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
RAILS_ENV=production IMPORT=1 bundle exec rails runner \&lt;br /&gt;
    script/import_scripts/mbox.rb script/import_scripts/mbox/settings.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Export ===&lt;br /&gt;
* Wenn ein Forum beendet wird, möchte man evtl. eine Sicherung als statische HTML Seiten. &lt;br /&gt;
** Das wird hier diskutiert: https://meta.discourse.org/t/how-do-i-export-the-complete-forum-as-static-html-pages/71007/3&lt;br /&gt;
* Um ein Forum von Discourse zu Flarum umzuziehen, hat Timotheus ein Skript geschrieben.&lt;br /&gt;
** Das Migrations-Skript: https://github.com/SolidCharity/discourse_to_flarum&lt;br /&gt;
** siehe auch https://discuss.flarum.org/d/4930-discourse-to-flarum-migration-support/29&lt;br /&gt;
&lt;br /&gt;
=== Updates ===&lt;br /&gt;
&lt;br /&gt;
Discourse wird über update via mail informieren (dies kann man m.W. abschalten).&lt;br /&gt;
&lt;br /&gt;
Achtung: bei größeren Updates auch immer Änderungen an der Datei site_settings.yml (https://github.com/discourse/discourse/blob/main/config/site_settings.yml) beachten!&lt;br /&gt;
&lt;br /&gt;
Siehe auch die unterstützten Releases: https://releases.discourse.org/ und die Tags: https://github.com/discourse/discourse/tags&lt;br /&gt;
&lt;br /&gt;
==== Am Beispiel von 2026.1.5 auf 2026.1.7 ====&lt;br /&gt;
&lt;br /&gt;
# Im Web-Backend unter Administration-&amp;gt;Backups-&amp;gt; Read-Only Mouds setzen (oder Web Server so konfigurieren, dass keine Zugriffe mehr stattfinden können)&lt;br /&gt;
# Backup&lt;br /&gt;
# Die lokalen Änderungen sichern:&lt;br /&gt;
# cd discourse&lt;br /&gt;
# mv ~/plugins.bak/discourse-ai plugins&lt;br /&gt;
# git diff v2026.1.5 &amp;gt; diff-2026.1.5.txt&lt;br /&gt;
# git fetch&lt;br /&gt;
# git checkout -b hostsharing-deployment-v2026.1.7 v2026.1.7&lt;br /&gt;
# evtl. Änderungen aus diff-2026.1.5.txt wieder übernehmen und committen&lt;br /&gt;
# patch -p1 &amp;lt; diff-2026.1.5.txt&lt;br /&gt;
# git commit -a -m &amp;quot;spezifische Änderungen für diese Instanz&amp;quot; --no-verify&lt;br /&gt;
# Schauen, ob discourse eine neue Ruby-Version nutzt (z.B. in https://github.com/discourse/discourse_docker/blob/main/image/base/Dockerfile bzw. https://github.com/discourse/discourse/blob/v2026.1.7/Gemfile)&lt;br /&gt;
# Ist dies der Fall, dann:&lt;br /&gt;
# rbenv install 3.3.8&lt;br /&gt;
# rbenv global 3.3.8&lt;br /&gt;
# rbenv rehash&lt;br /&gt;
# echo &amp;quot;3.3.8&amp;quot; &amp;gt; .ruby-version&lt;br /&gt;
# installiere Node 22: https://codeberg.org/tpokorra/hostsharing-scripts/src/branch/main/install-nodejs.sh&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# gem update --system&lt;br /&gt;
# bundle install&lt;br /&gt;
# npm install -g terser uglify-js pnpm@10&lt;br /&gt;
#&lt;br /&gt;
# to avoid this error: ERR_PNPM_INVALID_DEPENDENCY_NAME  The current package contains a dependency with an invalid name: &amp;quot;@types/@glimmer__component&amp;quot;&lt;br /&gt;
# vi frontend/discourse-types/package.json&lt;br /&gt;
&lt;br /&gt;
 -    &amp;quot;@types/@glimmer__component&amp;quot;: &amp;quot;npm:@glimmer/component@^2.0.0&amp;quot;,&lt;br /&gt;
 -    &amp;quot;@types/@glint__ember-tsc&amp;quot;: &amp;quot;npm:@glint/ember-tsc@^1.0.7&amp;quot;,&lt;br /&gt;
 -    &amp;quot;@types/@glint__template&amp;quot;: &amp;quot;npm:@glint/template@^1.7.2&amp;quot;&lt;br /&gt;
 +    &amp;quot;@types/glimmer__component&amp;quot;: &amp;quot;npm:@glimmer/component@^2.0.0&amp;quot;,&lt;br /&gt;
 +    &amp;quot;@types/glint__ember-tsc&amp;quot;: &amp;quot;npm:@glint/ember-tsc@^1.0.7&amp;quot;,&lt;br /&gt;
 +    &amp;quot;@types/glint__template&amp;quot;: &amp;quot;npm:@glint/template@^1.7.2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# corepack use pnpm@latest-10&lt;br /&gt;
# pnpm install&lt;br /&gt;
# export $(grep -v &#039;^#&#039; ~/discourse.env | xargs -d &#039;\n&#039;)&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# Falls die pg extension pg_vector nicht installiert ist: deaktiviere das Plugin während migrate, aber auch für später damit /admin/settings funktioniert (ansonsten in salt pillar pg_vector installieren, und als postgres user: create extension vector;)&lt;br /&gt;
## mkdir -p ~/plugins.bak&lt;br /&gt;
## mv plugins/discourse-ai ~/plugins.bak&lt;br /&gt;
# RAILS_ENV=production bundle exec rake db:migrate&lt;br /&gt;
# RAILS_ENV=production bundle exec rake assets:precompile&lt;br /&gt;
# Services neu starten&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user restart puma&lt;br /&gt;
systemctl --user restart sidekiq&lt;br /&gt;
systemctl --user restart redis&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zuletzt: Read-Only Modus wieder deaktivieren&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
&lt;br /&gt;
Es können folgende Einstellungen in der Datei config/environments/production.rb vorgenommen werden. Danach den Puma Dienst neustarten. Fehlermeldungen und Stacktraces werden dann im Browser ausgegeben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
config.log_level = :debug&lt;br /&gt;
config.action_dispatch.show_exceptions = :all&lt;br /&gt;
config.action_dispatch.debug_exception_log_level = :error&lt;br /&gt;
&lt;br /&gt;
# Full error reports are enabled and caching is turned off&lt;br /&gt;
config.consider_all_requests_local = true&lt;br /&gt;
config.action_controller.perform_caching = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erforderliche Anpassungen ===&lt;br /&gt;
Weil wir bei Debian Bookworm noch mit ImageMagick 6.9 arbeiten, muss dieser [https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119 Patch] rückgängig gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line&amp;gt;&lt;br /&gt;
wget https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119.patch -O ~/imagemagick.patch&lt;br /&gt;
patch -p1 --reverse &amp;lt; ~/imagemagick.patch&lt;br /&gt;
git commit -a -m &amp;quot;revert imagemagick patch&amp;quot;  --no-verify&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update: es hat sich wieder mehr im Code verändert. Bitte den Patch von https://codeberg.org/tpokorra/hs.ansible/src/branch/main/roles/apps/discourse/templates/imagemagick.patch benutzen!&lt;br /&gt;
&lt;br /&gt;
== ToDos ==&lt;br /&gt;
&lt;br /&gt;
* Ein Patch, um Discourse auch via Unix-Socket mit Redis sprechen lassen zu können dürfte relativ einfach sein (es wird ein Wrapper um das redis-gem genutzt).&lt;br /&gt;
* Konfiguration von discourse, um mit postgresql via Unix-Socket zu kommunizieren (DISCOURSE_DB_SOCKET environment variable)&lt;br /&gt;
* Performance-tuning an diversen Stellen, anhand der discourse_docker-Vorgaben (https://github.com/discourse/discourse_docker), z.B.&lt;br /&gt;
** thpoff (huge page settings)&lt;br /&gt;
** unicorn (hat eine wesentlich ausgefeiltere Konfigurations-Vorlage, wahrscheinlich bereits ordentlich optimiert)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://help.skysilk.com/support/solutions/articles/9000120927-how-to-install-discourse-without-docker-using-skysilk-vps-&lt;br /&gt;
* https://github.com/discourse/discourse_docker&lt;br /&gt;
* https://github.com/discourse/discourse&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/discourse&lt;br /&gt;
&lt;br /&gt;
== Historie ==&lt;br /&gt;
&lt;br /&gt;
* 2018, 14 . September: Initiale Fassung&lt;br /&gt;
* 2019, Januar: Update-Informationen ergänzt&lt;br /&gt;
* 2022, Juni: systemd Dienste, Discourse 3.0&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:RubyOnRails]]&lt;br /&gt;
[[Kategorie:Webforen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7616</id>
		<title>Discourse installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7616"/>
		<updated>2026-08-06T08:59:12Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Am Beispiel von 2026.1.5 auf 2026.1.7 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Textkasten|gelb|Für Managed Server|Ein funktionierender Discourse-Server erfordert mehrere laufende Server-Dienste. Für den Betrieb ist ein Managed Server sinnvoll.}}&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|rot|Support von der Discourse-Community|Die Discourse-Entwickler haben sich entschieden, nur eine mehr oder weniger genormte Installationsmethode (via docker) zu unterstützen. Dies ist so auf der hostsharing-Architektur aufgrund mehrerer Bedenken und Überlegungen nicht möglich. Die Community ist durchaus hilfreich, geht aber davon aus, dass quasi alle Nutzer* eine &amp;quot;supported&amp;quot;e Installation durchgeführt haben. Wenn man in entsprechenden Kanälen nach Hilfe fragt, sollte man unbedingt erwähnen, dass man discourse selber anhand dieser hier lesbaren Anleitung installiert hat, um bereits entsprechenden Kommentaren und Nachfragen vorzugreifen.}}&lt;br /&gt;
&lt;br /&gt;
== Über ==&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel wird die Installation von discourse, Version 2.1.0 (September 2018) beschrieben.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von HSAdmin wird angelegt:&lt;br /&gt;
# Ein User als Service-User mit &#039;&#039;/bin/bash&#039;&#039; als Shell, zum Beispiel Beispiel: &#039;&#039;xyz00-discourse&#039;&#039;&lt;br /&gt;
# Eine Domain mit &#039;&#039;xyz00-discourse&#039; als Domain-Administrator, zum Beispiel &#039;&#039;beispiel.discussion&#039;&#039;&lt;br /&gt;
# Einen Postgresql-User &#039;&#039;xyz00_discourseuser&#039;&#039; mit Passwort &#039;&#039;meinPasswort&#039;&#039;&lt;br /&gt;
# Eine Postgresql-Datenbank &#039;&#039;xyz00_discoursedb&#039;&#039; mit Datenbank-Owner &#039;&#039;xyz00_discourseuser&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verwendete IP-Ports der Server-Dienste:&lt;br /&gt;
# Redis: localhost:32002&lt;br /&gt;
# Discourse-Web: localhost:13000&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der PostgreSQL Datenbank ==&lt;br /&gt;
&lt;br /&gt;
Es müssen noch Erweiterungen für Postgresql installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA public;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration des Redis Server ==&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gelb|Firewall/Redis Port|Leider unterstützt discourse nicht die Kommunikation mit Redis über Unix-Sockets. Dementsprechend muss der für Redis konfigurierte Port von dem hostsharing-Support in der Firewall freigegeben werden.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd&lt;br /&gt;
mkdir redis/etc redis/lib redis/log redis/run&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/redis/etc/redis.conf&#039;&#039; mit folgendem Inhalt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
daemonize no&lt;br /&gt;
pidfile /home/pacs/xyz00/users/discourse/redis/run/redis-server.pid&lt;br /&gt;
port 32002&lt;br /&gt;
tcp-backlog 128&lt;br /&gt;
bind 127.0.0.1&lt;br /&gt;
timeout 300&lt;br /&gt;
loglevel notice&lt;br /&gt;
logfile /home/pacs/xyz00/users/discourse/redis/log/redis.log&lt;br /&gt;
databases 16&lt;br /&gt;
save 900 1&lt;br /&gt;
save 300 10&lt;br /&gt;
save 60 10000&lt;br /&gt;
slave-serve-stale-data yes&lt;br /&gt;
appendonly no&lt;br /&gt;
dbfilename dump.rdb&lt;br /&gt;
dir /home/pacs/xyz00/users/discourse/redis/lib&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für Discourse 3.x gilt: &amp;quot;Discourse requires Redis 6.2.0 or up&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Für Debian Buster und Bullseye ist daher das Installieren eines neueren Binaries erforderlich. Bei Debian Bookwork ist bereits Redis 7.0 enthalten (siehe https://packages.debian.org/search?keywords=redis-server).&lt;br /&gt;
&lt;br /&gt;
Hier steht ein entsprechendes Binary für Debian Buster zur Verfügung, das mit dem Public Key von Timotheus geprüft werden kann:&lt;br /&gt;
&lt;br /&gt;
* https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
* Prüfsignatur: https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz.sig&lt;br /&gt;
&lt;br /&gt;
Prüfen der Signatur:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gpg --verify redis-server-6.2.12-debian-buster.tar.gz.sig redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Binary muss nach &amp;lt;code&amp;gt;$HOME/bin&amp;lt;/code&amp;gt; verschoben werden, und entsprechend beim Starten des Dienstes eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
== Installation von Ruby ==&lt;br /&gt;
&lt;br /&gt;
Als User &#039;&#039;xyz00-discourse&#039;&#039;:  Installation von Ruby mit &#039;&#039;rbenv&#039;&#039; mit folgenden Befehlen:&lt;br /&gt;
&lt;br /&gt;
Zunächst &#039;&#039;rbenv&#039;&#039; and &#039;&#039;ruby-build&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/rbenv.git ~/.rbenv&lt;br /&gt;
cd ~/.rbenv &amp;amp;&amp;amp; src/configure &amp;amp;&amp;amp; make -C src&lt;br /&gt;
echo &#039;export PATH=&amp;quot;$HOME/.rbenv/bin:$PATH&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
echo &#039;eval &amp;quot;$(rbenv init -)&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
starte neue Shell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
exec bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Überprüfe rbenv-Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
type rbenv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installiere ruby-build als rbenv-Plugin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun kann die benötigte Ruby-Version installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
rbenv install 2.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation von Discourse selber ==&lt;br /&gt;
&lt;br /&gt;
Weiterhin Als User &#039;&#039;xyz00-discourse&#039;&#039;:  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~&lt;br /&gt;
git clone https://github.com/discourse/discourse.git discourse&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die stabile Version auschecken:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git checkout stable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ruby Pakete installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gem install bundler&lt;br /&gt;
bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without development test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der Discourse Software ==&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/discourse/config/discourse.conf&#039;&#039; anhand der Beispiel-Datei:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
cp config/discourse_defaults.conf config/discourse.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anpassen folgender Inhalte:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
db_host = 127.0.0.1&lt;br /&gt;
db_port = 5432&lt;br /&gt;
#db_backup_port = 5432 #(auskommentieren)&lt;br /&gt;
db_name = xyz00_discoursedb&lt;br /&gt;
db_username = xyz00_discourseuser&lt;br /&gt;
db_password = &amp;quot;&amp;quot; #db password&lt;br /&gt;
hostname = &amp;quot;discourse.xyz00&amp;quot; # hostname&lt;br /&gt;
smtp_address = localhost&lt;br /&gt;
smtp_enable_start_tls = false&lt;br /&gt;
smtp_openssl_verify_mode = &#039;none&#039;&lt;br /&gt;
developer_emails = # your email-address&lt;br /&gt;
redis_host = 127.0.0.1&lt;br /&gt;
redis_port = 32002&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===TODO: Secrets setzen! ===&lt;br /&gt;
Die Zufallswerte für die Variablen SECRET_KEY_BASE und OTP_SECRET erzeugt man durch zwei Aufrufe des Kommandos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rake secret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq für Hintergrund-Aufgaben konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;config/sidekiq.conf&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wichtig: development auf production ändern.&lt;br /&gt;
&lt;br /&gt;
Mit diesem Dienst werden z.B. die E-Mails zur Aktivierung oder zum Passwort Reset verschickt.&lt;br /&gt;
&lt;br /&gt;
=== Problem mit Content Security Policy ===&lt;br /&gt;
&lt;br /&gt;
Um ein Problem mit Content Security Policy zu lösen, weil manche Dateien über http nachgeladen werden, muss in der Datei &amp;lt;code&amp;gt;config/site_settings.yml&amp;lt;/code&amp;gt; der Default Wert für force_https auf True gesetzt werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
force_https:&lt;br /&gt;
    default: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Problem beim Aufsetzen der Datenbank vermeiden ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;→ Notiz Mai 2024:&#039;&#039;&#039; dies scheint aktuell nicht aufzutreten. &lt;br /&gt;
&lt;br /&gt;
Aus irgendeinem Grund wird beim Initialisieren der Datenbank versucht, den TYPE hotlinked_media_status zweimal in der Datenbank anzulegen. Der Grund ist nicht ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Es kann folgende Änderung an der Datei &amp;lt;code&amp;gt;db/migrate/20220428094026_create_post_hotlinked_media.rb&amp;lt;/code&amp;gt; vorgenommen werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
reversible do |dir|&lt;br /&gt;
  dir.up { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DO $$ BEGIN CREATE TYPE hotlinked_media_status AS ENUM(&#039;downloaded&#039;, &#039;too_large&#039;, &#039;download_failed&#039;, &#039;upload_create_failed&#039;); EXCEPTION WHEN duplicate_object THEN null; END $$;&lt;br /&gt;
    SQL&lt;br /&gt;
  dir.down { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DROP TYPE hotlinked_media_status&lt;br /&gt;
    SQL&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Initialisieren der Datenbank ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
export SAFETY_ASSURED=1&lt;br /&gt;
# In Version 2.0.4 funktioniert db:migrate noch, ansonsten db:schema:load und seed nutzen!&lt;br /&gt;
# In Version 3.0.3 funktioniert db:migrate auch noch, db:schema:load ging nicht weil die Datei structure.sql fehlte&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:schema:load&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:seed&lt;br /&gt;
RAILS_ENV=production bundle exec rails db:migrate&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kompilieren der Assets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rails assets:precompile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration des Web-Servers (am Beispiel Puma)  ===&lt;br /&gt;
&lt;br /&gt;
Die Datei &#039;&#039;config/puma.conf&#039;&#039; anpassen (hier nur Änderungen angezeigt):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini&amp;gt;&lt;br /&gt;
APP_ROOT = &#039;/home/pacs/xyz00/users/discourse/discourse&#039;&lt;br /&gt;
daemonize false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starten der Dienste  ==&lt;br /&gt;
&lt;br /&gt;
Zum Start aller notwendigen Dienste sollte systemd benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Dateien müssen nach &amp;lt;code&amp;gt;.config/systemd/user/&amp;lt;/code&amp;gt; kopiert werden (überlange Zeilen werden hier im Wiki umgebrochen)&lt;br /&gt;
&lt;br /&gt;
redis.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Redis User Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/var/redis&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
ExecStart=%h/bin/redis-server %h/etc/redis.conf&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sidekiq.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Sidekiq Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;DB_POOL=8&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec sidekiq -C %h/discourse/config/sidekiq.yml&lt;br /&gt;
StandardOutput=append:%h/var/log/sidekiq.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
discourse.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Web Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;WEB_CONCURRENCY=2&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MAX_THREADS=5&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec puma -C config/puma.rb -e production -b tcp://127.0.0.1:13000&lt;br /&gt;
StandardOutput=append:%h/var/log/puma.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einrichten des Apache VHost ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/doms/beispiel.discuss&lt;br /&gt;
rm -rf htdocs-ssl subs/www subs-ssl/www&lt;br /&gt;
ln -s ~/live/public htdocs-ssl&lt;br /&gt;
touch htdocs-ssl/.htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann die &#039;&#039;htdocs-ssl/.htaccess&#039;&#039; (durch das gelinkte Verzeichnis entspricht das dem Pfad /home/pacs/xyz00/users/discourse/discourse/public/.htaccess ) mit dem Editor der Wahl öffnen und folgende Konfiguration einfügen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
  &lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RewriteRule .* http://127.0.0.1:13000%{REQUEST_URI} [proxy,last]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wartung ==&lt;br /&gt;
=== Backup ===&lt;br /&gt;
&lt;br /&gt;
Discourse macht selbstätig backups und legt diese unter &#039;public/backups&#039; ab. Enthalten ist ein Datenbank-Dump und die hochgeladenen Dateien.&lt;br /&gt;
&lt;br /&gt;
Im Admin-Bereich lassen sich backups auch manuell antreten.&lt;br /&gt;
&lt;br /&gt;
=== Admin Benutzer einladen ===&lt;br /&gt;
&lt;br /&gt;
Manchmal brauchen wir einen neuen Admin Benutzer, den wir von der Kommandozeile aus einladen möchten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd /discourse&lt;br /&gt;
RAILS_ENV=production rake admin:invite[admin@example.org]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Import aus mbox Archiven ===&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel ein Mailman2 Archiv zu importieren, wo die Nachrichten als .mbox Datei vorliegen, sind folgende Schritte nötig:&lt;br /&gt;
&lt;br /&gt;
Vorbereitungen an Discourse:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
bundle config set frozen false&lt;br /&gt;
IMPORT=1 bundle install&lt;br /&gt;
bundle config set frozen true&lt;br /&gt;
nano script/import_scripts/mbox/settings.yml&lt;br /&gt;
#  dort ändern:&lt;br /&gt;
#    data_dir: /home/pacs/xyz00/users/discourse/list-archiv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hochladen der Mailinglisten-Archive:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/list-archiv&lt;br /&gt;
# dort muss es Unterordner mit dem Namen der gewünschten Kategorie geben,&lt;br /&gt;
# und die mbox Datei muss auch diesen Namen haben, z.B.:&lt;br /&gt;
# ~/list-archiv/beispiel/beispiel.mbox&lt;br /&gt;
# ~/list-archiv/example/example.mbox&lt;br /&gt;
# um die Beiträge in den entsprechenden Kategorien beispiel und example einzufügen.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durchführen des Imports:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
RAILS_ENV=production IMPORT=1 bundle exec rails runner \&lt;br /&gt;
    script/import_scripts/mbox.rb script/import_scripts/mbox/settings.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Export ===&lt;br /&gt;
* Wenn ein Forum beendet wird, möchte man evtl. eine Sicherung als statische HTML Seiten. &lt;br /&gt;
** Das wird hier diskutiert: https://meta.discourse.org/t/how-do-i-export-the-complete-forum-as-static-html-pages/71007/3&lt;br /&gt;
* Um ein Forum von Discourse zu Flarum umzuziehen, hat Timotheus ein Skript geschrieben.&lt;br /&gt;
** Das Migrations-Skript: https://github.com/SolidCharity/discourse_to_flarum&lt;br /&gt;
** siehe auch https://discuss.flarum.org/d/4930-discourse-to-flarum-migration-support/29&lt;br /&gt;
&lt;br /&gt;
=== Updates ===&lt;br /&gt;
&lt;br /&gt;
Discourse wird über update via mail informieren (dies kann man m.W. abschalten).&lt;br /&gt;
&lt;br /&gt;
Achtung: bei größeren Updates auch immer Änderungen an der Datei site_settings.yml (https://github.com/discourse/discourse/blob/main/config/site_settings.yml) beachten!&lt;br /&gt;
&lt;br /&gt;
Siehe auch die unterstützten Releases: https://releases.discourse.org/ und die Tags: https://github.com/discourse/discourse/tags&lt;br /&gt;
&lt;br /&gt;
==== Am Beispiel von 2026.1.5 auf 2026.1.7 ====&lt;br /&gt;
&lt;br /&gt;
# Im Web-Backend unter Administration-&amp;gt;Backups-&amp;gt; Read-Only Mouds setzen (oder Web Server so konfigurieren, dass keine Zugriffe mehr stattfinden können)&lt;br /&gt;
# Backup&lt;br /&gt;
# Die lokalen Änderungen sichern:&lt;br /&gt;
# cd discourse&lt;br /&gt;
# mv ~/plugins.bak/discourse-ai plugins&lt;br /&gt;
# git diff v2026.1.5 &amp;gt; diff-2026.1.5.txt&lt;br /&gt;
# git fetch&lt;br /&gt;
# git checkout -b hostsharing-deployment-v2026.1.7 v2026.1.7&lt;br /&gt;
# evtl. Änderungen aus diff-2026.1.5.txt wieder übernehmen und committen&lt;br /&gt;
# patch -p1 &amp;lt; diff-2026.1.5.txt&lt;br /&gt;
# git commit -a -m &amp;quot;spezifische Änderungen für diese Instanz&amp;quot; --no-verify&lt;br /&gt;
# Schauen, ob discourse eine neue Ruby-Version nutzt (z.B. in https://github.com/discourse/discourse_docker/blob/main/image/base/Dockerfile bzw. https://github.com/discourse/discourse/blob/v2026.1.7/Gemfile)&lt;br /&gt;
# Ist dies der Fall, dann:&lt;br /&gt;
# rbenv install 3.3.8&lt;br /&gt;
# rbenv global 3.3.8&lt;br /&gt;
# rbenv rehash&lt;br /&gt;
# echo &amp;quot;3.3.8&amp;quot; &amp;gt; .ruby-version&lt;br /&gt;
# installiere Node 22: https://codeberg.org/tpokorra/hostsharing-scripts/src/branch/main/install-nodejs.sh&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# gem update --system&lt;br /&gt;
# bundle install&lt;br /&gt;
# npm install -g terser uglify-js pnpm@10&lt;br /&gt;
#&lt;br /&gt;
# to avoid this error: ERR_PNPM_INVALID_DEPENDENCY_NAME  The current package contains a dependency with an invalid name: &amp;quot;@types/@glimmer__component&amp;quot;&lt;br /&gt;
# vi frontend/discourse-types/package.json&lt;br /&gt;
&lt;br /&gt;
 -    &amp;quot;@types/@glimmer__component&amp;quot;: &amp;quot;npm:@glimmer/component@^2.0.0&amp;quot;,&lt;br /&gt;
 -    &amp;quot;@types/@glint__ember-tsc&amp;quot;: &amp;quot;npm:@glint/ember-tsc@^1.0.7&amp;quot;,&lt;br /&gt;
 -    &amp;quot;@types/@glint__template&amp;quot;: &amp;quot;npm:@glint/template@^1.7.2&amp;quot;&lt;br /&gt;
 +    &amp;quot;@types/glimmer__component&amp;quot;: &amp;quot;npm:@glimmer/component@^2.0.0&amp;quot;,&lt;br /&gt;
 +    &amp;quot;@types/glint__ember-tsc&amp;quot;: &amp;quot;npm:@glint/ember-tsc@^1.0.7&amp;quot;,&lt;br /&gt;
 +    &amp;quot;@types/glint__template&amp;quot;: &amp;quot;npm:@glint/template@^1.7.2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# corepack use pnpm@latest-10&lt;br /&gt;
# pnpm install&lt;br /&gt;
# export $(grep -v &#039;^#&#039; ~/discourse.env | xargs -d &#039;\n&#039;)&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# Falls die pg extension pg_vector nicht installiert ist: deaktiviere das Plugin während migrate, aber auch für später damit /admin/settings funktioniert (ansonsten in salt pillar pg_vector installieren, und als postgres user: create extension vector;)&lt;br /&gt;
## mkdir -p ~/plugins.bak&lt;br /&gt;
## mv plugins/discourse-ai ~/plugins.bak&lt;br /&gt;
# RAILS_ENV=production bundle exec rake db:migrate&lt;br /&gt;
# RAILS_ENV=production bundle exec rake assets:precompile&lt;br /&gt;
# Services neu starten&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user restart puma&lt;br /&gt;
systemctl --user restart sidekiq&lt;br /&gt;
systemctl --user restart redis&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zuletzt: Read-Only Modus wieder deaktivieren&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
&lt;br /&gt;
Es können folgende Einstellungen in der Datei config/environments/production.rb vorgenommen werden. Danach den Puma Dienst neustarten. Fehlermeldungen und Stacktraces werden dann im Browser ausgegeben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
config.log_level = :debug&lt;br /&gt;
config.action_dispatch.show_exceptions = :all&lt;br /&gt;
config.action_dispatch.debug_exception_log_level = :error&lt;br /&gt;
&lt;br /&gt;
# Full error reports are enabled and caching is turned off&lt;br /&gt;
config.consider_all_requests_local = true&lt;br /&gt;
config.action_controller.perform_caching = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erforderliche Anpassungen ===&lt;br /&gt;
Weil wir bei Debian Bookworm noch mit ImageMagick 6.9 arbeiten, muss dieser [https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119 Patch] rückgängig gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line&amp;gt;&lt;br /&gt;
wget https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119.patch -O ~/imagemagick.patch&lt;br /&gt;
patch -p1 --reverse &amp;lt; ~/imagemagick.patch&lt;br /&gt;
git commit -a -m &amp;quot;revert imagemagick patch&amp;quot;  --no-verify&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ToDos ==&lt;br /&gt;
&lt;br /&gt;
* Ein Patch, um Discourse auch via Unix-Socket mit Redis sprechen lassen zu können dürfte relativ einfach sein (es wird ein Wrapper um das redis-gem genutzt).&lt;br /&gt;
* Konfiguration von discourse, um mit postgresql via Unix-Socket zu kommunizieren (DISCOURSE_DB_SOCKET environment variable)&lt;br /&gt;
* Performance-tuning an diversen Stellen, anhand der discourse_docker-Vorgaben (https://github.com/discourse/discourse_docker), z.B.&lt;br /&gt;
** thpoff (huge page settings)&lt;br /&gt;
** unicorn (hat eine wesentlich ausgefeiltere Konfigurations-Vorlage, wahrscheinlich bereits ordentlich optimiert)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://help.skysilk.com/support/solutions/articles/9000120927-how-to-install-discourse-without-docker-using-skysilk-vps-&lt;br /&gt;
* https://github.com/discourse/discourse_docker&lt;br /&gt;
* https://github.com/discourse/discourse&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/discourse&lt;br /&gt;
&lt;br /&gt;
== Historie ==&lt;br /&gt;
&lt;br /&gt;
* 2018, 14 . September: Initiale Fassung&lt;br /&gt;
* 2019, Januar: Update-Informationen ergänzt&lt;br /&gt;
* 2022, Juni: systemd Dienste, Discourse 3.0&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:RubyOnRails]]&lt;br /&gt;
[[Kategorie:Webforen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Matrix_Synapse_installieren&amp;diff=7615</id>
		<title>Matrix Synapse installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Matrix_Synapse_installieren&amp;diff=7615"/>
		<updated>2026-08-04T09:36:19Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Verwalten von Benutzern */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Der Matrix Server &#039;&#039;Synapse&#039;&#039;, der sogenannte &#039;Homeserver&#039;, ist aktuell die einzige vollständige serverseitige Implementierung des Matrix-Protokolls.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gelb|Work in Progress|Leider funktioniert die Server-zu-Server-Kommunikation von Synapse hinter dem Apache-Proxy mit den genannten Rewrite-Rules nicht. Bitten Sie dazu den Service, Ihren Apache VHost individuell für den Matrix Server anzupassen.}}&lt;br /&gt;
&lt;br /&gt;
Die hier beschriebene Installation benötigt bei Hostsharing die Paket-Option &amp;quot;RAM&amp;quot;. Benötigt werden min. 512 MB. Im Managed Webspace ist diese Option kostenpflichtig: https://www.hostsharing.net/angebote/managed-webspace/ gebucht werden muss der RAM auch bei einem Managed-Server.&lt;br /&gt;
Wir empfehlen für den Betrieb einen &#039;&#039;Managed Server&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt, wie man den Matrix-Homeserver Synapse auf der Managed Hosting Plattform von Hostsharing installieren kann. Dabei sind die User-IDs nach dem Schema @user:beispiel.de aufgebaut, der Homeserver an sich ist unter matrix.beispiel.de erreichbar.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von HSAdmin werden angelegt:&lt;br /&gt;
# Ein User als Service-User mit &#039;&#039;/bin/bash&#039;&#039; als Shell, zum Beispiel Beispiel: &#039;&#039;xyz00-matrix&#039;&#039;&lt;br /&gt;
# Eine Domain mit &#039;&#039;xyz00-matrix&#039;&#039; als Domain-Administrator, zum Beispiel &#039;&#039;matrix.beispiel.de&#039;&#039;&lt;br /&gt;
# Einen Postgresql-User &#039;&#039;xyz00_matrixuser&#039;&#039; mit Passwort &#039;&#039;meinPasswort&#039;&#039;&lt;br /&gt;
# Eine Postgresql-Datenbank &#039;&#039;xyz00_matrixdb&#039;&#039; mit Datenbank-Owner &#039;&#039;xyz00_matrixuser&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verwendeter IP-Port für den Server-Dienst:&lt;br /&gt;
# Synapse: localhost:32801&lt;br /&gt;
&lt;br /&gt;
== Installation von Synapse ==&lt;br /&gt;
&lt;br /&gt;
Installationsanleitung basierend auf https://matrix-org.github.io/synapse/latest/setup/installation.html#installing-as-a-python-module-from-pypi&lt;br /&gt;
&lt;br /&gt;
Als User &#039;&#039;xyz00-matrix&amp;quot; ein Python3 virtualenv erstellen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/synapse&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
python -m venv .venv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Synapse und Postgres-Dependencies installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
source ~/synapse/.venv/bin/activate&lt;br /&gt;
pip install pipenv&lt;br /&gt;
pipenv install matrix-synapse[postgres,oidc] lxml authlib&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Initiale Konfiguration mit richtigem server-name &amp;quot;beispiel.de&amp;quot; generieren, außerdem im laufenden Betrieb keine Statistiken an Matrix.org senden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
pipenv run python -m synapse.app.homeserver --server-name beispiel.de --config-path homeserver.yaml --generate-config --report-stats=no&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration von Synapse ==&lt;br /&gt;
&lt;br /&gt;
In die initial generierte Konfiguration muss noch die Port- und Datenbank-Konfiguration eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
Port: Innerhalb der listener-section den Port 8008 auf 32801 (wie initial definiert) ändern, alles andere beibehalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
- port: 32801&lt;br /&gt;
    tls: false&lt;br /&gt;
    bind_addresses: [&#039;::1&#039;, &#039;127.0.0.1&#039;]&lt;br /&gt;
    type: http&lt;br /&gt;
    x_forwarded: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Postgres-Datenbank:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
database:&lt;br /&gt;
    # The database engine name&lt;br /&gt;
    name: &amp;quot;psycopg2&amp;quot;&lt;br /&gt;
    # Arguments to pass to the engine&lt;br /&gt;
    args:&lt;br /&gt;
    host: &amp;quot;localhost&amp;quot;&lt;br /&gt;
    database: &amp;quot;xyz00_matrixdb&amp;quot;&lt;br /&gt;
    user: &amp;quot;xyz00_matrixuser&amp;quot;&lt;br /&gt;
    password: &amp;quot;meinPasswort&amp;quot;&lt;br /&gt;
    cp_min: 5&lt;br /&gt;
    cp_max: 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starten der Dienste  ==&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;Synapse&#039;&#039;-Dienst wird hier als Service-Unit im SystemD des Users eingetragen.&lt;br /&gt;
&lt;br /&gt;
Lege dazu die folgende Datei an: &#039;&#039;~/.config/systemd/user/synapse.service&#039;&#039; mit dem Inhalt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Synapse&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
WorkingDirectory=%h/synapse&lt;br /&gt;
Environment=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2&lt;br /&gt;
ExecStart=pipenv run python -m synapse.app.homeserver --config-path=%h/synapse/homeserver.yaml&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durch Aufruf der folgenden Kommandos wird der Dienst aktiviert und gestartet:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot; lines&amp;gt;&lt;br /&gt;
systemctl --user daemon-reload&lt;br /&gt;
systemctl --user enable synapse.service&lt;br /&gt;
systemctl --user start synapse.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Verwalten von Benutzern ==&lt;br /&gt;
&lt;br /&gt;
Mit den folgenden Befehlen kann ein Benutzer angelegt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
register_new_matrix_user -c homeserver.yaml --user &amp;lt;USERNAME&amp;gt; &amp;lt;--admin|--no-admin&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So kann ein Benutzer auch wieder deaktiviert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
user=&amp;lt;USERNAME&amp;gt;&lt;br /&gt;
domain=&amp;quot;https://&amp;lt;matrix.example.org&amp;gt;&amp;quot;&lt;br /&gt;
password=&amp;quot;&amp;lt;TOPSECRET&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
&lt;br /&gt;
url_user=`echo -n &amp;quot;$user&amp;quot; | jq -s -R -r @uri`&lt;br /&gt;
json=`curl -s --insecure -XPOST -d &#039;{&amp;quot;type&amp;quot;:&amp;quot;m.login.password&amp;quot;, &amp;quot;user&amp;quot;:&amp;quot;root&amp;quot;, &amp;quot;password&amp;quot;:&amp;quot;&#039;$password&#039;&amp;quot;}&#039; &amp;quot;https://$domain/_matrix/client/r0/login&amp;quot;`&lt;br /&gt;
access_token=`echo &amp;quot;$json&amp;quot; | jq -r &amp;quot;.access_token&amp;quot;`&lt;br /&gt;
&lt;br /&gt;
# see https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#deactivate-account&lt;br /&gt;
curl --insecure -XPOST -H &amp;quot;Authorization: Bearer $access_token&amp;quot; -H &amp;quot;Content-Type: application/json&amp;quot; -d \&lt;br /&gt;
  &#039;{&amp;quot;erase&amp;quot;: true}&#039; &amp;quot;$domain/_synapse/admin/v1/deactivate/$url_user&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt auch Bash Skripte dafür, damit die Benutzung vereinfacht wird:&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible.app.synapse/src/branch/main/templates/adduser.sh&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible.app.synapse/src/branch/main/templates/deluser.sh&lt;br /&gt;
&lt;br /&gt;
Es gibt auch eine grafische Oberfläche:&lt;br /&gt;
* https://github.com/Awesome-Technologies/synapse-admin&lt;br /&gt;
* bzw. der Fork https://github.com/etkecc/ketesa&lt;br /&gt;
&lt;br /&gt;
Ansonsten kann für die Benutzerverwaltung ein Keycloak installiert werden, und Synapse über OIDC an den Keycloak angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
== Einrichten des Apache VHost ==&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;~/doms/matrix.beispiel.de/.htaccess&#039;&#039; mit dem Editor der Wahl öffnen und &lt;br /&gt;
folgende Konfiguration einfügen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RewriteRule .* http://localhost:32801%{REQUEST_URI} [NE,proxy]&lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Well-Known unter beispiel.de ==&lt;br /&gt;
&lt;br /&gt;
Damit die User-Accounts das Format @user:beispiel.de haben, der Server aber unter matrix.beispiel.de erreichbar ist, müssen noch folgende zwei Dateien unter der Domain beispiel.de abgelegt werden:&lt;br /&gt;
&lt;br /&gt;
https://beispiel.de/.well-known/matrix/server&lt;br /&gt;
&amp;lt;syntaxhighlight lang=json line&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;m.server&amp;quot;: &amp;quot;matrix.beispiel.de:443&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://beispiel.de/.well-known/matrix/client&lt;br /&gt;
&amp;lt;syntaxhighlight lang=json line&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;m.homeserver&amp;quot;: {&lt;br /&gt;
        &amp;quot;base_url&amp;quot;: &amp;quot;https://matrix.beispiel.de&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;m.identity_server&amp;quot;: {&lt;br /&gt;
        &amp;quot;base_url&amp;quot;: &amp;quot;https://vector.im&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für die muss noch der CORS-Header Access-Control-Allow-Origin &amp;quot;*&amp;quot; gesetzt werden, damit die Datei aus beliebigem Riot-Web im Browser abrufbar ist. Dazu in den Ordner .well-known/matrix/ folgende .htaccess anlegen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
&amp;lt;IfModule mod_headers.c&amp;gt;&lt;br /&gt;
  Header set Access-Control-Allow-Origin &amp;quot;*&amp;quot;&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Dokumentation dazu findet man unter https://matrix.org/docs/spec/server_server/r0.1.2#get-well-known-matrix-server und https://matrix.org/docs/spec/client_server/r0.5.0#get-well-known-matrix-client&lt;br /&gt;
&lt;br /&gt;
== Update von Synapse ==&lt;br /&gt;
&lt;br /&gt;
Normalerweise sollte es so gehen, mit pipenv:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
pipenv update --outdated || echo &amp;quot;there are packages to update&amp;quot;&lt;br /&gt;
pipenv update&lt;br /&gt;
systemctl --user restart synapse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In seltenen Fällen gibt es Probleme bei den Abhängigkeiten, die schon wieder aktualisiert wurden, und nicht mehr kompatibel zum aktuellen Synapse sind.&lt;br /&gt;
Dann ist es zu empfehlen, Synapse mit der offiziellen poetry.lock Datei zu aktualisieren, um die Konflikte zu vermeiden.&lt;br /&gt;
&lt;br /&gt;
mit poetry:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user stop synapse.service&lt;br /&gt;
source ~/.venv/bin/activate&lt;br /&gt;
release=`curl -L https://api.github.com/repos/element-hq/synapse/releases/latest -s | jq -r &#039;.tag_name&#039;`&lt;br /&gt;
rm -Rf ~/synapse.src&lt;br /&gt;
git clone --depth 1 https://github.com/element-hq/synapse.git -b ${release} ~/synapse.src&lt;br /&gt;
cd ~/synapse.src&lt;br /&gt;
pip install poetry&lt;br /&gt;
poetry install --extras=postgres --extras=oidc&lt;br /&gt;
systemctl --user start synapse.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Föderation für den Synapse Server aktiviert ist, kann mit dem [https://federationtester.matrix.org/ Matrix Federation Tester] die eigene Instanz auf die laufende Version geprüft werden. Als Server nicht matrix.example.org eingeben, sondern den öffentlichen Namen, wo auch die Benutzernamen drauf laufen, z.B. example.org&lt;br /&gt;
&lt;br /&gt;
Ansonsten ist die laufende Version auch über die URL https://matrix.example.org/_synapse/admin/v1/server_version zu erfahren.&lt;br /&gt;
&lt;br /&gt;
== Element-Web ==&lt;br /&gt;
&lt;br /&gt;
Element-Web ist aus Server-Seite eine rein statische html+javascript-Kombination, daher:&lt;br /&gt;
&lt;br /&gt;
* Account und Domain anlegen (separat von der Synapse-Domain)&lt;br /&gt;
* [https://github.com/element-hq/element-web/releases/latest aktuelles element-web release] .tgz herunterladen&lt;br /&gt;
* Symlink von htdocs-ssl auf entpacktes element-web-Verzeichnis&lt;br /&gt;
* config.sample.json in config.json kopieren und Matrix-Homeserver-Einträge anpassen&lt;br /&gt;
* Piwik aus config.json entfernen&lt;br /&gt;
&lt;br /&gt;
== SAML mit Synapse ==&lt;br /&gt;
&lt;br /&gt;
Synapse unterstützt mit Version 1.1.0 SAML. Dazu wie folgt vorgehen:&lt;br /&gt;
&lt;br /&gt;
Das Paket xmlsec1 muss installiert sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
$ xmlsec1  --version&lt;br /&gt;
xmlsec1 1.2.23 (openssl)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Python-Paket pysaml2 installieren&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
pipenv shell&lt;br /&gt;
pipenv install pysaml2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der homeserver.yaml die SAML-Direktiven einkommentieren, hier mit dem Beispiel eines SAML IdP unter https://login.beispiel.de/simplesaml/saml2/idp/metadata.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
# Once SAML support is enabled, a metadata file will be exposed at&lt;br /&gt;
# https://&amp;lt;server&amp;gt;:&amp;lt;port&amp;gt;/_matrix/saml2/metadata.xml, which you may be able to &lt;br /&gt;
# use to configure your SAML IdP with. Alternatively, you can manually configure&lt;br /&gt;
# the IdP to use an ACS location of&lt;br /&gt;
# https://&amp;lt;server&amp;gt;:&amp;lt;port&amp;gt;/_matrix/saml2/authn_response.&lt;br /&gt;
#&lt;br /&gt;
saml2_config:&lt;br /&gt;
    sp_config:&lt;br /&gt;
        # point this to the IdP&#039;s metadata. You can use either a local file or&lt;br /&gt;
        # (preferably) a URL.&lt;br /&gt;
        metadata:&lt;br /&gt;
        #local: [&amp;quot;saml2/idp.xml&amp;quot;]&lt;br /&gt;
        remote:&lt;br /&gt;
            - url: https://login.beispiel.de/simplesaml/saml2/idp/metadata.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wichtig ist außerdem, dass die public_baseurl in der homeserver.yaml gesetzt ist, damit Synapse weiß, wie es erreichbar ist und dies in seine SP-Metadaten einbauen kann:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
public_baseurl: https://matrix.beispiel.de/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Service-Provider-Konfiguration als XML bekommt man von Synapse dann wie schon in der homeserver.yaml als Kommentar beschrieben, unter https://matrix.beispiel.de/_matrix/saml2/metadata.xml&lt;br /&gt;
&lt;br /&gt;
Diese dann in den SAML-IdP-importieren und dann sollte der Single-Sign-On via SAML funktionieren.&lt;br /&gt;
&lt;br /&gt;
== Federation Sender Worker für Synapse ==&lt;br /&gt;
&lt;br /&gt;
Zur Parallelisierung bietet Synapse das Konzept &amp;quot;Worker&amp;quot; an, die spezifische Aufgaben übernehmen, damit der Hauptprozess diese nicht durchführen muss.&lt;br /&gt;
&lt;br /&gt;
Details dazu: https://github.com/matrix-org/synapse/blob/master/docs/workers.md&lt;br /&gt;
&lt;br /&gt;
Ein einfach einzurichtender Worker, der auch viel Last abfedert, ist der Federation Sender Worker, da das Verschicken des Federation-Traffics 10-50% der Serverlast ausmacht.&lt;br /&gt;
&lt;br /&gt;
In der homeserver.yaml die Worker-Konfiguration aktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
## Worker ##&lt;br /&gt;
worker_app: synapse.app.homeserver&lt;br /&gt;
daemonize: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und dazugehörige Listener (Abschnitt listener:) aktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
# The TCP replication port&lt;br /&gt;
- port: 32892&lt;br /&gt;
  bind_address: &#039;127.0.0.1&#039;&lt;br /&gt;
  type: replication&lt;br /&gt;
# The HTTP replication port&lt;br /&gt;
- port: 32893&lt;br /&gt;
  bind_address: &#039;127.0.0.1&#039;&lt;br /&gt;
  type: http&lt;br /&gt;
  resources:&lt;br /&gt;
   - names: [replication]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen, die Worker machen sollen, in der homeserver.yaml deaktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
# disable federation sending here, use worker for it&lt;br /&gt;
send_federation: False&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann Verzeichnis synapse/workers anlegen, darin federation_sender.yaml:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
worker_app: synapse.app.federation_sender&lt;br /&gt;
&lt;br /&gt;
# The replication listener on the synapse to talk to.&lt;br /&gt;
worker_replication_host: 127.0.0.1&lt;br /&gt;
worker_replication_port: 32892&lt;br /&gt;
worker_replication_http_port: 32893&lt;br /&gt;
&lt;br /&gt;
worker_daemonize: True&lt;br /&gt;
worker_pid_file: /home/pacs/xyz00/users/matrix/synapse/federation_sender.pid&lt;br /&gt;
worker_log_config: /home/pacs/xyz00/users/matrix/synapse/federation_sender.log.config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
.monitrc um worker erweitern:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
check process federation_sender with pidfile /home/pacs/xyz00/users/matrix/synapse/federation_sender.pid&lt;br /&gt;
    start program &amp;quot;/bin/bash -c &#039;export VIRTUAL_ENV=$HOME/synapse/env &amp;amp;&amp;amp; export PATH=$VIRTUAL_ENV/bin:$PATH &amp;amp;&amp;amp; cd $HOME/synapse &amp;amp;&amp;amp; synctl -w workers/federation_sender.yaml start&#039;&amp;quot;&lt;br /&gt;
    stop program &amp;quot;/bin/bash -c &#039;/bin/kill $( cat $HOME/synapse/federation_sender.pid )&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Monit neu laden und synapse und federation_sender neustarten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
monit reload&lt;br /&gt;
monit restart all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nach Updates ebenfalls immer Hauptprozess und alle Worker neustarten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
monit restart all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sliding Sync Proxy ==&lt;br /&gt;
Zum Zeitpunkt dieser Anleitung werden aktiv neue Element Anwendungen (Element X) und ein neues Syncverfahren entwickelt um Matrix performanter und weniger ressourcenhungrig zu machen. Bei stärkerer Matrix Nutzung können die neuen Anwendungen besonders mobil schon eine große Entlastung sein.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;Ende 2024 wurden grundlegende Funktionen direkt in Synapse implementiert. Der Proxy wird nicht länger weiterentwickelt und sollte deinstalliert werden (nicht vergessen die .well-known zurück zu ändern).&amp;lt;/strong&amp;gt; Auch der 3rdparty Server [[Conduit]] bringt nativ Support für Sliding Sync.&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://matrix.org/docs/projects/server/synapse &lt;br /&gt;
* https://github.com/element-hq/synapse&lt;br /&gt;
* https://github.com/element-hq/synapse/blob/master/INSTALL.md&lt;br /&gt;
* https://github.com/matrix-org/sliding-sync&lt;br /&gt;
* https://matrix.org/docs/spec/&lt;br /&gt;
* https://www.hostsharing.net/loesungen/matrix/&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/synapse&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/element&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Messenger]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Eigene Daemons]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Matrix_Synapse_installieren&amp;diff=7614</id>
		<title>Matrix Synapse installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Matrix_Synapse_installieren&amp;diff=7614"/>
		<updated>2026-08-04T09:00:28Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Verwalten von Benutzern */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Der Matrix Server &#039;&#039;Synapse&#039;&#039;, der sogenannte &#039;Homeserver&#039;, ist aktuell die einzige vollständige serverseitige Implementierung des Matrix-Protokolls.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gelb|Work in Progress|Leider funktioniert die Server-zu-Server-Kommunikation von Synapse hinter dem Apache-Proxy mit den genannten Rewrite-Rules nicht. Bitten Sie dazu den Service, Ihren Apache VHost individuell für den Matrix Server anzupassen.}}&lt;br /&gt;
&lt;br /&gt;
Die hier beschriebene Installation benötigt bei Hostsharing die Paket-Option &amp;quot;RAM&amp;quot;. Benötigt werden min. 512 MB. Im Managed Webspace ist diese Option kostenpflichtig: https://www.hostsharing.net/angebote/managed-webspace/ gebucht werden muss der RAM auch bei einem Managed-Server.&lt;br /&gt;
Wir empfehlen für den Betrieb einen &#039;&#039;Managed Server&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt, wie man den Matrix-Homeserver Synapse auf der Managed Hosting Plattform von Hostsharing installieren kann. Dabei sind die User-IDs nach dem Schema @user:beispiel.de aufgebaut, der Homeserver an sich ist unter matrix.beispiel.de erreichbar.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von HSAdmin werden angelegt:&lt;br /&gt;
# Ein User als Service-User mit &#039;&#039;/bin/bash&#039;&#039; als Shell, zum Beispiel Beispiel: &#039;&#039;xyz00-matrix&#039;&#039;&lt;br /&gt;
# Eine Domain mit &#039;&#039;xyz00-matrix&#039;&#039; als Domain-Administrator, zum Beispiel &#039;&#039;matrix.beispiel.de&#039;&#039;&lt;br /&gt;
# Einen Postgresql-User &#039;&#039;xyz00_matrixuser&#039;&#039; mit Passwort &#039;&#039;meinPasswort&#039;&#039;&lt;br /&gt;
# Eine Postgresql-Datenbank &#039;&#039;xyz00_matrixdb&#039;&#039; mit Datenbank-Owner &#039;&#039;xyz00_matrixuser&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verwendeter IP-Port für den Server-Dienst:&lt;br /&gt;
# Synapse: localhost:32801&lt;br /&gt;
&lt;br /&gt;
== Installation von Synapse ==&lt;br /&gt;
&lt;br /&gt;
Installationsanleitung basierend auf https://matrix-org.github.io/synapse/latest/setup/installation.html#installing-as-a-python-module-from-pypi&lt;br /&gt;
&lt;br /&gt;
Als User &#039;&#039;xyz00-matrix&amp;quot; ein Python3 virtualenv erstellen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/synapse&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
python -m venv .venv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Synapse und Postgres-Dependencies installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
source ~/synapse/.venv/bin/activate&lt;br /&gt;
pip install pipenv&lt;br /&gt;
pipenv install matrix-synapse[postgres,oidc] lxml authlib&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Initiale Konfiguration mit richtigem server-name &amp;quot;beispiel.de&amp;quot; generieren, außerdem im laufenden Betrieb keine Statistiken an Matrix.org senden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
pipenv run python -m synapse.app.homeserver --server-name beispiel.de --config-path homeserver.yaml --generate-config --report-stats=no&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration von Synapse ==&lt;br /&gt;
&lt;br /&gt;
In die initial generierte Konfiguration muss noch die Port- und Datenbank-Konfiguration eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
Port: Innerhalb der listener-section den Port 8008 auf 32801 (wie initial definiert) ändern, alles andere beibehalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
- port: 32801&lt;br /&gt;
    tls: false&lt;br /&gt;
    bind_addresses: [&#039;::1&#039;, &#039;127.0.0.1&#039;]&lt;br /&gt;
    type: http&lt;br /&gt;
    x_forwarded: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Postgres-Datenbank:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
database:&lt;br /&gt;
    # The database engine name&lt;br /&gt;
    name: &amp;quot;psycopg2&amp;quot;&lt;br /&gt;
    # Arguments to pass to the engine&lt;br /&gt;
    args:&lt;br /&gt;
    host: &amp;quot;localhost&amp;quot;&lt;br /&gt;
    database: &amp;quot;xyz00_matrixdb&amp;quot;&lt;br /&gt;
    user: &amp;quot;xyz00_matrixuser&amp;quot;&lt;br /&gt;
    password: &amp;quot;meinPasswort&amp;quot;&lt;br /&gt;
    cp_min: 5&lt;br /&gt;
    cp_max: 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starten der Dienste  ==&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;Synapse&#039;&#039;-Dienst wird hier als Service-Unit im SystemD des Users eingetragen.&lt;br /&gt;
&lt;br /&gt;
Lege dazu die folgende Datei an: &#039;&#039;~/.config/systemd/user/synapse.service&#039;&#039; mit dem Inhalt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Synapse&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
WorkingDirectory=%h/synapse&lt;br /&gt;
Environment=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2&lt;br /&gt;
ExecStart=pipenv run python -m synapse.app.homeserver --config-path=%h/synapse/homeserver.yaml&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durch Aufruf der folgenden Kommandos wird der Dienst aktiviert und gestartet:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot; lines&amp;gt;&lt;br /&gt;
systemctl --user daemon-reload&lt;br /&gt;
systemctl --user enable synapse.service&lt;br /&gt;
systemctl --user start synapse.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Verwalten von Benutzern ==&lt;br /&gt;
&lt;br /&gt;
Mit den folgenden Befehlen kann ein Benutzer angelegt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
register_new_matrix_user -c homeserver.yaml --user &amp;lt;USERNAME&amp;gt; &amp;lt;--admin|--no-admin&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So kann ein Benutzer auch wieder deaktiviert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
user=&amp;lt;USERNAME&amp;gt;&lt;br /&gt;
domain=&amp;quot;https://&amp;lt;matrix.example.org&amp;gt;&amp;quot;&lt;br /&gt;
password=&amp;quot;&amp;lt;TOPSECRET&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
&lt;br /&gt;
url_user=`echo -n &amp;quot;$user&amp;quot; | jq -s -R -r @uri`&lt;br /&gt;
json=`curl -s --insecure -XPOST -d &#039;{&amp;quot;type&amp;quot;:&amp;quot;m.login.password&amp;quot;, &amp;quot;user&amp;quot;:&amp;quot;root&amp;quot;, &amp;quot;password&amp;quot;:&amp;quot;&#039;$password&#039;&amp;quot;}&#039; &amp;quot;https://$domain/_matrix/client/r0/login&amp;quot;`&lt;br /&gt;
access_token=`echo &amp;quot;$json&amp;quot; | jq -r &amp;quot;.access_token&amp;quot;`&lt;br /&gt;
&lt;br /&gt;
# see https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#deactivate-account&lt;br /&gt;
curl --insecure -XPOST -H &amp;quot;Authorization: Bearer $access_token&amp;quot; -H &amp;quot;Content-Type: application/json&amp;quot; -d \&lt;br /&gt;
  &#039;{&amp;quot;erase&amp;quot;: true}&#039; &amp;quot;$domain/_synapse/admin/v1/deactivate/$url_user&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ansonsten kann für die Benutzerverwaltung ein Keycloak installiert werden, und Synapse über OIDC an den Keycloak angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
== Einrichten des Apache VHost ==&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;~/doms/matrix.beispiel.de/.htaccess&#039;&#039; mit dem Editor der Wahl öffnen und &lt;br /&gt;
folgende Konfiguration einfügen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RewriteRule .* http://localhost:32801%{REQUEST_URI} [NE,proxy]&lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Well-Known unter beispiel.de ==&lt;br /&gt;
&lt;br /&gt;
Damit die User-Accounts das Format @user:beispiel.de haben, der Server aber unter matrix.beispiel.de erreichbar ist, müssen noch folgende zwei Dateien unter der Domain beispiel.de abgelegt werden:&lt;br /&gt;
&lt;br /&gt;
https://beispiel.de/.well-known/matrix/server&lt;br /&gt;
&amp;lt;syntaxhighlight lang=json line&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;m.server&amp;quot;: &amp;quot;matrix.beispiel.de:443&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://beispiel.de/.well-known/matrix/client&lt;br /&gt;
&amp;lt;syntaxhighlight lang=json line&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;m.homeserver&amp;quot;: {&lt;br /&gt;
        &amp;quot;base_url&amp;quot;: &amp;quot;https://matrix.beispiel.de&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;m.identity_server&amp;quot;: {&lt;br /&gt;
        &amp;quot;base_url&amp;quot;: &amp;quot;https://vector.im&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für die muss noch der CORS-Header Access-Control-Allow-Origin &amp;quot;*&amp;quot; gesetzt werden, damit die Datei aus beliebigem Riot-Web im Browser abrufbar ist. Dazu in den Ordner .well-known/matrix/ folgende .htaccess anlegen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
&amp;lt;IfModule mod_headers.c&amp;gt;&lt;br /&gt;
  Header set Access-Control-Allow-Origin &amp;quot;*&amp;quot;&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Dokumentation dazu findet man unter https://matrix.org/docs/spec/server_server/r0.1.2#get-well-known-matrix-server und https://matrix.org/docs/spec/client_server/r0.5.0#get-well-known-matrix-client&lt;br /&gt;
&lt;br /&gt;
== Update von Synapse ==&lt;br /&gt;
&lt;br /&gt;
Normalerweise sollte es so gehen, mit pipenv:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
pipenv update --outdated || echo &amp;quot;there are packages to update&amp;quot;&lt;br /&gt;
pipenv update&lt;br /&gt;
systemctl --user restart synapse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In seltenen Fällen gibt es Probleme bei den Abhängigkeiten, die schon wieder aktualisiert wurden, und nicht mehr kompatibel zum aktuellen Synapse sind.&lt;br /&gt;
Dann ist es zu empfehlen, Synapse mit der offiziellen poetry.lock Datei zu aktualisieren, um die Konflikte zu vermeiden.&lt;br /&gt;
&lt;br /&gt;
mit poetry:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user stop synapse.service&lt;br /&gt;
source ~/.venv/bin/activate&lt;br /&gt;
release=`curl -L https://api.github.com/repos/element-hq/synapse/releases/latest -s | jq -r &#039;.tag_name&#039;`&lt;br /&gt;
rm -Rf ~/synapse.src&lt;br /&gt;
git clone --depth 1 https://github.com/element-hq/synapse.git -b ${release} ~/synapse.src&lt;br /&gt;
cd ~/synapse.src&lt;br /&gt;
pip install poetry&lt;br /&gt;
poetry install --extras=postgres --extras=oidc&lt;br /&gt;
systemctl --user start synapse.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Föderation für den Synapse Server aktiviert ist, kann mit dem [https://federationtester.matrix.org/ Matrix Federation Tester] die eigene Instanz auf die laufende Version geprüft werden. Als Server nicht matrix.example.org eingeben, sondern den öffentlichen Namen, wo auch die Benutzernamen drauf laufen, z.B. example.org&lt;br /&gt;
&lt;br /&gt;
Ansonsten ist die laufende Version auch über die URL https://matrix.example.org/_synapse/admin/v1/server_version zu erfahren.&lt;br /&gt;
&lt;br /&gt;
== Element-Web ==&lt;br /&gt;
&lt;br /&gt;
Element-Web ist aus Server-Seite eine rein statische html+javascript-Kombination, daher:&lt;br /&gt;
&lt;br /&gt;
* Account und Domain anlegen (separat von der Synapse-Domain)&lt;br /&gt;
* [https://github.com/element-hq/element-web/releases/latest aktuelles element-web release] .tgz herunterladen&lt;br /&gt;
* Symlink von htdocs-ssl auf entpacktes element-web-Verzeichnis&lt;br /&gt;
* config.sample.json in config.json kopieren und Matrix-Homeserver-Einträge anpassen&lt;br /&gt;
* Piwik aus config.json entfernen&lt;br /&gt;
&lt;br /&gt;
== SAML mit Synapse ==&lt;br /&gt;
&lt;br /&gt;
Synapse unterstützt mit Version 1.1.0 SAML. Dazu wie folgt vorgehen:&lt;br /&gt;
&lt;br /&gt;
Das Paket xmlsec1 muss installiert sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
$ xmlsec1  --version&lt;br /&gt;
xmlsec1 1.2.23 (openssl)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Python-Paket pysaml2 installieren&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
pipenv shell&lt;br /&gt;
pipenv install pysaml2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der homeserver.yaml die SAML-Direktiven einkommentieren, hier mit dem Beispiel eines SAML IdP unter https://login.beispiel.de/simplesaml/saml2/idp/metadata.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
# Once SAML support is enabled, a metadata file will be exposed at&lt;br /&gt;
# https://&amp;lt;server&amp;gt;:&amp;lt;port&amp;gt;/_matrix/saml2/metadata.xml, which you may be able to &lt;br /&gt;
# use to configure your SAML IdP with. Alternatively, you can manually configure&lt;br /&gt;
# the IdP to use an ACS location of&lt;br /&gt;
# https://&amp;lt;server&amp;gt;:&amp;lt;port&amp;gt;/_matrix/saml2/authn_response.&lt;br /&gt;
#&lt;br /&gt;
saml2_config:&lt;br /&gt;
    sp_config:&lt;br /&gt;
        # point this to the IdP&#039;s metadata. You can use either a local file or&lt;br /&gt;
        # (preferably) a URL.&lt;br /&gt;
        metadata:&lt;br /&gt;
        #local: [&amp;quot;saml2/idp.xml&amp;quot;]&lt;br /&gt;
        remote:&lt;br /&gt;
            - url: https://login.beispiel.de/simplesaml/saml2/idp/metadata.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wichtig ist außerdem, dass die public_baseurl in der homeserver.yaml gesetzt ist, damit Synapse weiß, wie es erreichbar ist und dies in seine SP-Metadaten einbauen kann:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
public_baseurl: https://matrix.beispiel.de/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Service-Provider-Konfiguration als XML bekommt man von Synapse dann wie schon in der homeserver.yaml als Kommentar beschrieben, unter https://matrix.beispiel.de/_matrix/saml2/metadata.xml&lt;br /&gt;
&lt;br /&gt;
Diese dann in den SAML-IdP-importieren und dann sollte der Single-Sign-On via SAML funktionieren.&lt;br /&gt;
&lt;br /&gt;
== Federation Sender Worker für Synapse ==&lt;br /&gt;
&lt;br /&gt;
Zur Parallelisierung bietet Synapse das Konzept &amp;quot;Worker&amp;quot; an, die spezifische Aufgaben übernehmen, damit der Hauptprozess diese nicht durchführen muss.&lt;br /&gt;
&lt;br /&gt;
Details dazu: https://github.com/matrix-org/synapse/blob/master/docs/workers.md&lt;br /&gt;
&lt;br /&gt;
Ein einfach einzurichtender Worker, der auch viel Last abfedert, ist der Federation Sender Worker, da das Verschicken des Federation-Traffics 10-50% der Serverlast ausmacht.&lt;br /&gt;
&lt;br /&gt;
In der homeserver.yaml die Worker-Konfiguration aktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
## Worker ##&lt;br /&gt;
worker_app: synapse.app.homeserver&lt;br /&gt;
daemonize: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und dazugehörige Listener (Abschnitt listener:) aktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
# The TCP replication port&lt;br /&gt;
- port: 32892&lt;br /&gt;
  bind_address: &#039;127.0.0.1&#039;&lt;br /&gt;
  type: replication&lt;br /&gt;
# The HTTP replication port&lt;br /&gt;
- port: 32893&lt;br /&gt;
  bind_address: &#039;127.0.0.1&#039;&lt;br /&gt;
  type: http&lt;br /&gt;
  resources:&lt;br /&gt;
   - names: [replication]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen, die Worker machen sollen, in der homeserver.yaml deaktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
# disable federation sending here, use worker for it&lt;br /&gt;
send_federation: False&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann Verzeichnis synapse/workers anlegen, darin federation_sender.yaml:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
worker_app: synapse.app.federation_sender&lt;br /&gt;
&lt;br /&gt;
# The replication listener on the synapse to talk to.&lt;br /&gt;
worker_replication_host: 127.0.0.1&lt;br /&gt;
worker_replication_port: 32892&lt;br /&gt;
worker_replication_http_port: 32893&lt;br /&gt;
&lt;br /&gt;
worker_daemonize: True&lt;br /&gt;
worker_pid_file: /home/pacs/xyz00/users/matrix/synapse/federation_sender.pid&lt;br /&gt;
worker_log_config: /home/pacs/xyz00/users/matrix/synapse/federation_sender.log.config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
.monitrc um worker erweitern:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
check process federation_sender with pidfile /home/pacs/xyz00/users/matrix/synapse/federation_sender.pid&lt;br /&gt;
    start program &amp;quot;/bin/bash -c &#039;export VIRTUAL_ENV=$HOME/synapse/env &amp;amp;&amp;amp; export PATH=$VIRTUAL_ENV/bin:$PATH &amp;amp;&amp;amp; cd $HOME/synapse &amp;amp;&amp;amp; synctl -w workers/federation_sender.yaml start&#039;&amp;quot;&lt;br /&gt;
    stop program &amp;quot;/bin/bash -c &#039;/bin/kill $( cat $HOME/synapse/federation_sender.pid )&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Monit neu laden und synapse und federation_sender neustarten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
monit reload&lt;br /&gt;
monit restart all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nach Updates ebenfalls immer Hauptprozess und alle Worker neustarten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
monit restart all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sliding Sync Proxy ==&lt;br /&gt;
Zum Zeitpunkt dieser Anleitung werden aktiv neue Element Anwendungen (Element X) und ein neues Syncverfahren entwickelt um Matrix performanter und weniger ressourcenhungrig zu machen. Bei stärkerer Matrix Nutzung können die neuen Anwendungen besonders mobil schon eine große Entlastung sein.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;Ende 2024 wurden grundlegende Funktionen direkt in Synapse implementiert. Der Proxy wird nicht länger weiterentwickelt und sollte deinstalliert werden (nicht vergessen die .well-known zurück zu ändern).&amp;lt;/strong&amp;gt; Auch der 3rdparty Server [[Conduit]] bringt nativ Support für Sliding Sync.&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://matrix.org/docs/projects/server/synapse &lt;br /&gt;
* https://github.com/element-hq/synapse&lt;br /&gt;
* https://github.com/element-hq/synapse/blob/master/INSTALL.md&lt;br /&gt;
* https://github.com/matrix-org/sliding-sync&lt;br /&gt;
* https://matrix.org/docs/spec/&lt;br /&gt;
* https://www.hostsharing.net/loesungen/matrix/&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/synapse&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/element&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Messenger]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Eigene Daemons]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Matrix_Synapse_installieren&amp;diff=7613</id>
		<title>Matrix Synapse installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Matrix_Synapse_installieren&amp;diff=7613"/>
		<updated>2026-08-04T08:59:48Z</updated>

		<summary type="html">&lt;p&gt;Tim00: Benutzerverwaltung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Der Matrix Server &#039;&#039;Synapse&#039;&#039;, der sogenannte &#039;Homeserver&#039;, ist aktuell die einzige vollständige serverseitige Implementierung des Matrix-Protokolls.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gelb|Work in Progress|Leider funktioniert die Server-zu-Server-Kommunikation von Synapse hinter dem Apache-Proxy mit den genannten Rewrite-Rules nicht. Bitten Sie dazu den Service, Ihren Apache VHost individuell für den Matrix Server anzupassen.}}&lt;br /&gt;
&lt;br /&gt;
Die hier beschriebene Installation benötigt bei Hostsharing die Paket-Option &amp;quot;RAM&amp;quot;. Benötigt werden min. 512 MB. Im Managed Webspace ist diese Option kostenpflichtig: https://www.hostsharing.net/angebote/managed-webspace/ gebucht werden muss der RAM auch bei einem Managed-Server.&lt;br /&gt;
Wir empfehlen für den Betrieb einen &#039;&#039;Managed Server&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt, wie man den Matrix-Homeserver Synapse auf der Managed Hosting Plattform von Hostsharing installieren kann. Dabei sind die User-IDs nach dem Schema @user:beispiel.de aufgebaut, der Homeserver an sich ist unter matrix.beispiel.de erreichbar.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von HSAdmin werden angelegt:&lt;br /&gt;
# Ein User als Service-User mit &#039;&#039;/bin/bash&#039;&#039; als Shell, zum Beispiel Beispiel: &#039;&#039;xyz00-matrix&#039;&#039;&lt;br /&gt;
# Eine Domain mit &#039;&#039;xyz00-matrix&#039;&#039; als Domain-Administrator, zum Beispiel &#039;&#039;matrix.beispiel.de&#039;&#039;&lt;br /&gt;
# Einen Postgresql-User &#039;&#039;xyz00_matrixuser&#039;&#039; mit Passwort &#039;&#039;meinPasswort&#039;&#039;&lt;br /&gt;
# Eine Postgresql-Datenbank &#039;&#039;xyz00_matrixdb&#039;&#039; mit Datenbank-Owner &#039;&#039;xyz00_matrixuser&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verwendeter IP-Port für den Server-Dienst:&lt;br /&gt;
# Synapse: localhost:32801&lt;br /&gt;
&lt;br /&gt;
== Installation von Synapse ==&lt;br /&gt;
&lt;br /&gt;
Installationsanleitung basierend auf https://matrix-org.github.io/synapse/latest/setup/installation.html#installing-as-a-python-module-from-pypi&lt;br /&gt;
&lt;br /&gt;
Als User &#039;&#039;xyz00-matrix&amp;quot; ein Python3 virtualenv erstellen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/synapse&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
python -m venv .venv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Synapse und Postgres-Dependencies installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
source ~/synapse/.venv/bin/activate&lt;br /&gt;
pip install pipenv&lt;br /&gt;
pipenv install matrix-synapse[postgres,oidc] lxml authlib&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Initiale Konfiguration mit richtigem server-name &amp;quot;beispiel.de&amp;quot; generieren, außerdem im laufenden Betrieb keine Statistiken an Matrix.org senden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
pipenv run python -m synapse.app.homeserver --server-name beispiel.de --config-path homeserver.yaml --generate-config --report-stats=no&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration von Synapse ==&lt;br /&gt;
&lt;br /&gt;
In die initial generierte Konfiguration muss noch die Port- und Datenbank-Konfiguration eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
Port: Innerhalb der listener-section den Port 8008 auf 32801 (wie initial definiert) ändern, alles andere beibehalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
- port: 32801&lt;br /&gt;
    tls: false&lt;br /&gt;
    bind_addresses: [&#039;::1&#039;, &#039;127.0.0.1&#039;]&lt;br /&gt;
    type: http&lt;br /&gt;
    x_forwarded: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Postgres-Datenbank:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
database:&lt;br /&gt;
    # The database engine name&lt;br /&gt;
    name: &amp;quot;psycopg2&amp;quot;&lt;br /&gt;
    # Arguments to pass to the engine&lt;br /&gt;
    args:&lt;br /&gt;
    host: &amp;quot;localhost&amp;quot;&lt;br /&gt;
    database: &amp;quot;xyz00_matrixdb&amp;quot;&lt;br /&gt;
    user: &amp;quot;xyz00_matrixuser&amp;quot;&lt;br /&gt;
    password: &amp;quot;meinPasswort&amp;quot;&lt;br /&gt;
    cp_min: 5&lt;br /&gt;
    cp_max: 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starten der Dienste  ==&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;Synapse&#039;&#039;-Dienst wird hier als Service-Unit im SystemD des Users eingetragen.&lt;br /&gt;
&lt;br /&gt;
Lege dazu die folgende Datei an: &#039;&#039;~/.config/systemd/user/synapse.service&#039;&#039; mit dem Inhalt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Synapse&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
WorkingDirectory=%h/synapse&lt;br /&gt;
Environment=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2&lt;br /&gt;
ExecStart=pipenv run python -m synapse.app.homeserver --config-path=%h/synapse/homeserver.yaml&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durch Aufruf der folgenden Kommandos wird der Dienst aktiviert und gestartet:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot; lines&amp;gt;&lt;br /&gt;
systemctl --user daemon-reload&lt;br /&gt;
systemctl --user enable synapse.service&lt;br /&gt;
systemctl --user start synapse.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Verwalten von Benutzern ==&lt;br /&gt;
&lt;br /&gt;
Mit den folgenden Befehlen kann ein Benutzer angelegt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
register_new_matrix_user -c homeserver.yaml --user &amp;lt;USERNAME&amp;gt; &amp;lt;--admin|--no-admin&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So kann ein Benutzer auch wieder deaktiviert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
user=&amp;lt;USERNAME&amp;gt;&lt;br /&gt;
domain=&amp;quot;https://&amp;lt;matrix.example.org&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
&lt;br /&gt;
url_user=`echo -n &amp;quot;$user&amp;quot; | jq -s -R -r @uri`&lt;br /&gt;
json=`curl -s --insecure -XPOST -d &#039;{&amp;quot;type&amp;quot;:&amp;quot;m.login.password&amp;quot;, &amp;quot;user&amp;quot;:&amp;quot;root&amp;quot;, &amp;quot;password&amp;quot;:&amp;quot;&#039;$password&#039;&amp;quot;}&#039; &amp;quot;https://$domain/_matrix/client/r0/login&amp;quot;`&lt;br /&gt;
access_token=`echo &amp;quot;$json&amp;quot; | jq -r &amp;quot;.access_token&amp;quot;`&lt;br /&gt;
&lt;br /&gt;
# see https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#deactivate-account&lt;br /&gt;
curl --insecure -XPOST -H &amp;quot;Authorization: Bearer $access_token&amp;quot; -H &amp;quot;Content-Type: application/json&amp;quot; -d \&lt;br /&gt;
  &#039;{&amp;quot;erase&amp;quot;: true}&#039; &amp;quot;$domain/_synapse/admin/v1/deactivate/$url_user&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ansonsten kann für die Benutzerverwaltung ein Keycloak installiert werden, und Synapse über OIDC an den Keycloak angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
== Einrichten des Apache VHost ==&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;~/doms/matrix.beispiel.de/.htaccess&#039;&#039; mit dem Editor der Wahl öffnen und &lt;br /&gt;
folgende Konfiguration einfügen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RewriteRule .* http://localhost:32801%{REQUEST_URI} [NE,proxy]&lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Well-Known unter beispiel.de ==&lt;br /&gt;
&lt;br /&gt;
Damit die User-Accounts das Format @user:beispiel.de haben, der Server aber unter matrix.beispiel.de erreichbar ist, müssen noch folgende zwei Dateien unter der Domain beispiel.de abgelegt werden:&lt;br /&gt;
&lt;br /&gt;
https://beispiel.de/.well-known/matrix/server&lt;br /&gt;
&amp;lt;syntaxhighlight lang=json line&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;m.server&amp;quot;: &amp;quot;matrix.beispiel.de:443&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://beispiel.de/.well-known/matrix/client&lt;br /&gt;
&amp;lt;syntaxhighlight lang=json line&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;m.homeserver&amp;quot;: {&lt;br /&gt;
        &amp;quot;base_url&amp;quot;: &amp;quot;https://matrix.beispiel.de&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;m.identity_server&amp;quot;: {&lt;br /&gt;
        &amp;quot;base_url&amp;quot;: &amp;quot;https://vector.im&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für die muss noch der CORS-Header Access-Control-Allow-Origin &amp;quot;*&amp;quot; gesetzt werden, damit die Datei aus beliebigem Riot-Web im Browser abrufbar ist. Dazu in den Ordner .well-known/matrix/ folgende .htaccess anlegen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
&amp;lt;IfModule mod_headers.c&amp;gt;&lt;br /&gt;
  Header set Access-Control-Allow-Origin &amp;quot;*&amp;quot;&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Dokumentation dazu findet man unter https://matrix.org/docs/spec/server_server/r0.1.2#get-well-known-matrix-server und https://matrix.org/docs/spec/client_server/r0.5.0#get-well-known-matrix-client&lt;br /&gt;
&lt;br /&gt;
== Update von Synapse ==&lt;br /&gt;
&lt;br /&gt;
Normalerweise sollte es so gehen, mit pipenv:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
pipenv update --outdated || echo &amp;quot;there are packages to update&amp;quot;&lt;br /&gt;
pipenv update&lt;br /&gt;
systemctl --user restart synapse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In seltenen Fällen gibt es Probleme bei den Abhängigkeiten, die schon wieder aktualisiert wurden, und nicht mehr kompatibel zum aktuellen Synapse sind.&lt;br /&gt;
Dann ist es zu empfehlen, Synapse mit der offiziellen poetry.lock Datei zu aktualisieren, um die Konflikte zu vermeiden.&lt;br /&gt;
&lt;br /&gt;
mit poetry:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user stop synapse.service&lt;br /&gt;
source ~/.venv/bin/activate&lt;br /&gt;
release=`curl -L https://api.github.com/repos/element-hq/synapse/releases/latest -s | jq -r &#039;.tag_name&#039;`&lt;br /&gt;
rm -Rf ~/synapse.src&lt;br /&gt;
git clone --depth 1 https://github.com/element-hq/synapse.git -b ${release} ~/synapse.src&lt;br /&gt;
cd ~/synapse.src&lt;br /&gt;
pip install poetry&lt;br /&gt;
poetry install --extras=postgres --extras=oidc&lt;br /&gt;
systemctl --user start synapse.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Föderation für den Synapse Server aktiviert ist, kann mit dem [https://federationtester.matrix.org/ Matrix Federation Tester] die eigene Instanz auf die laufende Version geprüft werden. Als Server nicht matrix.example.org eingeben, sondern den öffentlichen Namen, wo auch die Benutzernamen drauf laufen, z.B. example.org&lt;br /&gt;
&lt;br /&gt;
Ansonsten ist die laufende Version auch über die URL https://matrix.example.org/_synapse/admin/v1/server_version zu erfahren.&lt;br /&gt;
&lt;br /&gt;
== Element-Web ==&lt;br /&gt;
&lt;br /&gt;
Element-Web ist aus Server-Seite eine rein statische html+javascript-Kombination, daher:&lt;br /&gt;
&lt;br /&gt;
* Account und Domain anlegen (separat von der Synapse-Domain)&lt;br /&gt;
* [https://github.com/element-hq/element-web/releases/latest aktuelles element-web release] .tgz herunterladen&lt;br /&gt;
* Symlink von htdocs-ssl auf entpacktes element-web-Verzeichnis&lt;br /&gt;
* config.sample.json in config.json kopieren und Matrix-Homeserver-Einträge anpassen&lt;br /&gt;
* Piwik aus config.json entfernen&lt;br /&gt;
&lt;br /&gt;
== SAML mit Synapse ==&lt;br /&gt;
&lt;br /&gt;
Synapse unterstützt mit Version 1.1.0 SAML. Dazu wie folgt vorgehen:&lt;br /&gt;
&lt;br /&gt;
Das Paket xmlsec1 muss installiert sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
$ xmlsec1  --version&lt;br /&gt;
xmlsec1 1.2.23 (openssl)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Python-Paket pysaml2 installieren&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
pipenv shell&lt;br /&gt;
pipenv install pysaml2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der homeserver.yaml die SAML-Direktiven einkommentieren, hier mit dem Beispiel eines SAML IdP unter https://login.beispiel.de/simplesaml/saml2/idp/metadata.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
# Once SAML support is enabled, a metadata file will be exposed at&lt;br /&gt;
# https://&amp;lt;server&amp;gt;:&amp;lt;port&amp;gt;/_matrix/saml2/metadata.xml, which you may be able to &lt;br /&gt;
# use to configure your SAML IdP with. Alternatively, you can manually configure&lt;br /&gt;
# the IdP to use an ACS location of&lt;br /&gt;
# https://&amp;lt;server&amp;gt;:&amp;lt;port&amp;gt;/_matrix/saml2/authn_response.&lt;br /&gt;
#&lt;br /&gt;
saml2_config:&lt;br /&gt;
    sp_config:&lt;br /&gt;
        # point this to the IdP&#039;s metadata. You can use either a local file or&lt;br /&gt;
        # (preferably) a URL.&lt;br /&gt;
        metadata:&lt;br /&gt;
        #local: [&amp;quot;saml2/idp.xml&amp;quot;]&lt;br /&gt;
        remote:&lt;br /&gt;
            - url: https://login.beispiel.de/simplesaml/saml2/idp/metadata.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wichtig ist außerdem, dass die public_baseurl in der homeserver.yaml gesetzt ist, damit Synapse weiß, wie es erreichbar ist und dies in seine SP-Metadaten einbauen kann:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
public_baseurl: https://matrix.beispiel.de/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Service-Provider-Konfiguration als XML bekommt man von Synapse dann wie schon in der homeserver.yaml als Kommentar beschrieben, unter https://matrix.beispiel.de/_matrix/saml2/metadata.xml&lt;br /&gt;
&lt;br /&gt;
Diese dann in den SAML-IdP-importieren und dann sollte der Single-Sign-On via SAML funktionieren.&lt;br /&gt;
&lt;br /&gt;
== Federation Sender Worker für Synapse ==&lt;br /&gt;
&lt;br /&gt;
Zur Parallelisierung bietet Synapse das Konzept &amp;quot;Worker&amp;quot; an, die spezifische Aufgaben übernehmen, damit der Hauptprozess diese nicht durchführen muss.&lt;br /&gt;
&lt;br /&gt;
Details dazu: https://github.com/matrix-org/synapse/blob/master/docs/workers.md&lt;br /&gt;
&lt;br /&gt;
Ein einfach einzurichtender Worker, der auch viel Last abfedert, ist der Federation Sender Worker, da das Verschicken des Federation-Traffics 10-50% der Serverlast ausmacht.&lt;br /&gt;
&lt;br /&gt;
In der homeserver.yaml die Worker-Konfiguration aktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
## Worker ##&lt;br /&gt;
worker_app: synapse.app.homeserver&lt;br /&gt;
daemonize: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und dazugehörige Listener (Abschnitt listener:) aktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
# The TCP replication port&lt;br /&gt;
- port: 32892&lt;br /&gt;
  bind_address: &#039;127.0.0.1&#039;&lt;br /&gt;
  type: replication&lt;br /&gt;
# The HTTP replication port&lt;br /&gt;
- port: 32893&lt;br /&gt;
  bind_address: &#039;127.0.0.1&#039;&lt;br /&gt;
  type: http&lt;br /&gt;
  resources:&lt;br /&gt;
   - names: [replication]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen, die Worker machen sollen, in der homeserver.yaml deaktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
# disable federation sending here, use worker for it&lt;br /&gt;
send_federation: False&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann Verzeichnis synapse/workers anlegen, darin federation_sender.yaml:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
worker_app: synapse.app.federation_sender&lt;br /&gt;
&lt;br /&gt;
# The replication listener on the synapse to talk to.&lt;br /&gt;
worker_replication_host: 127.0.0.1&lt;br /&gt;
worker_replication_port: 32892&lt;br /&gt;
worker_replication_http_port: 32893&lt;br /&gt;
&lt;br /&gt;
worker_daemonize: True&lt;br /&gt;
worker_pid_file: /home/pacs/xyz00/users/matrix/synapse/federation_sender.pid&lt;br /&gt;
worker_log_config: /home/pacs/xyz00/users/matrix/synapse/federation_sender.log.config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
.monitrc um worker erweitern:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
check process federation_sender with pidfile /home/pacs/xyz00/users/matrix/synapse/federation_sender.pid&lt;br /&gt;
    start program &amp;quot;/bin/bash -c &#039;export VIRTUAL_ENV=$HOME/synapse/env &amp;amp;&amp;amp; export PATH=$VIRTUAL_ENV/bin:$PATH &amp;amp;&amp;amp; cd $HOME/synapse &amp;amp;&amp;amp; synctl -w workers/federation_sender.yaml start&#039;&amp;quot;&lt;br /&gt;
    stop program &amp;quot;/bin/bash -c &#039;/bin/kill $( cat $HOME/synapse/federation_sender.pid )&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Monit neu laden und synapse und federation_sender neustarten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
monit reload&lt;br /&gt;
monit restart all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nach Updates ebenfalls immer Hauptprozess und alle Worker neustarten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
monit restart all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sliding Sync Proxy ==&lt;br /&gt;
Zum Zeitpunkt dieser Anleitung werden aktiv neue Element Anwendungen (Element X) und ein neues Syncverfahren entwickelt um Matrix performanter und weniger ressourcenhungrig zu machen. Bei stärkerer Matrix Nutzung können die neuen Anwendungen besonders mobil schon eine große Entlastung sein.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;Ende 2024 wurden grundlegende Funktionen direkt in Synapse implementiert. Der Proxy wird nicht länger weiterentwickelt und sollte deinstalliert werden (nicht vergessen die .well-known zurück zu ändern).&amp;lt;/strong&amp;gt; Auch der 3rdparty Server [[Conduit]] bringt nativ Support für Sliding Sync.&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://matrix.org/docs/projects/server/synapse &lt;br /&gt;
* https://github.com/element-hq/synapse&lt;br /&gt;
* https://github.com/element-hq/synapse/blob/master/INSTALL.md&lt;br /&gt;
* https://github.com/matrix-org/sliding-sync&lt;br /&gt;
* https://matrix.org/docs/spec/&lt;br /&gt;
* https://www.hostsharing.net/loesungen/matrix/&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/synapse&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/element&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Messenger]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Eigene Daemons]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Matrix_Synapse_installieren&amp;diff=7612</id>
		<title>Matrix Synapse installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Matrix_Synapse_installieren&amp;diff=7612"/>
		<updated>2026-08-04T08:54:40Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Installation von Synapse */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Der Matrix Server &#039;&#039;Synapse&#039;&#039;, der sogenannte &#039;Homeserver&#039;, ist aktuell die einzige vollständige serverseitige Implementierung des Matrix-Protokolls.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gelb|Work in Progress|Leider funktioniert die Server-zu-Server-Kommunikation von Synapse hinter dem Apache-Proxy mit den genannten Rewrite-Rules nicht. Bitten Sie dazu den Service, Ihren Apache VHost individuell für den Matrix Server anzupassen.}}&lt;br /&gt;
&lt;br /&gt;
Die hier beschriebene Installation benötigt bei Hostsharing die Paket-Option &amp;quot;RAM&amp;quot;. Benötigt werden min. 512 MB. Im Managed Webspace ist diese Option kostenpflichtig: https://www.hostsharing.net/angebote/managed-webspace/ gebucht werden muss der RAM auch bei einem Managed-Server.&lt;br /&gt;
Wir empfehlen für den Betrieb einen &#039;&#039;Managed Server&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung beschreibt, wie man den Matrix-Homeserver Synapse auf der Managed Hosting Plattform von Hostsharing installieren kann. Dabei sind die User-IDs nach dem Schema @user:beispiel.de aufgebaut, der Homeserver an sich ist unter matrix.beispiel.de erreichbar.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von HSAdmin werden angelegt:&lt;br /&gt;
# Ein User als Service-User mit &#039;&#039;/bin/bash&#039;&#039; als Shell, zum Beispiel Beispiel: &#039;&#039;xyz00-matrix&#039;&#039;&lt;br /&gt;
# Eine Domain mit &#039;&#039;xyz00-matrix&#039;&#039; als Domain-Administrator, zum Beispiel &#039;&#039;matrix.beispiel.de&#039;&#039;&lt;br /&gt;
# Einen Postgresql-User &#039;&#039;xyz00_matrixuser&#039;&#039; mit Passwort &#039;&#039;meinPasswort&#039;&#039;&lt;br /&gt;
# Eine Postgresql-Datenbank &#039;&#039;xyz00_matrixdb&#039;&#039; mit Datenbank-Owner &#039;&#039;xyz00_matrixuser&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verwendeter IP-Port für den Server-Dienst:&lt;br /&gt;
# Synapse: localhost:32801&lt;br /&gt;
&lt;br /&gt;
== Installation von Synapse ==&lt;br /&gt;
&lt;br /&gt;
Installationsanleitung basierend auf https://matrix-org.github.io/synapse/latest/setup/installation.html#installing-as-a-python-module-from-pypi&lt;br /&gt;
&lt;br /&gt;
Als User &#039;&#039;xyz00-matrix&amp;quot; ein Python3 virtualenv erstellen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p ~/synapse&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
python -m venv .venv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Synapse und Postgres-Dependencies installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
source ~/synapse/.venv/bin/activate&lt;br /&gt;
pip install pipenv&lt;br /&gt;
pipenv install matrix-synapse[postgres,oidc] lxml authlib&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Initiale Konfiguration mit richtigem server-name &amp;quot;beispiel.de&amp;quot; generieren, außerdem im laufenden Betrieb keine Statistiken an Matrix.org senden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
pipenv run python -m synapse.app.homeserver --server-name beispiel.de --config-path homeserver.yaml --generate-config --report-stats=no&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration von Synapse ==&lt;br /&gt;
&lt;br /&gt;
In die initial generierte Konfiguration muss noch die Port- und Datenbank-Konfiguration eingetragen werden:&lt;br /&gt;
&lt;br /&gt;
Port: Innerhalb der listener-section den Port 8008 auf 32801 (wie initial definiert) ändern, alles andere beibehalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
- port: 32801&lt;br /&gt;
    tls: false&lt;br /&gt;
    bind_addresses: [&#039;::1&#039;, &#039;127.0.0.1&#039;]&lt;br /&gt;
    type: http&lt;br /&gt;
    x_forwarded: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Postgres-Datenbank:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
database:&lt;br /&gt;
    # The database engine name&lt;br /&gt;
    name: &amp;quot;psycopg2&amp;quot;&lt;br /&gt;
    # Arguments to pass to the engine&lt;br /&gt;
    args:&lt;br /&gt;
    host: &amp;quot;localhost&amp;quot;&lt;br /&gt;
    database: &amp;quot;xyz00_matrixdb&amp;quot;&lt;br /&gt;
    user: &amp;quot;xyz00_matrixuser&amp;quot;&lt;br /&gt;
    password: &amp;quot;meinPasswort&amp;quot;&lt;br /&gt;
    cp_min: 5&lt;br /&gt;
    cp_max: 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starten der Dienste  ==&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;Synapse&#039;&#039;-Dienst wird hier als Service-Unit im SystemD des Users eingetragen.&lt;br /&gt;
&lt;br /&gt;
Lege dazu die folgende Datei an: &#039;&#039;~/.config/systemd/user/synapse.service&#039;&#039; mit dem Inhalt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Synapse&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
WorkingDirectory=%h/synapse&lt;br /&gt;
Environment=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2&lt;br /&gt;
ExecStart=pipenv run python -m synapse.app.homeserver --config-path=%h/synapse/homeserver.yaml&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durch Aufruf der folgenden Kommandos wird der Dienst aktiviert und gestartet:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot; lines&amp;gt;&lt;br /&gt;
systemctl --user daemon-reload&lt;br /&gt;
systemctl --user enable synapse.service&lt;br /&gt;
systemctl --user start synapse.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Einrichten des Apache VHost ==&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;~/doms/matrix.beispiel.de/.htaccess&#039;&#039; mit dem Editor der Wahl öffnen und &lt;br /&gt;
folgende Konfiguration einfügen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RewriteRule .* http://localhost:32801%{REQUEST_URI} [NE,proxy]&lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Well-Known unter beispiel.de ==&lt;br /&gt;
&lt;br /&gt;
Damit die User-Accounts das Format @user:beispiel.de haben, der Server aber unter matrix.beispiel.de erreichbar ist, müssen noch folgende zwei Dateien unter der Domain beispiel.de abgelegt werden:&lt;br /&gt;
&lt;br /&gt;
https://beispiel.de/.well-known/matrix/server&lt;br /&gt;
&amp;lt;syntaxhighlight lang=json line&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;m.server&amp;quot;: &amp;quot;matrix.beispiel.de:443&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://beispiel.de/.well-known/matrix/client&lt;br /&gt;
&amp;lt;syntaxhighlight lang=json line&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;m.homeserver&amp;quot;: {&lt;br /&gt;
        &amp;quot;base_url&amp;quot;: &amp;quot;https://matrix.beispiel.de&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;m.identity_server&amp;quot;: {&lt;br /&gt;
        &amp;quot;base_url&amp;quot;: &amp;quot;https://vector.im&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für die muss noch der CORS-Header Access-Control-Allow-Origin &amp;quot;*&amp;quot; gesetzt werden, damit die Datei aus beliebigem Riot-Web im Browser abrufbar ist. Dazu in den Ordner .well-known/matrix/ folgende .htaccess anlegen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
&amp;lt;IfModule mod_headers.c&amp;gt;&lt;br /&gt;
  Header set Access-Control-Allow-Origin &amp;quot;*&amp;quot;&lt;br /&gt;
&amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Dokumentation dazu findet man unter https://matrix.org/docs/spec/server_server/r0.1.2#get-well-known-matrix-server und https://matrix.org/docs/spec/client_server/r0.5.0#get-well-known-matrix-client&lt;br /&gt;
&lt;br /&gt;
== Update von Synapse ==&lt;br /&gt;
&lt;br /&gt;
Normalerweise sollte es so gehen, mit pipenv:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
pipenv update --outdated || echo &amp;quot;there are packages to update&amp;quot;&lt;br /&gt;
pipenv update&lt;br /&gt;
systemctl --user restart synapse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In seltenen Fällen gibt es Probleme bei den Abhängigkeiten, die schon wieder aktualisiert wurden, und nicht mehr kompatibel zum aktuellen Synapse sind.&lt;br /&gt;
Dann ist es zu empfehlen, Synapse mit der offiziellen poetry.lock Datei zu aktualisieren, um die Konflikte zu vermeiden.&lt;br /&gt;
&lt;br /&gt;
mit poetry:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user stop synapse.service&lt;br /&gt;
source ~/.venv/bin/activate&lt;br /&gt;
release=`curl -L https://api.github.com/repos/element-hq/synapse/releases/latest -s | jq -r &#039;.tag_name&#039;`&lt;br /&gt;
rm -Rf ~/synapse.src&lt;br /&gt;
git clone --depth 1 https://github.com/element-hq/synapse.git -b ${release} ~/synapse.src&lt;br /&gt;
cd ~/synapse.src&lt;br /&gt;
pip install poetry&lt;br /&gt;
poetry install --extras=postgres --extras=oidc&lt;br /&gt;
systemctl --user start synapse.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Föderation für den Synapse Server aktiviert ist, kann mit dem [https://federationtester.matrix.org/ Matrix Federation Tester] die eigene Instanz auf die laufende Version geprüft werden. Als Server nicht matrix.example.org eingeben, sondern den öffentlichen Namen, wo auch die Benutzernamen drauf laufen, z.B. example.org&lt;br /&gt;
&lt;br /&gt;
Ansonsten ist die laufende Version auch über die URL https://matrix.example.org/_synapse/admin/v1/server_version zu erfahren.&lt;br /&gt;
&lt;br /&gt;
== Element-Web ==&lt;br /&gt;
&lt;br /&gt;
Element-Web ist aus Server-Seite eine rein statische html+javascript-Kombination, daher:&lt;br /&gt;
&lt;br /&gt;
* Account und Domain anlegen (separat von der Synapse-Domain)&lt;br /&gt;
* [https://github.com/element-hq/element-web/releases/latest aktuelles element-web release] .tgz herunterladen&lt;br /&gt;
* Symlink von htdocs-ssl auf entpacktes element-web-Verzeichnis&lt;br /&gt;
* config.sample.json in config.json kopieren und Matrix-Homeserver-Einträge anpassen&lt;br /&gt;
* Piwik aus config.json entfernen&lt;br /&gt;
&lt;br /&gt;
== SAML mit Synapse ==&lt;br /&gt;
&lt;br /&gt;
Synapse unterstützt mit Version 1.1.0 SAML. Dazu wie folgt vorgehen:&lt;br /&gt;
&lt;br /&gt;
Das Paket xmlsec1 muss installiert sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
$ xmlsec1  --version&lt;br /&gt;
xmlsec1 1.2.23 (openssl)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Python-Paket pysaml2 installieren&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/synapse&lt;br /&gt;
pipenv shell&lt;br /&gt;
pipenv install pysaml2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der homeserver.yaml die SAML-Direktiven einkommentieren, hier mit dem Beispiel eines SAML IdP unter https://login.beispiel.de/simplesaml/saml2/idp/metadata.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
# Once SAML support is enabled, a metadata file will be exposed at&lt;br /&gt;
# https://&amp;lt;server&amp;gt;:&amp;lt;port&amp;gt;/_matrix/saml2/metadata.xml, which you may be able to &lt;br /&gt;
# use to configure your SAML IdP with. Alternatively, you can manually configure&lt;br /&gt;
# the IdP to use an ACS location of&lt;br /&gt;
# https://&amp;lt;server&amp;gt;:&amp;lt;port&amp;gt;/_matrix/saml2/authn_response.&lt;br /&gt;
#&lt;br /&gt;
saml2_config:&lt;br /&gt;
    sp_config:&lt;br /&gt;
        # point this to the IdP&#039;s metadata. You can use either a local file or&lt;br /&gt;
        # (preferably) a URL.&lt;br /&gt;
        metadata:&lt;br /&gt;
        #local: [&amp;quot;saml2/idp.xml&amp;quot;]&lt;br /&gt;
        remote:&lt;br /&gt;
            - url: https://login.beispiel.de/simplesaml/saml2/idp/metadata.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wichtig ist außerdem, dass die public_baseurl in der homeserver.yaml gesetzt ist, damit Synapse weiß, wie es erreichbar ist und dies in seine SP-Metadaten einbauen kann:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
public_baseurl: https://matrix.beispiel.de/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Service-Provider-Konfiguration als XML bekommt man von Synapse dann wie schon in der homeserver.yaml als Kommentar beschrieben, unter https://matrix.beispiel.de/_matrix/saml2/metadata.xml&lt;br /&gt;
&lt;br /&gt;
Diese dann in den SAML-IdP-importieren und dann sollte der Single-Sign-On via SAML funktionieren.&lt;br /&gt;
&lt;br /&gt;
== Federation Sender Worker für Synapse ==&lt;br /&gt;
&lt;br /&gt;
Zur Parallelisierung bietet Synapse das Konzept &amp;quot;Worker&amp;quot; an, die spezifische Aufgaben übernehmen, damit der Hauptprozess diese nicht durchführen muss.&lt;br /&gt;
&lt;br /&gt;
Details dazu: https://github.com/matrix-org/synapse/blob/master/docs/workers.md&lt;br /&gt;
&lt;br /&gt;
Ein einfach einzurichtender Worker, der auch viel Last abfedert, ist der Federation Sender Worker, da das Verschicken des Federation-Traffics 10-50% der Serverlast ausmacht.&lt;br /&gt;
&lt;br /&gt;
In der homeserver.yaml die Worker-Konfiguration aktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
## Worker ##&lt;br /&gt;
worker_app: synapse.app.homeserver&lt;br /&gt;
daemonize: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und dazugehörige Listener (Abschnitt listener:) aktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
# The TCP replication port&lt;br /&gt;
- port: 32892&lt;br /&gt;
  bind_address: &#039;127.0.0.1&#039;&lt;br /&gt;
  type: replication&lt;br /&gt;
# The HTTP replication port&lt;br /&gt;
- port: 32893&lt;br /&gt;
  bind_address: &#039;127.0.0.1&#039;&lt;br /&gt;
  type: http&lt;br /&gt;
  resources:&lt;br /&gt;
   - names: [replication]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen, die Worker machen sollen, in der homeserver.yaml deaktivieren:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
# disable federation sending here, use worker for it&lt;br /&gt;
send_federation: False&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dann Verzeichnis synapse/workers anlegen, darin federation_sender.yaml:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
worker_app: synapse.app.federation_sender&lt;br /&gt;
&lt;br /&gt;
# The replication listener on the synapse to talk to.&lt;br /&gt;
worker_replication_host: 127.0.0.1&lt;br /&gt;
worker_replication_port: 32892&lt;br /&gt;
worker_replication_http_port: 32893&lt;br /&gt;
&lt;br /&gt;
worker_daemonize: True&lt;br /&gt;
worker_pid_file: /home/pacs/xyz00/users/matrix/synapse/federation_sender.pid&lt;br /&gt;
worker_log_config: /home/pacs/xyz00/users/matrix/synapse/federation_sender.log.config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
.monitrc um worker erweitern:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
check process federation_sender with pidfile /home/pacs/xyz00/users/matrix/synapse/federation_sender.pid&lt;br /&gt;
    start program &amp;quot;/bin/bash -c &#039;export VIRTUAL_ENV=$HOME/synapse/env &amp;amp;&amp;amp; export PATH=$VIRTUAL_ENV/bin:$PATH &amp;amp;&amp;amp; cd $HOME/synapse &amp;amp;&amp;amp; synctl -w workers/federation_sender.yaml start&#039;&amp;quot;&lt;br /&gt;
    stop program &amp;quot;/bin/bash -c &#039;/bin/kill $( cat $HOME/synapse/federation_sender.pid )&#039;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Monit neu laden und synapse und federation_sender neustarten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
monit reload&lt;br /&gt;
monit restart all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nach Updates ebenfalls immer Hauptprozess und alle Worker neustarten&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
monit restart all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sliding Sync Proxy ==&lt;br /&gt;
Zum Zeitpunkt dieser Anleitung werden aktiv neue Element Anwendungen (Element X) und ein neues Syncverfahren entwickelt um Matrix performanter und weniger ressourcenhungrig zu machen. Bei stärkerer Matrix Nutzung können die neuen Anwendungen besonders mobil schon eine große Entlastung sein.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;Ende 2024 wurden grundlegende Funktionen direkt in Synapse implementiert. Der Proxy wird nicht länger weiterentwickelt und sollte deinstalliert werden (nicht vergessen die .well-known zurück zu ändern).&amp;lt;/strong&amp;gt; Auch der 3rdparty Server [[Conduit]] bringt nativ Support für Sliding Sync.&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://matrix.org/docs/projects/server/synapse &lt;br /&gt;
* https://github.com/element-hq/synapse&lt;br /&gt;
* https://github.com/element-hq/synapse/blob/master/INSTALL.md&lt;br /&gt;
* https://github.com/matrix-org/sliding-sync&lt;br /&gt;
* https://matrix.org/docs/spec/&lt;br /&gt;
* https://www.hostsharing.net/loesungen/matrix/&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/synapse&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/element&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Messenger]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Eigene Daemons]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Prozessmanagement_mit_systemd_im_Userspace&amp;diff=7611</id>
		<title>Prozessmanagement mit systemd im Userspace</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Prozessmanagement_mit_systemd_im_Userspace&amp;diff=7611"/>
		<updated>2026-08-03T10:31:07Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* RAM- und CPU-Limits */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Über systemd ==&lt;br /&gt;
&#039;&#039;systemd&#039;&#039; ist seit einigen Jahren das Init-System aller gängigen Linux-Distributionen. Der &#039;&#039;init&#039;&#039;-Prozess hat im laufenden System die Prozessnummer &amp;quot;1&amp;quot;. Er verwaltet alle anderen Prozesse als Kind-Prozesse.&lt;br /&gt;
&lt;br /&gt;
Auch ein normaler Account ohne besondere Privilegien kann systemd nutzen, um Prozesse im Userspace zu starten und zu kontrollieren. Auf der Hostsharing Managed Operations Platform kann jeder Account mit einer gültigen Login-Shell Dienste unter der Kontrolle von systemd starten. &lt;br /&gt;
&lt;br /&gt;
Im Hostsharing Managed Webspace ist es zwingend, systemd als Prozessmonitor für eigene Serverdienste zu nutzen; auf einem Hostsharing Managed Server ist es die empfohlene Vorgehensweise (&amp;quot;Best practice&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Eigene Serverdienste mit systemd ==&lt;br /&gt;
&lt;br /&gt;
Die systemd-Konfiguration wird in dem Verzeichnis des Benutzers eingerichtet, unter dem die Anwendung laufen soll.&lt;br /&gt;
In diesem Beispiel soll die Anwendung GotoSocial unter der Benutzerkennung von &#039;&#039;xyz00-service&#039;&#039; laufen.&lt;br /&gt;
Nachdem die Anwendung im Benutzer &#039;&#039;xyz00-service&#039;&#039; installiert wurde, erfolgt nun die Konfiguration von systemd in demselben Benutzer.&lt;br /&gt;
&lt;br /&gt;
Benutzer, die systemd steuern sollen, müssen über eine gültige Shell verfügen, so dass man sich per &#039;&#039;ssh&#039;&#039; oder vom Paketadmin mit dem Befehl &#039;&#039;sudo -i -u xyz00-service&#039;&#039; anmelden kann. &lt;br /&gt;
Die Umgebungsvariable &#039;&#039;XDG_RUNTIME_DIR&#039;&#039; sollte im Environment des Users gesetzt sein, wenn man erfolgreich angemeldet ist. Das testet man mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo $XDG_RUNTIME_DIR&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Ausgabe sollte sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
xyz00-service@h01:~$ echo $XDG_RUNTIME_DIR &lt;br /&gt;
/run/user/112345&lt;br /&gt;
xyz00-service@h01:~$ &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei wird statt &#039;&#039;112345&#039;&#039; eine andere Zahl erscheinen. Diese Zahl ist die numerische User-Id des Users &#039;&#039;xyz00-service&#039;&#039; im System.&lt;br /&gt;
&lt;br /&gt;
=== systemd Units ===&lt;br /&gt;
&lt;br /&gt;
Die systemd-Units für einen User werden im Verzeichnis &#039;&#039;$HOME/.config/systemd/user/&#039;&#039; verwaltet. Dieser Pfad ist fest vorgegeben. Der Pfad muss bei einem neuen Benutzer angelegt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mkdir -p $HOME/.config/systemd/user&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Verzeichnis wird für jeden Service eine Datei mit der Endung &#039;&#039;.service&#039;&#039; angelegt. In diesem Beispiel ist dies eine GotoSocial-Instanz. GotoSocial ist ein einfaches Binärprogramm, das in der Programmiersprache &#039;&#039;Go&#039;&#039; programmiert ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=GotoSocial Service&lt;br /&gt;
#After=my-redis.service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
WorkingDirectory=%h/gotosocial&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
ExecStart=%h/gotosocial/gotosocial --config-path %h/gotosocial/config.yaml server start&lt;br /&gt;
StandardOutput=append:%h/var/gotosocial.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Folgende Eigenschaften sind einstellbar:&lt;br /&gt;
&lt;br /&gt;
; After: Hier kann eingestellt werden, welcher Dienst bereits laufen muss, bevor dieser Dienst gestartet wird. Wenn GotoSocial eine Redis-Instanz benötigt, könnte das entsprechend eingestellt werden.&lt;br /&gt;
; Type=simple : &#039;&#039;simple&#039;&#039; ist die Voreinstellung und kann weggelassen werden. Evtl. braucht man auch &#039;&#039;forking&#039;&#039;, wenn ein Dienst als Daemon im Hintergrund startet. Wenn man die Wahl hat, sollte man den Dienst immer im Vordergrund starten und nicht forken.&lt;br /&gt;
; WorkingDirectory : ist das Verzeichnis, in dem der Dienst gestartet wird. %h ist in dieser Datei eine Abkürzung für das Home-Verzeichnis des Users.&lt;br /&gt;
; Environment : Hier wird die Variable &#039;&#039;PATH&#039;&#039; definiert. Man kann mehrere Einträge des Namens &#039;&#039;Environment&#039;&#039; eintragen und bei Bedarf eine beliebige Anzahl von Environment-Variablen definieren.&lt;br /&gt;
; ExecStart : Das Programm, das als Dienst ausgeführt wird. Man kann eine komplette Kommandozeile angeben.&lt;br /&gt;
; StandardOutput : Eine Log-Datei, in die die Standardausgabe des laufenden Dienstes geschrieben wird.&lt;br /&gt;
; StandardError : Entsprechend zu &#039;&#039;StandardOutput&#039;&#039;. Mit &#039;&#039;inherit&#039;&#039; wird die Datei von &#039;&#039;StandardOutput&#039;&#039; geerbt.&lt;br /&gt;
; Restart=always : Der Dienst soll grundsätzlich neu gestartet werden, wenn der Prozess unerwartet beendet wird.&lt;br /&gt;
; PrivateTmp=true : &#039;&#039;/tmp&#039;&#039; und &#039;&#039;/var/tmp&#039;&#039; werden temporär im Namespace gemountet, so dass sie nicht mit anderen Prozessen geteilt werden.&lt;br /&gt;
; WantedBy : sollte im Usermodus von systemd meistens &#039;&#039;default.target&#039;&#039; sein. Andere Targets sind z.B. &#039;&#039;base.target&#039;&#039; oder &#039;&#039;timers.target&#039;&#039;. Für eine komplette Liste: &amp;lt;code&amp;gt;systemctl list-units --user --type=target&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== RAM- und CPU-Limits ====&lt;br /&gt;
&lt;br /&gt;
Auf Wunsch kann man die RAM- und CPU-Ressourcen für den Dienst begrenzen. Dazu trägt man weitere Eigenschaften im Abschnitt &#039;&#039;Service&#039;&#039; ein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
[Service]&lt;br /&gt;
...&lt;br /&gt;
MemoryAccounting=true&lt;br /&gt;
CPUAccounting=true&lt;br /&gt;
MemoryHigh=512M&lt;br /&gt;
MemoryMax=768M&lt;br /&gt;
MemorySwapMax=128M&lt;br /&gt;
CPUQuota=50%&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; MemoryHigh : Weiches RAM-Limit, das ggf. überschritten werden kann, wenn es unvermeidlich ist.&lt;br /&gt;
; MemoryMax : Hartes, absolutes RAM-Limit.&lt;br /&gt;
; MemorySwapMax: Wenn wir den RAM begrenzen, sollten wir auch den Swap begrenzen, da ansonsten die SSDs langfristig Schaden nehmen bei zu viel Swapping&lt;br /&gt;
; CPUQuota : Maximale Belegung eines CPU-Threads in Prozent. Werte über 100% sind sinnvoll, wenn mehr als ein CPU-Thread verfügbar ist.&lt;br /&gt;
&lt;br /&gt;
==== Ausführliche Dokumentation der Direktiven ====&lt;br /&gt;
Eine ausführliche Dokumentation der Direktiven findet sich hier: &lt;br /&gt;
&lt;br /&gt;
https://www.freedesktop.org/software/systemd/man/latest/systemd.directives.html&lt;br /&gt;
&lt;br /&gt;
=== systemd Unit starten und stoppen ===&lt;br /&gt;
&lt;br /&gt;
Nachdem die systemd-Unit definiert ist, soll der Dienst gestartet werden. &lt;br /&gt;
Für die Verwaltung des Dienstes stehen die folgenden Kommandos zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
==== Reload ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl --user daemon-reload&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Konfigurationsdateien im Verzeichnis &#039;&#039;$HOME/.config/systemd/user/&#039;&#039; werden neu eingelesen. Dieses Kommando ist nach jeder Änderung einer  &#039;&#039;.service&#039;&#039;-Datei nötig.&lt;br /&gt;
&lt;br /&gt;
==== Start und Stopp ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl --user start gotosocial.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
bzw.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl --user stop gotosocial.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sind die Kommandos zum Starten und Beenden des Dienstes.&lt;br /&gt;
&lt;br /&gt;
==== Enable und Disable ====&lt;br /&gt;
&lt;br /&gt;
Wenn ein Dienst nach einem Reboot des Servers automatisch gestartet werden soll, muss er aktiviert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl --user enable gotosocial.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn er nicht automatisch nach einem Reboot starten soll, muss der Dienst entsprechend deaktiviert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl --user disable gotosocial.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sind die Kommandos, die den Dienst für einen Reboot des Servers aktivieren bzw. deaktivieren.&lt;br /&gt;
&lt;br /&gt;
==== Status ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl --user status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl --user status gotosocial.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
zeigen den Status aller Dienste des Users bzw. eines bestimmten Dienstes an.&lt;br /&gt;
&lt;br /&gt;
=== Ressourcen einer systemd Unit beschränken ===&lt;br /&gt;
&lt;br /&gt;
Mit den folgenden Befehlen können die zur Verfügung stehenden Ressourcen einer systemd Unit beschränkt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl --user set-property gitea.service MemoryMax=500M&lt;br /&gt;
systemctl --user set-property gitea.service CPUQuota=25%&lt;br /&gt;
systemctl --user set-property gitea.service TasksMax=100&lt;br /&gt;
systemctl --user daemon-reload&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zeitgesteuerte Ausführung mit systemd ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von systemd können auch wiederkehrende Aufgaben zeitgesteuert automatisiert werden.&lt;br /&gt;
Cronjobs, die früher für solche Zwecke benutzt wurden, lassen sich also durch systemd Units ersetzen.&lt;br /&gt;
Neben dem »service-file« wird dazu eine weitere Unit, nämlich ein »timer-file«, mit der Endung ».timer« angelegt und aktiviert. &lt;br /&gt;
&lt;br /&gt;
=== Einrichten des »service-files« ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash line&amp;gt;&lt;br /&gt;
$ cat $HOME/.config/systemd/user/my-cleanup.service &lt;br /&gt;
&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=My Cleanup Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=oneshot&lt;br /&gt;
ExecStart=%h/bin/cleanup-script&lt;br /&gt;
&lt;br /&gt;
ExecStopPost=/usr/local/bin/hs-notify-unit-failure %N %H %u $EXIT_CODE $SERVICE_RESULT %u&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bemerkung: das Skript hs-notify-unit-failure schickt bei einem Fehler des Hauptskripts eine E-Mail an den aktuellen Benutzer, die über .forward oder über .procmailrc auch an eine andere E-Mail Adresse weitergeleitet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch eine Umgebungsvariable (z.B. MAILTO) gesetzt werden, in der mehrere E-Mailadressen mit Komma getrennt sein dürfen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash line&amp;gt;&lt;br /&gt;
Environment=&amp;quot;MAILTO=email1@example.org,alarm@example.org&amp;quot;&lt;br /&gt;
ExecStopPost=/usr/local/bin/hs-notify-unit-failure %N %H %u $EXIT_CODE $SERVICE_RESULT $MAILTO&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Testen ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
$ systemctl --user start my-cleanup.service &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Einrichten des »timer-files« ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
$ cat $HOME/.config/systemd/user/my-cleanup.timer &lt;br /&gt;
&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Daily My Cleanup Timer&lt;br /&gt;
&lt;br /&gt;
[Timer]&lt;br /&gt;
OnCalendar=daily&lt;br /&gt;
RandomizedDelaySec=3600&lt;br /&gt;
Persistent=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=timers.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der RandomizedDelay bewirkt, dass der Prozess zufällig im Zeitraum einer Stunde gestartet wird.&lt;br /&gt;
Wenn mehrere Timer-Aufgaben täglich (daily) auf einem System gestartet werden, verhindert diese Einstellung, dass alle Prozesse exakt zur gleichen Zeit starten und das System eventuell überlasten.&lt;br /&gt;
&lt;br /&gt;
Die zufällige Verzögerung sollte in einem sinnvollen Verhältnis zur Frequenz der Zeitsteuerung erfolgen.&lt;br /&gt;
Bei täglich ausgeführten Aufgaben mag eine Stunde (3600 Sekunden) sinnvoll sein.&lt;br /&gt;
Bei Aufgaben, die stündlich ausgeführt werden, wählt man eine kürzere Verzögerung, zum Beispiel fünf Minuten. &lt;br /&gt;
&lt;br /&gt;
Die Syntax der Datei lässt sich mit diesem Befehl prüfen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
systemd-analyze verify $HOME/.config/systemd/user/my-cleanup.timer&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einzelne Kalendereinträge lassen sich mit Erklärung ausgeben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
systemd-analyze calendar &#039;*:0/2&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine ausführliche Dokumentation der Direktiven findet sich hier: &lt;br /&gt;
&lt;br /&gt;
https://www.freedesktop.org/software/systemd/man/latest/systemd.timer.html&lt;br /&gt;
&lt;br /&gt;
=== Aktivieren der zeitgesteuerten Ausführung ===&lt;br /&gt;
&lt;br /&gt;
Der Timer muss noch aktiviert und gestartet werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
$ systemctl --user enable my-cleanup.timer --now&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Übersicht über die Timer im aktuellen User ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
$ systemctl --user list-timers --all&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== RAM Kontingent eines Webspace ==&lt;br /&gt;
&lt;br /&gt;
Den aktuell belegten RAM eines Webspace &#039;&#039;xyz00&#039;&#039; kann man sich mit dem Befehl&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status pacs-xyz00.slice&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ansehen.&lt;br /&gt;
&lt;br /&gt;
Etwa in der fünften Zeile der Ausgabe findet man eine Angabe der Form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Memory: 58.4M (max: 14.8G available: 14.8G)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier sind aktuell 58,4 Megabyte RAM genutzt, es sind 14,8 Gigabyte RAM für den Webspace verfügbar. Der verfügbare RAM ist das gebuchte Kontingent. Das gebuchte Kontigent wird im Shared Hosting deutlich kleiner sein.&lt;br /&gt;
&lt;br /&gt;
Das RAM Kontingent wird in Schritten von jeweils 128 Ḿegabyte gebucht. Änderungen des RAM Kontingents für einen Webspace nimmt der Service unter [mailto:service@hostsharing.net service@hostsharing.net] entgegen, wie es bei anderen Paketoptionen die Vorgehensweise ist.&lt;br /&gt;
&lt;br /&gt;
== Beliebte Fehler ==&lt;br /&gt;
=== Fehler: Failed to connect to bus: No such file or directory ===&lt;br /&gt;
&lt;br /&gt;
Wenn ich einen systemctl Befehl ausführe, kommt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl --user daemon-reload&lt;br /&gt;
Failed to connect to bus: No such file or directory&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bitte prüfen, ob Lingering für den Benutzer aktiviert ist. Dazu muss im Hsadmin beim Benutzer die Login Shell &amp;lt;code&amp;gt;/bin/bash&amp;lt;/code&amp;gt; eingetragen sein. Falls das bereits der Fall ist, ist es vielleicht ein sehr alter Benutzer. Dann bitte kurz auf &amp;lt;code&amp;gt;/usr/bin/passwd&amp;lt;/code&amp;gt; stellen, und dann wieder auf &amp;lt;code&amp;gt;/bin/bash&amp;lt;/code&amp;gt; zurückstellen.&lt;br /&gt;
&lt;br /&gt;
Evtl. hilft es auch, die Umgebungsvariable XDG_RUNTIME_DIR zu setzen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
export XDG_RUNTIME_DIR=/run/user/$UID&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das kann auch in die Datei &amp;lt;code&amp;gt;$HOME/.profile&amp;lt;/code&amp;gt; eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
=== Fehler: Beim Starten passiert nichts ===&lt;br /&gt;
&lt;br /&gt;
Ich hatte das Problem bei einem Redis Dienst. Er stoppte innerhalb von Millisekunden. In der Log Datei stand nichts.&lt;br /&gt;
&lt;br /&gt;
Ursache: in der Service Datei war bei &amp;lt;code&amp;gt;WorkingDirectory&amp;lt;/code&amp;gt; ein nicht existierendes Verzeichnis eingetragen.&lt;br /&gt;
&lt;br /&gt;
= weiterführende Links =&lt;br /&gt;
&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/latest/systemd.directives.html&lt;br /&gt;
* https://www.freedesktop.org/software/systemd/man/latest/systemd.timer.html&lt;br /&gt;
* https://documentation.suse.com/smart/systems-management/html/systemd-working-with-timers/index.html#systemd-timer-catchup&lt;br /&gt;
* https://wiki.archlinux.org/title/Systemd/Timers#As_a_cron_replacement&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:systemd]]&lt;br /&gt;
[[Kategorie:Eigene Daemons]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=ListMonk_installieren&amp;diff=7610</id>
		<title>ListMonk installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=ListMonk_installieren&amp;diff=7610"/>
		<updated>2026-08-01T21:32:59Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== ListMonk ==&lt;br /&gt;
ListMonk [https://listmonk.app/] ist ein Newsletter-Manager zum Selbsthosten, und steht unter der Open Source Lizenz AGPLv3.&lt;br /&gt;
&lt;br /&gt;
Monk hat in diesem Fall nichts mit einem Mönch zu tun, sondern ist eine versteckte Anspielung auf Monkey, da ListMonk eine Alternative zu MailChimp (Chimpanse) ist.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039; Listmonk wirbt damit, [https://github.com/knadh/listmonk/blob/master/README.md Newsletter- und Mailinglisten-Manager] zu sein. Laut [https://github.com/knadh/listmonk/issues/1355 Fehlerbericht] ist das Tool aber lediglich für Einweg-Kommunikation (Newsletter) vorgesehen.&lt;br /&gt;
&lt;br /&gt;
== Zur Technik ==&lt;br /&gt;
ListMonk ist in Go geschrieben, und wird als ein einziges Binary (Programm) installiert. Man muss im Shared Webspace bei Hostsharing einen Service dazu buchen, oder man setzt es auf einem Managed Server von Hostsharing ein.&lt;br /&gt;
&lt;br /&gt;
Im Hintergrund wird PostgreSQL als Datenbank benutzt.&lt;br /&gt;
&lt;br /&gt;
ListMonk bietet Anmeldungen per Double-Opt-In, und es gibt auch eine API für die Integration mit CRM/ERP Systemen (https://listmonk.app/docs/apis/apis/).&lt;br /&gt;
&lt;br /&gt;
== Zur Installation ==&lt;br /&gt;
Die Installation ist recht einfach: https://listmonk.app/docs/installation/&lt;br /&gt;
&lt;br /&gt;
* Das Programm beispielsweise [https://github.com/knadh/listmonk/releases auf Github herunterladen] und entpacken&lt;br /&gt;
* Vorher den Hostsharing Service um eine freie Port Nummer fragen.&lt;br /&gt;
* Eine Datenbank anlegen&lt;br /&gt;
* Mit [[systemd]] wird das Programm als Dienst gestartet. Hierzu wird das Verzeichnis &amp;lt;code&amp;gt;~/.config/systemd/user/&amp;lt;/code&amp;gt; erstellt und eine .service Datei angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Listmonk&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
Restart=on-abort&lt;br /&gt;
WorkingDirectory=/home/pacs/xyz00/users/newsletter&lt;br /&gt;
# --config mit vollständigem Pfad zum Configfile falls nicht im WorkingDirectory&lt;br /&gt;
ExecStart=/home/pacs/xyz00/users/newsletter/bin/listmonk&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start und aktivieren von Autostart mittels &amp;lt;code&amp;gt;systemctl enable --now --user listmonk&amp;lt;/code&amp;gt;&lt;br /&gt;
* Beispiel Webserver--Konfiguration unter &amp;lt;code&amp;gt;doms/meine-domain/htdocs-ssl/.htaccess&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot; line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
# Port entsprechend der config.toml nach Absprache mit Service s.o.&lt;br /&gt;
RewriteRule ^(.*) http://127.0.0.1:9000/$1 [proxy,last]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Installation mit Ansible Skript ===&lt;br /&gt;
Es gibt ein Ansible Skript für Hostsharing [https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/listmonk], das die Installation automatisiert vornimmt, und schon den SMTP und POP Zugang konfiguriert.&lt;br /&gt;
&lt;br /&gt;
Dort kann man sicherlich auch Feinheiten der Installation abschauen, wenn man ListMonk manuell installieren will.&lt;br /&gt;
&lt;br /&gt;
== Zur Bedienung ==&lt;br /&gt;
&lt;br /&gt;
Hier ist ein Bildschirmfoto zur Einrichtung von SMTP für den Versand der E-Mails:&lt;br /&gt;
&lt;br /&gt;
[[Datei:ListMonk SMTPSetup.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hier ist ein Bildschirmfoto zur Generierung des Formulars zur Anmeldung für einen Newsletter:&lt;br /&gt;
&lt;br /&gt;
[[Datei:ListMonk SubscriptionForm.png]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://listmonk.app/ Projektseite&lt;br /&gt;
* https://github.com/knadh/listmonk ListMonk auf Github&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible.app.listmonk Ansible Rolle für Hostsharing&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:Newsletterversand]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=ListMonk_installieren&amp;diff=7609</id>
		<title>ListMonk installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=ListMonk_installieren&amp;diff=7609"/>
		<updated>2026-08-01T21:32:44Z</updated>

		<summary type="html">&lt;p&gt;Tim00: aktualisierter Link zur Ansible Rolle&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== ListMonk ==&lt;br /&gt;
ListMonk [https://listmonk.app/] ist ein Newsletter-Manager zum Selbsthosten, und steht unter der Open Source Lizenz AGPLv3.&lt;br /&gt;
&lt;br /&gt;
Monk hat in diesem Fall nichts mit einem Mönch zu tun, sondern ist eine versteckte Anspielung auf Monkey, da ListMonk eine Alternative zu MailChimp (Chimpanse) ist.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039; Listmonk wirbt damit, [https://github.com/knadh/listmonk/blob/master/README.md Newsletter- und Mailinglisten-Manager] zu sein. Laut [https://github.com/knadh/listmonk/issues/1355 Fehlerbericht] ist das Tool aber lediglich für Einweg-Kommunikation (Newsletter) vorgesehen.&lt;br /&gt;
&lt;br /&gt;
== Zur Technik ==&lt;br /&gt;
ListMonk ist in Go geschrieben, und wird als ein einziges Binary (Programm) installiert. Man muss im Shared Webspace bei Hostsharing einen Service dazu buchen, oder man setzt es auf einem Managed Server von Hostsharing ein.&lt;br /&gt;
&lt;br /&gt;
Im Hintergrund wird PostgreSQL als Datenbank benutzt.&lt;br /&gt;
&lt;br /&gt;
ListMonk bietet Anmeldungen per Double-Opt-In, und es gibt auch eine API für die Integration mit CRM/ERP Systemen (https://listmonk.app/docs/apis/apis/).&lt;br /&gt;
&lt;br /&gt;
== Zur Installation ==&lt;br /&gt;
Die Installation ist recht einfach: https://listmonk.app/docs/installation/&lt;br /&gt;
&lt;br /&gt;
* Das Programm beispielsweise [https://github.com/knadh/listmonk/releases auf Github herunterladen] und entpacken&lt;br /&gt;
* Vorher den Hostsharing Service um eine freie Port Nummer fragen.&lt;br /&gt;
* Eine Datenbank anlegen&lt;br /&gt;
* Mit [[systemd]] wird das Programm als Dienst gestartet. Hierzu wird das Verzeichnis &amp;lt;code&amp;gt;~/.config/systemd/user/&amp;lt;/code&amp;gt; erstellt und eine .service Datei angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Listmonk&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
Restart=on-abort&lt;br /&gt;
WorkingDirectory=/home/pacs/xyz00/users/newsletter&lt;br /&gt;
# --config mit vollständigem Pfad zum Configfile falls nicht im WorkingDirectory&lt;br /&gt;
ExecStart=/home/pacs/xyz00/users/newsletter/bin/listmonk&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start und aktivieren von Autostart mittels &amp;lt;code&amp;gt;systemctl enable --now --user listmonk&amp;lt;/code&amp;gt;&lt;br /&gt;
* Beispiel Webserver--Konfiguration unter &amp;lt;code&amp;gt;doms/meine-domain/htdocs-ssl/.htaccess&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot; line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
# Port entsprechend der config.toml nach Absprache mit Service s.o.&lt;br /&gt;
RewriteRule ^(.*) http://127.0.0.1:9000/$1 [proxy,last]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Installation mit Ansible Skript ===&lt;br /&gt;
Es gibt ein Ansible Skript für Hostsharing [https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/listmonk], das die Installation automatisiert vornimmt, und schon den SMTP und POP Zugang konfiguriert.&lt;br /&gt;
&lt;br /&gt;
Dort kann man sicherlich auch Feinheiten der Installation abschauen, wenn man ListMonk manuell installieren will.&lt;br /&gt;
&lt;br /&gt;
== Zur Bedienung ==&lt;br /&gt;
&lt;br /&gt;
Hier ist ein Bildschirmfoto zur Einrichtung von SMTP für den Versand der E-Mails:&lt;br /&gt;
&lt;br /&gt;
[[Datei:ListMonk SMTPSetup.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hier ist ein Bildschirmfoto zur Generierung des Formulars zur Anmeldung für einen Newsletter:&lt;br /&gt;
&lt;br /&gt;
[[Datei:ListMonk SubscriptionForm.png]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://listmonk.app/ Projektseite&lt;br /&gt;
* https://github.com/knadh/listmonk ListMonk auf Github&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible.app.listmonk Ansible Rolle für Hostsharing von Timotheus Pokorra&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Mailinglisten]]&lt;br /&gt;
[[Kategorie:Newsletterversand]]&lt;br /&gt;
[[Kategorie:E-Mail]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Keycloak_installieren&amp;diff=7604</id>
		<title>Keycloak installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Keycloak_installieren&amp;diff=7604"/>
		<updated>2026-07-14T09:47:09Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Admin User einrichten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemein ==&lt;br /&gt;
&lt;br /&gt;
Keycloak [http://www.keycloak.org/] ist eine Open Source Lösung, die ein Single Sign On für verschiedene Anwendungen ermöglicht. Dabei ermöglicht es sowohl die Identitätsverwaltung als auch Zugriffsmanagement.&lt;br /&gt;
&lt;br /&gt;
Es kann die Benutzer entweder aus einem existierenden Verzeichnisdienst (LDAP, Active Directory) auslesen, oder die Gruppen und Benutzer auch selber verwalten.&lt;br /&gt;
&lt;br /&gt;
== Technische Details ==&lt;br /&gt;
Keycloak ist in Java geschrieben. Bisher lief es in einem Wildfly Server, aber seit Version 17 (Februar 2022) benutzt es Quarkus, welches ein leichtgewichtiges Java Framework ist.&lt;br /&gt;
&lt;br /&gt;
Es gibt ein Ansible Skript, das die Installationsschritte für Keycloak automatisiert durchführt.&lt;br /&gt;
&lt;br /&gt;
Die Quellen für das Ansible Skript können hier eingesehen werden: [https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/keycloak]&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
Was das Ansible Skript macht, lässt sich mit diesen Worten beschreiben:&lt;br /&gt;
&lt;br /&gt;
* Es wird ein Linux Benutzer eingerichtet.&lt;br /&gt;
* Es wird eine Postgresql Datenbank eingerichtet.&lt;br /&gt;
* Es wird eine Domain aufgeschaltet.&lt;br /&gt;
* Es wird Keycloak als Zip Datei heruntergeladen, z.B. [https://github.com/keycloak/keycloak/releases/download/17.0.0/keycloak-17.0.0.zip], und ins Verzeichnis $HOME/keycloak-17.0.0 entpackt.&lt;br /&gt;
* Dann werden ein paar Konfigurationen an der Datei &amp;lt;code&amp;gt;keycloak/conf/keycloak.conf&amp;lt;/code&amp;gt; vorgenommen, um die Postgresql Datenbank einzurichten, und um den Proxymodus auf edge zu setzen und den Hostname zu setzen.&lt;br /&gt;
* Nun wird die Keycloak Instanz initialisiert, mit dem Befehl: &amp;lt;code&amp;gt;keycloak/bin/kc.sh --cache=local --profile=prod build&amp;lt;/code&amp;gt;. Hierbei verhindert die Einstellung für den Cache, dass Keycloak versucht über das Netzwerk Verbindungen zu anderen Instanzen herzustellen.&lt;br /&gt;
* Es muss der Server einmal gestartet werden, während der Admin Benutzer mit Passwort in einer Umgebungsvariable gesetzt ist, damit der Benutzer eingerichtet wird.&lt;br /&gt;
* Es wird Monit konfiguriert, um den Keycloak Service zu starten, der auf einem internen Port lauscht.&lt;br /&gt;
* Es wird der Apache in der htaccess Datei konfiguriert, damit die aufgeschaltete Domain über Proxy auf den Keycloak Dienst verweist. Dabei ist wichtig, dass der Java Prozess mitbekommt, dass die Seite über https läuft. Dazu wird in der htaccess Datei der Wert X-Forwarded-Proto auf https gesetzt.&lt;br /&gt;
&lt;br /&gt;
=== Keycloak mit Systemd ===&lt;br /&gt;
&lt;br /&gt;
Sofern &amp;lt;code&amp;gt;linger&amp;lt;/code&amp;gt; für den User schon verfügbar ist, kann auch Systemd verwendet werden. Zudem sollte im Vorfeld &amp;lt;code&amp;gt;export XDG_RUNTIME_DIR=/run/user/$UID&amp;lt;/code&amp;gt; ausgeführt werden um Zugriff auf die Befehle zu erhalten.&lt;br /&gt;
&lt;br /&gt;
Beispiel einer Systemd Konfiguration in &amp;lt;code&amp;gt;.config/systemd/user/keycloak.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Keycloak&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
Restart=on-abort&lt;br /&gt;
WorkingDirectory=/home/pacs/xyz00/users/login/keycloak&lt;br /&gt;
Environment=PROXY_ADDRESS_FORWARDING=true&lt;br /&gt;
&lt;br /&gt;
# Für den ersten Start, um den Adminuser zu setzen&lt;br /&gt;
#Environment=KEYCLOAK_ADMIN=changeme&lt;br /&gt;
#Environment=KEYCLOAK_ADMIN_PASSWORD=changeme&lt;br /&gt;
&lt;br /&gt;
# Die Option cache=local kann auch an anderer Stelle gesetzt werden.&lt;br /&gt;
# Hauptsache sie taucht auf, da es sonst zu Performance-Problemen wie&lt;br /&gt;
# Timeouts kommen kann.&lt;br /&gt;
ExecStart=/home/pacs/xyz00/users/login/keycloak/latest/bin/kc.sh start --cache=local&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
# Achtung: multiuser.target würde hier zu Problemen führen&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Beispiel einer Einrichtung ==&lt;br /&gt;
Diese Anleitung steht auch als [https://youtu.be/bmOp8epgxsM Video auf Youtube] zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
* Auf https://keycloak.example.org/admin anmelden.&lt;br /&gt;
&lt;br /&gt;
=== Admin User einrichten ===&lt;br /&gt;
* Der auf der Kommandozeile angelegte Benutzer ist nur vorübergehend gültig.&lt;br /&gt;
* Bitte einen permanenten Admin User anlegen, mit den entsprechenden Rollen (Realm Role: admin und default-roles-master) ausstatten&lt;br /&gt;
* Login mit permanentem Admin durchführen&lt;br /&gt;
* Dann den temporären Benutzer löschen.&lt;br /&gt;
&lt;br /&gt;
=== Realm einrichten ===&lt;br /&gt;
* Es soll nicht mit der master Realm gearbeitet werden, sondern sollte eine weitere Realm eingerichtet werden, z.B. &amp;quot;MeineFirma&amp;quot;&lt;br /&gt;
* Diese neue Realm wird dann ausgewählt&lt;br /&gt;
&lt;br /&gt;
=== Benutzer einrichten ===&lt;br /&gt;
* Innerhalb der neuen Realm wird dann ein neuer Benutzer angelegt.&lt;br /&gt;
* Beim neuen Benutzer kann ausgewählt werden, dass die E-Mail bereits bestätigt ist.&lt;br /&gt;
* Nach dem Speichern des Benutzers kann man dann auch bei Credentials das Passwort setzen. Wenn es nur temporär ist, muss der Benutzer es bei der ersten Anmeldung ändern.&lt;br /&gt;
* Nun kann man sich als Administrator abmelden und sich als der Benutzer anmelden, auf https://keycloak.example.org/realms/MeineFirma/account/#/&lt;br /&gt;
** Achtung: in anderen Anleitungen heißen die URLs /auth/realms usw, aber auth scheint nicht mehr Teil der Standardeinrichtung zu sein.&lt;br /&gt;
* Als Benutzer kann man sein Passwort ändern.&lt;br /&gt;
* Wieder abmelden, und wieder als Administrator anmelden.&lt;br /&gt;
&lt;br /&gt;
=== Client einrichten ===&lt;br /&gt;
* Achtung: erst aus der Master Realm in die vorher angelegte Realm wechseln, z.B. &amp;quot;MeineFirma&amp;quot;&lt;br /&gt;
* Nun sollte ein Client hinzugefügt werden, also eine beliebige Anwendung, die mit Keycloak zusammenarbeiten soll&lt;br /&gt;
** Als Client-Protokoll wählt man &amp;quot;OpenID Connect&amp;quot;&lt;br /&gt;
** Die Client-ID kann so aussehen: my-nextcloud&lt;br /&gt;
** Anwählen: &#039;Client Authentication&#039;, um den OID Typ auf &#039;Confidential Access Type&#039; zu setzen.&lt;br /&gt;
** Anwählen: &#039;Standard Flow&#039;, &#039;Implicit Flow&#039; und &#039;Direct Access Grants&#039;&lt;br /&gt;
* Eine Root Url eingeben, z.B. https://nextcloud.example.org&lt;br /&gt;
* Eine Valid Redirect URI eingeben, z.B. https://nextcloud.example.org/*&lt;br /&gt;
* Gültige Web Origins eingeben, z.B. https://nextcloud.example.org&lt;br /&gt;
* Speichern&lt;br /&gt;
* Unter Roles eine neue Rolle mit Namen admin anlegen.&lt;br /&gt;
* Wieder unter den Client Nextcloud gehen, und bei &amp;quot;Client Scopes&amp;quot; klicke auf &amp;quot;my-nextcloud-dedicated&amp;quot;, und wähle dort &amp;quot;Add predefined Mapper&amp;quot;. Wähle &amp;quot;client roles&amp;quot;, und klicke auf &amp;quot;Add&amp;quot;. Dann diesen neuen Mapper &amp;quot;client roles&amp;quot; Bearbeiten, und Client ID auf &amp;quot;my-nextcloud&amp;quot; setzen, und &amp;quot;Token Claim Name&amp;quot; mit &amp;quot;roles&amp;quot; setzen, und &amp;quot;Add to userinfo&amp;quot; auf &amp;quot;ON&amp;quot; stellen. Dann Speichern.&lt;br /&gt;
* Dann zu nochmal zu Client Scopes (im Client) gehen, und auf &amp;quot;my-nextcloud-dedicated&amp;quot; klicken, und dort im Reiter &amp;quot;Scope&amp;quot; die Option &amp;quot;Full Scope Allowed&amp;quot; abschalten.&lt;br /&gt;
&lt;br /&gt;
* Dann unter Configure / Realm Settings, in General, bei Endpoints auf &amp;quot;OpenID Endpoint Configuration&amp;quot; klicken, dann wird eine Seite geöffnet, auf dieser URL: https://keycloak.example.org/realms/MeineFirma/.well-known/openid-configuration; diese Seite offen halten, wir brauchen daraus die Daten für die Nextcloud Einrichtung&lt;br /&gt;
&lt;br /&gt;
=== Nextcloud einrichten (Einfach) ===&lt;br /&gt;
* Als Administrator anmelden, und bei den Apps die App [https://apps.nextcloud.com/apps/sociallogin &amp;quot;Social Login&amp;quot;] installieren.&lt;br /&gt;
* Dann bei Einstellungen, unter Verwaltung, Social Login, die gewünschten Einstellungen vornehmen.&lt;br /&gt;
* Es sollte ein Kreuz sein bei: Anlegen eines Kontos verhindern, wenn die E-Mail-Adresse bereits von einem anderen Konto verwendet wird.&lt;br /&gt;
* Es sollte ein Kreuz sein bei: Verhindern, dass sich Benutzer ohne gemappte Gruppe anmelden können.&lt;br /&gt;
* Speichern&lt;br /&gt;
* Dann bei &amp;quot;Benutzerdefinierte OpenID Connect Anbindung&amp;quot; auf das Plus klicken&lt;br /&gt;
* Nun die Daten aus der &amp;quot;OpenID Endpoint Configuration&amp;quot; (siehe oben) übernehmen: Authorize URL, Token URL, User info URL, Logout URL&lt;br /&gt;
* Client ID: nc (Name des Clients in Keycloak)&lt;br /&gt;
* Client Secret: hier kommt das Secret hinein, das in Keycloak im Client unter Credentials &amp;quot;Client Secret&amp;quot; zu finden ist. Das kann über die Zwischenablage kopiert werden.&lt;br /&gt;
* Scope: openid&lt;br /&gt;
* Speichern&lt;br /&gt;
&lt;br /&gt;
=== Nextcloud einrichten (Fortgeschritten) ===&lt;br /&gt;
Die folgende App wird mit Rücksicht auf Keycloak entwickelt und hat daher eine &amp;lt;strong&amp;gt;bessere Kompatibilität&amp;lt;/strong&amp;gt; als das Beispiel oben. Allerdings gibt es hierfür keine Optionen in der Cloud, stattdessen wird die &amp;lt;code&amp;gt;config.php&amp;lt;/code&amp;gt; direkt bearbeitet.&lt;br /&gt;
&lt;br /&gt;
==== Plugin-Installation ====&lt;br /&gt;
&lt;br /&gt;
# Als Administrator die App [https://github.com/pulsejet/nextcloud-oidc-login &amp;quot;Nextcloud OIDC Login&amp;quot;] installieren&lt;br /&gt;
# Die Nextcloud Konfigurationsdatei unter &amp;lt;code&amp;gt;pfad/zur/nextcloud/config/config.php&amp;lt;/code&amp;gt; öffnen und basierend auf dem Readme der App (Link aus Schritt #1) befüllen. Das könnte so aussehen: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=php line&amp;gt;&lt;br /&gt;
&#039;oidc_login_client_id&#039; =&amp;gt; &#039;nextcloud&#039;,&lt;br /&gt;
&#039;oidc_login_client_secret&#039; =&amp;gt; &#039;bSIPDNUyTQpxmfOpXdwyoBP8nZDQZVuL&#039;, // Client Reiter &amp;quot;Credentials&amp;quot; in Keycloak&lt;br /&gt;
&#039;oidc_login_provider_url&#039; =&amp;gt; &#039;https://login.mydomain.de/realms/myrealm&#039;,&lt;br /&gt;
&#039;oidc_login_end_session_redirect&#039; =&amp;gt; true,&lt;br /&gt;
&#039;oidc_login_logout_url&#039; =&amp;gt; &#039;https://cloud.mydomain.de/index.php/apps/oidc_login/oidc&#039;,&lt;br /&gt;
&#039;oidc_login_auto_redirect&#039; =&amp;gt; true, // hiermit wird das Login-Formular übergangen um Leute weniger zu verwirren&lt;br /&gt;
&#039;oidc_login_redir_fallback&#039; =&amp;gt; false,&lt;br /&gt;
&#039;oidc_login_disable_registration&#039; =&amp;gt; false, // Nextcloud soll neue Keycloak Accounts akzeptieren&lt;br /&gt;
&#039;oidc_create_groups&#039; =&amp;gt; true,&lt;br /&gt;
&#039;oidc_login_attributes&#039; =&amp;gt; array(&lt;br /&gt;
&#039;id&#039; =&amp;gt; &#039;preferred_username&#039;,&lt;br /&gt;
&#039;mail&#039; =&amp;gt; &#039;email&#039;,&lt;br /&gt;
&#039;groups&#039; =&amp;gt; &#039;ownCloudGroups&#039;,&lt;br /&gt;
&#039;is_admin&#039; =&amp;gt; &#039;ownCloudAdmin&#039;,&lt;br /&gt;
),&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== In Keycloak nochmal alles kontrollieren ====&lt;br /&gt;
# Client ID stimmt überein&lt;br /&gt;
# unter &amp;lt;code&amp;gt;Capability config&amp;lt;/code&amp;gt; ist &amp;lt;code&amp;gt;Client authentication&amp;lt;/code&amp;gt; aktiv (damit wir ua. unser Secret bekommen)&lt;br /&gt;
# &amp;lt;code&amp;gt;Valid redirect URIs&amp;lt;/code&amp;gt; erlaubt &amp;lt;/code&amp;gt;https://cloud.mydomain.de/*&amp;lt;/code&amp;gt; – oder eine konkretere Adresse. Das Plus übernimmt die Einstellung aus &amp;lt;code&amp;gt;Valid redirect URIs&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;Valid post logout redirect URIs&amp;lt;/code&amp;gt; erlaubt &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; oder &amp;lt;/code&amp;gt;https://cloud.mydomain.de/*&amp;lt;/code&amp;gt; – oder eine konkretere Adresse&lt;br /&gt;
# &amp;lt;code&amp;gt;Fine Grain OpenID Connect Configuration&amp;lt;/code&amp;gt; steht unter &amp;lt;code&amp;gt;ID Token Signature Algorithm&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;RS256&amp;lt;/code&amp;gt; (Achtung, hier verrutscht man schnell weil die Einträge sich ähneln)&lt;br /&gt;
&lt;br /&gt;
==== Gruppen Synchronisation über Rollen ermöglichen ====&lt;br /&gt;
Hierfür legen wir einen Mapper in &amp;lt;code&amp;gt;nextcloud&amp;lt;/code&amp;gt; Client an. Anschließend müssen die tatsächlichen Gruppen mit Roles verknüpft werden. Hintergrund ist, dass Roles eigentlich für Berechtigungsmanagement gedacht sind, und Gruppen eigentlich nur User gruppieren sollen.&lt;br /&gt;
# wir wechseln im Client &amp;lt;code&amp;gt;nextcloud&amp;lt;/code&amp;gt; auf den Reiter &amp;lt;code&amp;gt;Client scopes&amp;lt;/code&amp;gt;&lt;br /&gt;
# wir wählen &amp;lt;code&amp;gt;nextcloud-dedicated&amp;lt;/code&amp;gt;&lt;br /&gt;
# Add mapper -&amp;gt; by configuration&lt;br /&gt;
## Type: &amp;lt;code&amp;gt;User Client Role&amp;lt;/code&amp;gt;&lt;br /&gt;
## Name: &amp;lt;code&amp;gt;ownCloudGroups&amp;lt;/code&amp;gt;&lt;br /&gt;
## Client ID&lt;br /&gt;
### &amp;lt;strong&amp;gt;Option #1:&amp;lt;/strong&amp;gt; &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; – es werden alle &amp;lt;code&amp;gt;Realm roles&amp;lt;/code&amp;gt; abgerufen. Das umfasst allerdings auch die Defaults wie &amp;lt;code&amp;gt;uma_authorization&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;offline_access&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;default-user-roles&amp;lt;/code&amp;gt; und ist nicht immer gewünscht.&lt;br /&gt;
### &amp;lt;strong&amp;gt;Option #2:&amp;lt;/strong&amp;gt; &amp;lt;code&amp;gt;nextcloud&amp;lt;/code&amp;gt; hier können im Anschluss roles im Client angelegt und mit &amp;lt;code&amp;gt;Groups&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;Realm roles&amp;lt;/code&amp;gt; verknüpft werden. &lt;br /&gt;
## Multivalued: &amp;lt;code&amp;gt;On&amp;lt;/code&amp;gt;&lt;br /&gt;
## Token Claim Name: &amp;lt;code&amp;gt;NextcloudGroups&amp;lt;/code&amp;gt;&lt;br /&gt;
## Claim JSON Type: &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt;&lt;br /&gt;
## die folgenden drei Optionen: &amp;lt;code&amp;gt;On&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Gruppen Synchronisation in der Praxis ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;Option #2:&amp;lt;/strong&amp;gt; Client ID &amp;lt;code&amp;gt;nextcloud&amp;lt;/code&amp;gt;&lt;br /&gt;
# wir wechseln im Client &amp;lt;code&amp;gt;nextcloud&amp;lt;/code&amp;gt; auf den Reiter &amp;lt;code&amp;gt;Roles&amp;lt;/code&amp;gt;&lt;br /&gt;
# Create role&lt;br /&gt;
## Wunschname&lt;br /&gt;
# wir wechseln in &amp;lt;code&amp;gt;Groups&amp;lt;/code&amp;gt; (Sidebar)&lt;br /&gt;
# Create group&lt;br /&gt;
## Wunschname: Wichtig: es muss der Name der Gruppe in Nextcloud genommen werden, der in der URL der Gruppe erkennbar ist; nicht der DisplayName&lt;br /&gt;
# In der Gruppe wechseln wir auf den Reiter &amp;lt;code&amp;gt;Role mapping&amp;lt;/code&amp;gt;&lt;br /&gt;
## Assign role&lt;br /&gt;
## Im Dropdown wechseln wir auf den Filter &amp;lt;code&amp;gt;by clients&amp;lt;/code&amp;gt;&lt;br /&gt;
## Wir wählen die gewünschte Rolle&lt;br /&gt;
## Unten Links, button &amp;lt;code&amp;gt;Assign&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ab hier können wir die Gruppe normal zuweisen.&lt;br /&gt;
&lt;br /&gt;
=== Benutzer einrichten ===&lt;br /&gt;
* Einen Benutzer im Keycloak einrichten, in der Realm &amp;quot;MeineFirma&amp;quot;.&lt;br /&gt;
* Den Benutzer bearbeiten, und unter &amp;quot;Role Mappings&amp;quot;, &amp;quot;Assign Role&amp;quot;, &amp;quot;Filter by Clients&amp;quot;, wähle &amp;quot;my-nextcloud admin&amp;quot; und klicke auf &amp;quot;Assign&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Fehler beheben ==&lt;br /&gt;
&lt;br /&gt;
Problem: Gerade beim Experimentieren kommt schon mal die Meldung: &amp;quot;expected expression, got end of script&amp;quot;&lt;br /&gt;
* Lösung: Webseite aus der Firefox Chronik komplett löschen, oder in einem privaten Fenster öffnen, dann geht es wieder.&lt;br /&gt;
&lt;br /&gt;
Generell kann es zu verwirrenden Fehlermeldungen kommen, wenn man sich versucht in einer verknüpften Anwendung einzuloggen aber beispielsweise noch als Admin im Master-Realm eingeloggt ist.&lt;br /&gt;
&lt;br /&gt;
=== Logging ===&lt;br /&gt;
Um Fehler besser verstehen zu können, kann das Logging angeschaltet werden, siehe auch [https://www.keycloak.org/server/logging].&lt;br /&gt;
&lt;br /&gt;
Dazu müssen im Start Skript &amp;lt;code&amp;gt;bin/start-keycloak.sh&amp;lt;/code&amp;gt; folgende Parameter hinzugefügt werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
--log-level=ERROR --log=file&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Also sieht es z.B. so aus:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
./bin/kc.sh start --http-port [...] --proxy edge --log-level=ERROR --log=file &amp;amp;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Nach dem Neustart von Keycloak gibt es dann die Datei &amp;lt;code&amp;gt;keycloak/data/log/keycloak.log&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
*[http://www.keycloak.org/ Webseite von Keycloak]&lt;br /&gt;
*[https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/keycloak Ansible Playbook für Hostsharing]&lt;br /&gt;
*[https://robferguson.org/blog/2019/12/24/getting-started-with-keycloak/ Getting started with Keycloak]&lt;br /&gt;
*[https://janikvonrotz.ch/2020/10/20/openid-connect-with-nextcloud-and-keycloak/ OpenID Connect with Nextcloud and Keycloak] von Janik Vonrotz, Oktober 2020&lt;br /&gt;
* [https://www.muehlencord.de/wordpress/2019/12/14/nextcloud-sso-using-keycloak/ Nextcloud SSO using Keycloak] von Jörns Blog, Dezember 2019&lt;br /&gt;
* [https://youtu.be/bmOp8epgxsM Erklärvideo auf Youtube] zum Einrichten von Keycloak und Nextcloud&lt;br /&gt;
* [https://apps.nextcloud.com/apps/sociallogin Nextcloud App Social Login]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:SSO]]&lt;br /&gt;
[[Kategorie:Java]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Verzeichnis-Struktur&amp;diff=7601</id>
		<title>Verzeichnis-Struktur</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Verzeichnis-Struktur&amp;diff=7601"/>
		<updated>2026-07-08T15:48:51Z</updated>

		<summary type="html">&lt;p&gt;Tim00: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Textkasten|rot|Hinweis:|Inhalt ist nun in der HS Dokumentation.&lt;br /&gt;
https://www.hostsharing.net/doc/managed-operations-platform/webpaket/&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
[[Kategorie:Glossar]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Verzeichnis-Struktur&amp;diff=7600</id>
		<title>Verzeichnis-Struktur</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Verzeichnis-Struktur&amp;diff=7600"/>
		<updated>2026-07-08T15:48:02Z</updated>

		<summary type="html">&lt;p&gt;Tim00: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Textkasten|rot|Hinweis:|Inhalt ist nun in der HS Dokumentation.&lt;br /&gt;
https://www.hostsharing.net/doc/managed-operations-platform/tutorials/webspace/&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
[[Kategorie:Glossar]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7599</id>
		<title>Discourse installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7599"/>
		<updated>2026-07-02T04:29:53Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Am Beispiel von 2026.1.3 auf 2026.1.4 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Textkasten|gelb|Für Managed Server|Ein funktionierender Discourse-Server erfordert mehrere laufende Server-Dienste. Für den Betrieb ist ein Managed Server sinnvoll.}}&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|rot|Support von der Discourse-Community|Die Discourse-Entwickler haben sich entschieden, nur eine mehr oder weniger genormte Installationsmethode (via docker) zu unterstützen. Dies ist so auf der hostsharing-Architektur aufgrund mehrerer Bedenken und Überlegungen nicht möglich. Die Community ist durchaus hilfreich, geht aber davon aus, dass quasi alle Nutzer* eine &amp;quot;supported&amp;quot;e Installation durchgeführt haben. Wenn man in entsprechenden Kanälen nach Hilfe fragt, sollte man unbedingt erwähnen, dass man discourse selber anhand dieser hier lesbaren Anleitung installiert hat, um bereits entsprechenden Kommentaren und Nachfragen vorzugreifen.}}&lt;br /&gt;
&lt;br /&gt;
== Über ==&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel wird die Installation von discourse, Version 2.1.0 (September 2018) beschrieben.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von HSAdmin wird angelegt:&lt;br /&gt;
# Ein User als Service-User mit &#039;&#039;/bin/bash&#039;&#039; als Shell, zum Beispiel Beispiel: &#039;&#039;xyz00-discourse&#039;&#039;&lt;br /&gt;
# Eine Domain mit &#039;&#039;xyz00-discourse&#039; als Domain-Administrator, zum Beispiel &#039;&#039;beispiel.discussion&#039;&#039;&lt;br /&gt;
# Einen Postgresql-User &#039;&#039;xyz00_discourseuser&#039;&#039; mit Passwort &#039;&#039;meinPasswort&#039;&#039;&lt;br /&gt;
# Eine Postgresql-Datenbank &#039;&#039;xyz00_discoursedb&#039;&#039; mit Datenbank-Owner &#039;&#039;xyz00_discourseuser&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verwendete IP-Ports der Server-Dienste:&lt;br /&gt;
# Redis: localhost:32002&lt;br /&gt;
# Discourse-Web: localhost:13000&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der PostgreSQL Datenbank ==&lt;br /&gt;
&lt;br /&gt;
Es müssen noch Erweiterungen für Postgresql installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA public;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration des Redis Server ==&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gelb|Firewall/Redis Port|Leider unterstützt discourse nicht die Kommunikation mit Redis über Unix-Sockets. Dementsprechend muss der für Redis konfigurierte Port von dem hostsharing-Support in der Firewall freigegeben werden.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd&lt;br /&gt;
mkdir redis/etc redis/lib redis/log redis/run&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/redis/etc/redis.conf&#039;&#039; mit folgendem Inhalt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
daemonize no&lt;br /&gt;
pidfile /home/pacs/xyz00/users/discourse/redis/run/redis-server.pid&lt;br /&gt;
port 32002&lt;br /&gt;
tcp-backlog 128&lt;br /&gt;
bind 127.0.0.1&lt;br /&gt;
timeout 300&lt;br /&gt;
loglevel notice&lt;br /&gt;
logfile /home/pacs/xyz00/users/discourse/redis/log/redis.log&lt;br /&gt;
databases 16&lt;br /&gt;
save 900 1&lt;br /&gt;
save 300 10&lt;br /&gt;
save 60 10000&lt;br /&gt;
slave-serve-stale-data yes&lt;br /&gt;
appendonly no&lt;br /&gt;
dbfilename dump.rdb&lt;br /&gt;
dir /home/pacs/xyz00/users/discourse/redis/lib&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für Discourse 3.x gilt: &amp;quot;Discourse requires Redis 6.2.0 or up&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Für Debian Buster und Bullseye ist daher das Installieren eines neueren Binaries erforderlich. Bei Debian Bookwork ist bereits Redis 7.0 enthalten (siehe https://packages.debian.org/search?keywords=redis-server).&lt;br /&gt;
&lt;br /&gt;
Hier steht ein entsprechendes Binary für Debian Buster zur Verfügung, das mit dem Public Key von Timotheus geprüft werden kann:&lt;br /&gt;
&lt;br /&gt;
* https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
* Prüfsignatur: https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz.sig&lt;br /&gt;
&lt;br /&gt;
Prüfen der Signatur:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gpg --verify redis-server-6.2.12-debian-buster.tar.gz.sig redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Binary muss nach &amp;lt;code&amp;gt;$HOME/bin&amp;lt;/code&amp;gt; verschoben werden, und entsprechend beim Starten des Dienstes eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
== Installation von Ruby ==&lt;br /&gt;
&lt;br /&gt;
Als User &#039;&#039;xyz00-discourse&#039;&#039;:  Installation von Ruby mit &#039;&#039;rbenv&#039;&#039; mit folgenden Befehlen:&lt;br /&gt;
&lt;br /&gt;
Zunächst &#039;&#039;rbenv&#039;&#039; and &#039;&#039;ruby-build&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/rbenv.git ~/.rbenv&lt;br /&gt;
cd ~/.rbenv &amp;amp;&amp;amp; src/configure &amp;amp;&amp;amp; make -C src&lt;br /&gt;
echo &#039;export PATH=&amp;quot;$HOME/.rbenv/bin:$PATH&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
echo &#039;eval &amp;quot;$(rbenv init -)&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
starte neue Shell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
exec bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Überprüfe rbenv-Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
type rbenv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installiere ruby-build als rbenv-Plugin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun kann die benötigte Ruby-Version installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
rbenv install 2.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation von Discourse selber ==&lt;br /&gt;
&lt;br /&gt;
Weiterhin Als User &#039;&#039;xyz00-discourse&#039;&#039;:  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~&lt;br /&gt;
git clone https://github.com/discourse/discourse.git discourse&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die stabile Version auschecken:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git checkout stable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ruby Pakete installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gem install bundler&lt;br /&gt;
bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without development test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der Discourse Software ==&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/discourse/config/discourse.conf&#039;&#039; anhand der Beispiel-Datei:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
cp config/discourse_defaults.conf config/discourse.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anpassen folgender Inhalte:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
db_host = 127.0.0.1&lt;br /&gt;
db_port = 5432&lt;br /&gt;
#db_backup_port = 5432 #(auskommentieren)&lt;br /&gt;
db_name = xyz00_discoursedb&lt;br /&gt;
db_username = xyz00_discourseuser&lt;br /&gt;
db_password = &amp;quot;&amp;quot; #db password&lt;br /&gt;
hostname = &amp;quot;discourse.xyz00&amp;quot; # hostname&lt;br /&gt;
smtp_address = localhost&lt;br /&gt;
smtp_enable_start_tls = false&lt;br /&gt;
smtp_openssl_verify_mode = &#039;none&#039;&lt;br /&gt;
developer_emails = # your email-address&lt;br /&gt;
redis_host = 127.0.0.1&lt;br /&gt;
redis_port = 32002&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===TODO: Secrets setzen! ===&lt;br /&gt;
Die Zufallswerte für die Variablen SECRET_KEY_BASE und OTP_SECRET erzeugt man durch zwei Aufrufe des Kommandos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rake secret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq für Hintergrund-Aufgaben konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;config/sidekiq.conf&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wichtig: development auf production ändern.&lt;br /&gt;
&lt;br /&gt;
Mit diesem Dienst werden z.B. die E-Mails zur Aktivierung oder zum Passwort Reset verschickt.&lt;br /&gt;
&lt;br /&gt;
=== Problem mit Content Security Policy ===&lt;br /&gt;
&lt;br /&gt;
Um ein Problem mit Content Security Policy zu lösen, weil manche Dateien über http nachgeladen werden, muss in der Datei &amp;lt;code&amp;gt;config/site_settings.yml&amp;lt;/code&amp;gt; der Default Wert für force_https auf True gesetzt werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
force_https:&lt;br /&gt;
    default: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Problem beim Aufsetzen der Datenbank vermeiden ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;→ Notiz Mai 2024:&#039;&#039;&#039; dies scheint aktuell nicht aufzutreten. &lt;br /&gt;
&lt;br /&gt;
Aus irgendeinem Grund wird beim Initialisieren der Datenbank versucht, den TYPE hotlinked_media_status zweimal in der Datenbank anzulegen. Der Grund ist nicht ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Es kann folgende Änderung an der Datei &amp;lt;code&amp;gt;db/migrate/20220428094026_create_post_hotlinked_media.rb&amp;lt;/code&amp;gt; vorgenommen werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
reversible do |dir|&lt;br /&gt;
  dir.up { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DO $$ BEGIN CREATE TYPE hotlinked_media_status AS ENUM(&#039;downloaded&#039;, &#039;too_large&#039;, &#039;download_failed&#039;, &#039;upload_create_failed&#039;); EXCEPTION WHEN duplicate_object THEN null; END $$;&lt;br /&gt;
    SQL&lt;br /&gt;
  dir.down { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DROP TYPE hotlinked_media_status&lt;br /&gt;
    SQL&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Initialisieren der Datenbank ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
export SAFETY_ASSURED=1&lt;br /&gt;
# In Version 2.0.4 funktioniert db:migrate noch, ansonsten db:schema:load und seed nutzen!&lt;br /&gt;
# In Version 3.0.3 funktioniert db:migrate auch noch, db:schema:load ging nicht weil die Datei structure.sql fehlte&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:schema:load&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:seed&lt;br /&gt;
RAILS_ENV=production bundle exec rails db:migrate&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kompilieren der Assets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rails assets:precompile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration des Web-Servers (am Beispiel Puma)  ===&lt;br /&gt;
&lt;br /&gt;
Die Datei &#039;&#039;config/puma.conf&#039;&#039; anpassen (hier nur Änderungen angezeigt):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini&amp;gt;&lt;br /&gt;
APP_ROOT = &#039;/home/pacs/xyz00/users/discourse/discourse&#039;&lt;br /&gt;
daemonize false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starten der Dienste  ==&lt;br /&gt;
&lt;br /&gt;
Zum Start aller notwendigen Dienste sollte systemd benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Dateien müssen nach &amp;lt;code&amp;gt;.config/systemd/user/&amp;lt;/code&amp;gt; kopiert werden (überlange Zeilen werden hier im Wiki umgebrochen)&lt;br /&gt;
&lt;br /&gt;
redis.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Redis User Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/var/redis&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
ExecStart=%h/bin/redis-server %h/etc/redis.conf&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sidekiq.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Sidekiq Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;DB_POOL=8&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec sidekiq -C %h/discourse/config/sidekiq.yml&lt;br /&gt;
StandardOutput=append:%h/var/log/sidekiq.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
discourse.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Web Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;WEB_CONCURRENCY=2&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MAX_THREADS=5&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec puma -C config/puma.rb -e production -b tcp://127.0.0.1:13000&lt;br /&gt;
StandardOutput=append:%h/var/log/puma.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einrichten des Apache VHost ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/doms/beispiel.discuss&lt;br /&gt;
rm -rf htdocs-ssl subs/www subs-ssl/www&lt;br /&gt;
ln -s ~/live/public htdocs-ssl&lt;br /&gt;
touch htdocs-ssl/.htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann die &#039;&#039;htdocs-ssl/.htaccess&#039;&#039; (durch das gelinkte Verzeichnis entspricht das dem Pfad /home/pacs/xyz00/users/discourse/discourse/public/.htaccess ) mit dem Editor der Wahl öffnen und folgende Konfiguration einfügen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
  &lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RewriteRule .* http://127.0.0.1:13000%{REQUEST_URI} [proxy,last]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wartung ==&lt;br /&gt;
=== Backup ===&lt;br /&gt;
&lt;br /&gt;
Discourse macht selbstätig backups und legt diese unter &#039;public/backups&#039; ab. Enthalten ist ein Datenbank-Dump und die hochgeladenen Dateien.&lt;br /&gt;
&lt;br /&gt;
Im Admin-Bereich lassen sich backups auch manuell antreten.&lt;br /&gt;
&lt;br /&gt;
=== Admin Benutzer einladen ===&lt;br /&gt;
&lt;br /&gt;
Manchmal brauchen wir einen neuen Admin Benutzer, den wir von der Kommandozeile aus einladen möchten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd /discourse&lt;br /&gt;
RAILS_ENV=production rake admin:invite[admin@example.org]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Import aus mbox Archiven ===&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel ein Mailman2 Archiv zu importieren, wo die Nachrichten als .mbox Datei vorliegen, sind folgende Schritte nötig:&lt;br /&gt;
&lt;br /&gt;
Vorbereitungen an Discourse:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
bundle config set frozen false&lt;br /&gt;
IMPORT=1 bundle install&lt;br /&gt;
bundle config set frozen true&lt;br /&gt;
nano script/import_scripts/mbox/settings.yml&lt;br /&gt;
#  dort ändern:&lt;br /&gt;
#    data_dir: /home/pacs/xyz00/users/discourse/list-archiv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hochladen der Mailinglisten-Archive:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/list-archiv&lt;br /&gt;
# dort muss es Unterordner mit dem Namen der gewünschten Kategorie geben,&lt;br /&gt;
# und die mbox Datei muss auch diesen Namen haben, z.B.:&lt;br /&gt;
# ~/list-archiv/beispiel/beispiel.mbox&lt;br /&gt;
# ~/list-archiv/example/example.mbox&lt;br /&gt;
# um die Beiträge in den entsprechenden Kategorien beispiel und example einzufügen.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durchführen des Imports:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
RAILS_ENV=production IMPORT=1 bundle exec rails runner \&lt;br /&gt;
    script/import_scripts/mbox.rb script/import_scripts/mbox/settings.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Export ===&lt;br /&gt;
* Wenn ein Forum beendet wird, möchte man evtl. eine Sicherung als statische HTML Seiten. &lt;br /&gt;
** Das wird hier diskutiert: https://meta.discourse.org/t/how-do-i-export-the-complete-forum-as-static-html-pages/71007/3&lt;br /&gt;
* Um ein Forum von Discourse zu Flarum umzuziehen, hat Timotheus ein Skript geschrieben.&lt;br /&gt;
** Das Migrations-Skript: https://github.com/SolidCharity/discourse_to_flarum&lt;br /&gt;
** siehe auch https://discuss.flarum.org/d/4930-discourse-to-flarum-migration-support/29&lt;br /&gt;
&lt;br /&gt;
=== Updates ===&lt;br /&gt;
&lt;br /&gt;
Discourse wird über update via mail informieren (dies kann man m.W. abschalten).&lt;br /&gt;
&lt;br /&gt;
Achtung: bei größeren Updates auch immer Änderungen an der Datei site_settings.yml (https://github.com/discourse/discourse/blob/main/config/site_settings.yml) beachten!&lt;br /&gt;
&lt;br /&gt;
Siehe auch die unterstützten Releases: https://releases.discourse.org/ und die Tags: https://github.com/discourse/discourse/tags&lt;br /&gt;
&lt;br /&gt;
==== Am Beispiel von 2026.1.4 auf 2026.1.5 ====&lt;br /&gt;
&lt;br /&gt;
# Im Web-Backend unter Administration-&amp;gt;Backups-&amp;gt; Read-Only Mouds setzen (oder Web Server so konfigurieren, dass keine Zugriffe mehr stattfinden können)&lt;br /&gt;
# Backup&lt;br /&gt;
# Die lokalen Änderungen sichern:&lt;br /&gt;
# cd discourse&lt;br /&gt;
# mv ~/plugins.bak/discourse-ai plugins&lt;br /&gt;
# git diff v2026.1.4 &amp;gt; diff-2026.1.4.txt&lt;br /&gt;
# git fetch&lt;br /&gt;
# git checkout -b hostsharing-deployment-v2026.1.5 v2026.1.5&lt;br /&gt;
# evtl. Änderungen aus diff-2026.1.4.txt wieder übernehmen und committen&lt;br /&gt;
# patch -p1 &amp;lt; diff-2026.1.4.txt&lt;br /&gt;
# git commit -a -m &amp;quot;spezifische Änderungen für diese Instanz&amp;quot; --no-verify&lt;br /&gt;
# Schauen, ob discourse eine neue Ruby-Version nutzt (z.B. in https://github.com/discourse/discourse_docker/blob/main/image/base/Dockerfile bzw. https://github.com/discourse/discourse/blob/v2026.1.5/Gemfile)&lt;br /&gt;
# Ist dies der Fall, dann:&lt;br /&gt;
# rbenv install 3.3.8&lt;br /&gt;
# rbenv global 3.3.8&lt;br /&gt;
# rbenv rehash&lt;br /&gt;
# echo &amp;quot;3.3.8&amp;quot; &amp;gt; .ruby-version&lt;br /&gt;
# installiere Node 22: https://codeberg.org/tpokorra/hostsharing-scripts/src/branch/main/install-nodejs.sh&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# gem update --system&lt;br /&gt;
# bundle install&lt;br /&gt;
# npm install -g terser uglify-js pnpm@10&lt;br /&gt;
#&lt;br /&gt;
# to avoid this error: ERR_PNPM_INVALID_DEPENDENCY_NAME  The current package contains a dependency with an invalid name: &amp;quot;@types/@glimmer__component&amp;quot;&lt;br /&gt;
# vi frontend/discourse-types/package.json&lt;br /&gt;
&lt;br /&gt;
 -    &amp;quot;@types/@glimmer__component&amp;quot;: &amp;quot;npm:@glimmer/component@^2.0.0&amp;quot;,&lt;br /&gt;
 -    &amp;quot;@types/@glint__ember-tsc&amp;quot;: &amp;quot;npm:@glint/ember-tsc@^1.0.7&amp;quot;,&lt;br /&gt;
 -    &amp;quot;@types/@glint__template&amp;quot;: &amp;quot;npm:@glint/template@^1.7.2&amp;quot;&lt;br /&gt;
 +    &amp;quot;@types/glimmer__component&amp;quot;: &amp;quot;npm:@glimmer/component@^2.0.0&amp;quot;,&lt;br /&gt;
 +    &amp;quot;@types/glint__ember-tsc&amp;quot;: &amp;quot;npm:@glint/ember-tsc@^1.0.7&amp;quot;,&lt;br /&gt;
 +    &amp;quot;@types/glint__template&amp;quot;: &amp;quot;npm:@glint/template@^1.7.2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# corepack use pnpm@latest-10&lt;br /&gt;
# pnpm install&lt;br /&gt;
# export $(grep -v &#039;^#&#039; ~/discourse.env | xargs -d &#039;\n&#039;)&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# Falls die pg extension pg_vector nicht installiert ist: deaktiviere das Plugin während migrate, aber auch für später damit /admin/settings funktioniert (ansonsten in salt pillar pg_vector installieren, und als postgres user: create extension vector;)&lt;br /&gt;
## mkdir -p ~/plugins.bak&lt;br /&gt;
## mv plugins/discourse-ai ~/plugins.bak&lt;br /&gt;
# RAILS_ENV=production bundle exec rake db:migrate&lt;br /&gt;
# RAILS_ENV=production bundle exec rake assets:precompile&lt;br /&gt;
# Services neu starten&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user restart puma&lt;br /&gt;
systemctl --user restart sidekiq&lt;br /&gt;
systemctl --user restart redis&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zuletzt: Read-Only Modus wieder deaktivieren&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
&lt;br /&gt;
Es können folgende Einstellungen in der Datei config/environments/production.rb vorgenommen werden. Danach den Puma Dienst neustarten. Fehlermeldungen und Stacktraces werden dann im Browser ausgegeben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
config.log_level = :debug&lt;br /&gt;
config.action_dispatch.show_exceptions = :all&lt;br /&gt;
config.action_dispatch.debug_exception_log_level = :error&lt;br /&gt;
&lt;br /&gt;
# Full error reports are enabled and caching is turned off&lt;br /&gt;
config.consider_all_requests_local = true&lt;br /&gt;
config.action_controller.perform_caching = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erforderliche Anpassungen ===&lt;br /&gt;
Weil wir bei Debian Bookworm noch mit ImageMagick 6.9 arbeiten, muss dieser [https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119 Patch] rückgängig gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line&amp;gt;&lt;br /&gt;
wget https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119.patch -O ~/imagemagick.patch&lt;br /&gt;
patch -p1 --reverse &amp;lt; ~/imagemagick.patch&lt;br /&gt;
git commit -a -m &amp;quot;revert imagemagick patch&amp;quot;  --no-verify&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ToDos ==&lt;br /&gt;
&lt;br /&gt;
* Ein Patch, um Discourse auch via Unix-Socket mit Redis sprechen lassen zu können dürfte relativ einfach sein (es wird ein Wrapper um das redis-gem genutzt).&lt;br /&gt;
* Konfiguration von discourse, um mit postgresql via Unix-Socket zu kommunizieren (DISCOURSE_DB_SOCKET environment variable)&lt;br /&gt;
* Performance-tuning an diversen Stellen, anhand der discourse_docker-Vorgaben (https://github.com/discourse/discourse_docker), z.B.&lt;br /&gt;
** thpoff (huge page settings)&lt;br /&gt;
** unicorn (hat eine wesentlich ausgefeiltere Konfigurations-Vorlage, wahrscheinlich bereits ordentlich optimiert)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://help.skysilk.com/support/solutions/articles/9000120927-how-to-install-discourse-without-docker-using-skysilk-vps-&lt;br /&gt;
* https://github.com/discourse/discourse_docker&lt;br /&gt;
* https://github.com/discourse/discourse&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/discourse&lt;br /&gt;
&lt;br /&gt;
== Historie ==&lt;br /&gt;
&lt;br /&gt;
* 2018, 14 . September: Initiale Fassung&lt;br /&gt;
* 2019, Januar: Update-Informationen ergänzt&lt;br /&gt;
* 2022, Juni: systemd Dienste, Discourse 3.0&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:RubyOnRails]]&lt;br /&gt;
[[Kategorie:Webforen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Skript_hs-list-apps&amp;diff=7598</id>
		<title>Skript hs-list-apps</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Skript_hs-list-apps&amp;diff=7598"/>
		<updated>2026-07-01T20:10:57Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Beschreibung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung ==&lt;br /&gt;
&lt;br /&gt;
hs-list-apps ist ein Skript, in Python geschrieben, welches viele der aktuell installierten Anwendungen und die Belegung von RAM, SSD und HDD anzeigt.&lt;br /&gt;
&lt;br /&gt;
Es hilft, gerade bei Paketen mit vielen Anwendungen, den Überblick zu behalten. Als Reseller will ich zum Beispiel wissen, wieviele Nextclouds in meinem Paket installiert sind, wieviel Platz sie belegen, und auf welchem Versionsstand sie sind.&lt;br /&gt;
&lt;br /&gt;
Das Skript wird momentan hier gepflegt: https://codeberg.org/tpokorra/hostsharing-scripts/src/branch/main/hs_list_apps&lt;br /&gt;
&lt;br /&gt;
== Einschränkungen ==&lt;br /&gt;
&lt;br /&gt;
Es werden bisher einige Anwendungen unterstützt, aber längst nicht alle Anwendungen, die bei Hostsharing installiert werden können oder installiert worden sind. Weitere Anwendungen können gerne ins Skript aufgenommen werden. Bitte einen PR oder Issue auf dem Repo bei Codeberg aufmachen.&lt;br /&gt;
&lt;br /&gt;
Es werden einige Annahmen getroffen, wo eine Anwendung zu finden ist. Damit vermeiden wir einen vollständigen Scan der Dateien, der sehr zeitintensiv wäre. z.B. wird erwartet, dass die Nextclouds alle im Benutzerverzeichnis im Ordner nextcloud liegen.&lt;br /&gt;
&lt;br /&gt;
Es wird versucht, die richtige Domain zu bestimmen. Wenn im Benutzer aber mehrere Domains eingetragen sind, wird die mit dem längsten Namen angezeigt.&lt;br /&gt;
&lt;br /&gt;
== Benutzung ==&lt;br /&gt;
&lt;br /&gt;
Das Skript steht auf den Hives zur Verfügung, es liegt in /usr/local/bin, und ist damit Teil des Standardpfades.&lt;br /&gt;
&lt;br /&gt;
Das Skript kann entweder innerhalb eines Benutzers aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00-nextcloud@h01:~$ hs-list-apps --detail&lt;br /&gt;
|-----------|---------|-------|-----------|-----------------------------------|--------|------|------|&lt;br /&gt;
| AppName   | Version | PAC   | USER      | URL                               | RAM    | SSD  | HDD  |&lt;br /&gt;
|-----------|---------|-------|-----------|-----------------------------------|--------|------|------|&lt;br /&gt;
| Nextcloud | 32.0.6  | xyz00 | nextcloud | https://test.nextcloud.example.de | 164.7M | 1.4G | 131M |&lt;br /&gt;
|-----------|---------|-------|-----------|-----------------------------------|--------|------|------|&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ohne den Parameter --detail wird der SSD Platz und der HDD Platz nicht berechnet. Das kann sonst etwas Zeit in Anspruch nehmen.&lt;br /&gt;
&lt;br /&gt;
Das Skript kann auch vom Paket Admin aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@h01:~$ hs-list-apps &lt;br /&gt;
|-----------|---------------|-------|-----------------|----------------------------- -----|-------|-----|-----|&lt;br /&gt;
| AppName   | Version       | PAC   | USER            | URL                               | RAM   | SSD | HDD |&lt;br /&gt;
|-----------|---------------|-------|-----------------|-----------------------------------|-------|-----|-----|&lt;br /&gt;
| Wordpress | 6.8.3         | xyz00 | mywordpresstest | https://www.example.de            | 21.2M |     |     |&lt;br /&gt;
| OpenLDAP  | 2.5.13+dfsg-5 | xyz00 | openldap        | https://openldap.example.de       | 28.5M |     |     |&lt;br /&gt;
| Nextcloud | 32.0.6        | xyz00 | nextcloud       | https://test.nextcloud.example.de | 33.0M |     |     |&lt;br /&gt;
|-----------|---------------|-------|-----------------|-----------------------------------|-------|-----|-----|&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Skript kann auch nur nach bestimmten Anwendungen suchen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
xyz00@h01:~$ hs-list-apps --app nextcloud&lt;br /&gt;
|-----------|---------------|-------|-----------------|----------------------------- -----|-------|-----|-----|&lt;br /&gt;
| AppName   | Version       | PAC   | USER            | URL                               | RAM   | SSD | HDD |&lt;br /&gt;
|-----------|---------------|-------|-----------------|-----------------------------------|-------|-----|-----|&lt;br /&gt;
| Nextcloud | 32.0.6        | xyz00 | nextcloud       | https://test.nextcloud.example.de | 33.0M |     |     |&lt;br /&gt;
|-----------|---------------|-------|-----------------|-----------------------------------|-------|-----|-----|&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Spamfilter&amp;diff=7596</id>
		<title>Spamfilter</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Spamfilter&amp;diff=7596"/>
		<updated>2026-06-24T08:20:38Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Konfiguration pro Domain */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Einrichtung, Konfiguration und Optimierung eines Spamfilters auf den Hostsharing Servern. Der Artikel beschreibt drei alternative Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
1. Die Nutzung der &amp;quot;xmailin&amp;quot;-Server für eine komplette Domain&lt;br /&gt;
&lt;br /&gt;
2. Die Einrichtung von Spamassassin für das persönliche Postfach&lt;br /&gt;
&lt;br /&gt;
3. Nutzung der Spam-Appliance &amp;quot;SecureMX&amp;quot; für eine komplette Domain&lt;br /&gt;
&lt;br /&gt;
= Alternative 1: Maileingangsserver mit Spamfilter nutzen =&lt;br /&gt;
&lt;br /&gt;
Diese Alternative kann von einer Domain-Administration oder vom &amp;quot;Webmaster on Demand&amp;quot; für eine oder mehrere E-Mail-Domains eingerichtet werden. Ein globaler Sieve-Filter für markiete Spam-Nachrichten ist in der Standard-Konfiguration voreingestellt, &lt;br /&gt;
so dass Nachrichten mit Spam-Bewertung in einen vorhandenen Spam-Ordner einsortiert werden.&lt;br /&gt;
&lt;br /&gt;
Seit einigen Jahren betreibt Hostsharing zusätzlich zu den vorkonfigurierte Maileingangsservern einen zweiten Satz von Maileingangsservern, bei denen Spamassassin bereits beim Annehmen einer E-Mail ausgeführt wird. Anfang 2026 ist eine Gruppe von Eingangsserver mit der Software &amp;quot;rspamd&amp;quot; hinzugekommen. Eingehende Nachrichten mit Malware oder sehr hoher Bewertung als Spam werden bereits im SMTP-Dialog abgewiesen. Nachrichten mit einem geringeren Spam-Score werden angenommen und zugestellt. Spamassassin fügt die Bewertung für diese Nachrichten in die Header der Nachricht ein, zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
X-Spam-Status: Yes, score=11.29&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der globale Sieve-Filter schiebt Nachrichten mit der Markierung &amp;quot;X-Spam-Status: Yes&amp;quot; in einen Ordner &amp;quot;Junk&amp;quot;, wenn der Ordner vorhanden ist. Viele Mailprogramme legen beim ersten Verbinden mit dem IMAP-Server einen solchen Ordner an. Unser &amp;quot;Roundcube&amp;quot;&lt;br /&gt;
unter https://webmail.hostsharing.net ist entsprechend eingerichtet, so dass der Ordner nach einer Nutzung von Webmail vorhanden ist.&lt;br /&gt;
&lt;br /&gt;
== Eingangsserver konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Die Maileingangsserver mit Rspamd lassen sich pro Domain konfigurieren, indem die MX-Records im DNS-Zonefile gegenüber dem Default-Zonefile angepasst werden.&lt;br /&gt;
&lt;br /&gt;
Im Zonefile entfällt der Platzhalter &amp;quot;{MX_RR}&amp;quot;. Stattdessen werden die folgenden MX-Records eingefügt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
{DOM_HOSTNAME}.    IN  MX  30  xmailin1.hostsharing.net.&lt;br /&gt;
{DOM_HOSTNAME}.    IN  MX  30  xmailin2.hostsharing.net.&lt;br /&gt;
{DOM_HOSTNAME}.    IN  MX  30  xmailin3.hostsharing.net.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur Änderung der DNS-Zone siehe: https://www.hostsharing.net/doc/managed-operations-platform/zonefile/&lt;br /&gt;
Wer sich die Aktion auf der Shell nicht zutraut, möge bitte den &amp;quot;Webmaster on Demand&amp;quot; beauftragen.&lt;br /&gt;
&lt;br /&gt;
Die Änderung des Zonefile kann für eine Domain &amp;quot;hs-example.de&amp;quot; wie folgt überprüft werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
dig +short -t MX hs-example.de @dns1.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die folgende Ausgabe wird erwartet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
30 xmailin2.hostsharing.net.&lt;br /&gt;
30 xmailin3.hostsharing.net.&lt;br /&gt;
30 xmailin1.hostsharing.net.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Reihenfolge der drei Eingangsserver kann variieren. &lt;br /&gt;
Die führende Zahl ist die Priorität im MX-Record (hier der Wert &amp;quot;30&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Den Filter trainieren ==&lt;br /&gt;
Wer auch am Trainieren des Filters mitwirken möchte, sendet den/die Benutzername/n xyz00-name (das ist der eMail Benutzername) an:&lt;br /&gt;
service (at) hostsharing (dot) net&lt;br /&gt;
&lt;br /&gt;
Das bedeutet dann, dass das Verschieben einer E-Mail in den Spam-Ordner (Junk) darauf Einfluß hat, das zukünftige E-Mails in dieser Art besser als Spam erkannt werden. Andersrum genauso: wenn ich eine E-Mail aus dem Spam-Ordner (Junk) in einen anderen Ordner verschiebe, werden in Zukunft ähnliche E-Mails auch nicht mehr als Spam erkannt.&lt;br /&gt;
&lt;br /&gt;
Da das Training gemeinschaftlich ist, sollte bitte darauf geachtet werden, Newsletter nicht in den Junk Ordner zu schieben, sondern sich davon abzumelden und die E-Mail zu löschen. Nur weil du den Newsletter der Firma xy nicht mehr magst, soll er für andere Benutzer nicht automatisch als Spam erkannt werden.&lt;br /&gt;
&lt;br /&gt;
== Weitere Konfigurationen pro Domain ==&lt;br /&gt;
&lt;br /&gt;
Die E-Mails werden vom Spamfilter auf verschiedene Kriterien geprüft, für die dann Punkte vergeben werden. Manche Eigenschaften sind positiv, andere sind negativ. Am Ende ergibt das eine Punktzahl.&lt;br /&gt;
&lt;br /&gt;
Voreingestellt ist: &lt;br /&gt;
* ab einer Gesamt-Punktzahl von 5 wird die E-Mail als Spam kategorisiert, und wandert in den Spam-Ordner (Junk).&lt;br /&gt;
* ab einer Gesamt-Punktzahl von 15 wird die E-Mail direkt abgewiesen, und der Absender erhält von seinem E-Mail-Server eine Unzustellbarkeitsbenachrichtigung.&lt;br /&gt;
&lt;br /&gt;
Wir können diese Punktzahlen pro Domain konfigurieren. Das geht leider noch nicht im HSAdmin, daher bitte eine E-Mail an den Hostsharing Service schicken.&lt;br /&gt;
&lt;br /&gt;
Ebenso können einzelne Kriterien pro Domain abgeschaltet werden. Wenn z.B. in Ihren Geschäftsemails oft hohe Euro Beträge vorkommen, wollen Sie vielleicht das Symbol LOTS_OF_MONEY für die Domain meinefirma.de ignorieren. Dann bitte ebenfalls eine E-Mail an den Hostsharing Service schreiben, und wir stellen das für die Domain ein.&lt;br /&gt;
&lt;br /&gt;
= Alternative 2: Persönlichen Spamfilter einrichten =&lt;br /&gt;
&lt;br /&gt;
Hier geht es darum, wie Personen mit (grundlegenden) Kenntnissen in der Shell-Bedienung für ihr persönliches Postfach einen Spam-Filter einrichten können. Spamassassin kann für jedes Postfach individuell konfiguriert werden. Für die Einrichtung und Pflege ist Shell-Zugang zur Mailbox erforderlich.  &lt;br /&gt;
&lt;br /&gt;
Ein Bayesfilter kann mit den persönlichen Nachrichten angelernt werden. Dazu sind tiefergehende Shell-Kenntnisse erforderlich (Shell-Skript und Einrichtung eines systemd-Timers).&lt;br /&gt;
&lt;br /&gt;
== Spamassassin Konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Der Spamfilter &amp;quot;Spamassassin&amp;quot; ist bei HS vorinstalliert. Es muss über das Kommando &amp;quot;spamc&amp;quot;, das Kommando zur Nutzung des Spamassassin-Daemon, in der Datei &amp;quot;.forward&amp;quot; eines Mail-Users aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
&amp;quot;|/usr/bin/spamc -U /var/run/spamd -e /usr/lib/dovecot/deliver&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Effekt: Spammassassin schreibt seine Testergebnisse in die Headerzeilen jeder E-Mail und leitet die E-Mails weiter an das Programm &amp;quot;deliver&amp;quot; aus dem Dovecot-Paket. Das Sortieren von Spam-EMail in einen Spam-Ordner lässt sich mit Sieve-Filtern umsetzen.&lt;br /&gt;
&lt;br /&gt;
In dieser Variante kann man Spamassassin individuell konfigurieren. Dazu legt man im $HOME des Mailbox-Account ein Verzeichnis &amp;quot;$HOME/.spamassassin&amp;quot; an. Die Konfiguration erfolgt in der Datei &amp;quot;$HOME/.spamassassin/user_prefs&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Konfigurationsbeispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
required_score          4.0&lt;br /&gt;
report_safe             0&lt;br /&gt;
use_bayes               1&lt;br /&gt;
bayes_auto_learn        1&lt;br /&gt;
skip_rbl_checks         0&lt;br /&gt;
use_razor2              1&lt;br /&gt;
use_pyzor               1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bayesfilter anlernen ==&lt;br /&gt;
&lt;br /&gt;
Wenn der Bayesfilter eingeschaltet ist, macht es Sinn den Filter mit den Befehlen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
sa-learn --spam &amp;lt;platzhalter-spam-nachricht-oder-verzeichnis&amp;gt;&lt;br /&gt;
sa-learn --ham &amp;lt;platzhalter-erwünschte-nachricht-oder-verzeichnis&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
anzulernen. Ein Bash-Skript für das Erlernen von Spam/Nonspam kann wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
HAM_MIN_AGE_DAYS=5&lt;br /&gt;
MAILDIR_HAM=${HOME}/Maildir/cur&lt;br /&gt;
TMPDIR=${HOME}/sa-learn-tmp&lt;br /&gt;
SPAMFOLDER=Junk&lt;br /&gt;
SPAMFOLDER_LEARNED=${SPAMFOLDER}.sa-learned&lt;br /&gt;
MAILDIR_SPAM=${HOME}/Maildir/.${SPAMFOLDER}&lt;br /&gt;
&lt;br /&gt;
# Learn spam from MAILDIR_SPAM&lt;br /&gt;
mkdir -p ${TMPDIR}/spam&lt;br /&gt;
rm -f ${TMPDIR}/spam/*&lt;br /&gt;
SPAM_COUNT=0&lt;br /&gt;
for DIR in &amp;quot;cur&amp;quot; &amp;quot;new&amp;quot;; do&lt;br /&gt;
	DIR=&amp;quot;${MAILDIR_SPAM}/${DIR}&amp;quot;&lt;br /&gt;
	cd ${DIR}&lt;br /&gt;
	# echo &amp;quot;---&amp;quot; DIR ${DIR}&lt;br /&gt;
	for SPAMFILE in $( ls ); do&lt;br /&gt;
		# echo &amp;quot;   &amp;quot; ${SPAMFILE}&lt;br /&gt;
		TMPFILE=&amp;quot;${TMPDIR}/spam/${SPAMFILE}&amp;quot;&lt;br /&gt;
		if ! zcat &amp;quot;${SPAMFILE}&amp;quot; &amp;gt; &amp;quot;${TMPFILE}&amp;quot; 2&amp;gt;/dev/null; then&lt;br /&gt;
			cp &amp;quot;${SPAMFILE}&amp;quot; &amp;quot;${TMPFILE}&amp;quot;&lt;br /&gt;
		fi&lt;br /&gt;
		SPAM_COUNT=$((SPAM_COUNT + 1))&lt;br /&gt;
	done&lt;br /&gt;
done&lt;br /&gt;
sa-learn --spam ${TMPDIR}/spam/*&lt;br /&gt;
&lt;br /&gt;
# Move processed spam to keep it in another folder&lt;br /&gt;
doveadm move -u $(whoami) INBOX.${SPAMFOLDER_LEARNED} mailbox INBOX.${SPAMFOLDER} all 2&amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
# Learn ham from MAILDIR_HAM (&amp;gt; HAM_MIN_AGE_DAYS days; max. 2x spam count)&lt;br /&gt;
mkdir -p ${TMPDIR}/ham&lt;br /&gt;
rm -f ${TMPDIR}/ham/*&lt;br /&gt;
cd ${MAILDIR_HAM}&lt;br /&gt;
MAX_HAM=$((SPAM_COUNT * 2))&lt;br /&gt;
HAM_COUNT=0&lt;br /&gt;
for HAMFILE in $( find . -type f -mtime +${HAM_MIN_AGE_DAYS} -printf &#039;%T@ %p\n&#039; | sort -rn | cut -d&#039; &#039; -f2- | head -n ${MAX_HAM} ); do&lt;br /&gt;
	TMPFILE=&amp;quot;${TMPDIR}/ham/${HAMFILE}&amp;quot;&lt;br /&gt;
	if ! zcat &amp;quot;${HAMFILE}&amp;quot; &amp;gt; &amp;quot;${TMPFILE}&amp;quot; 2&amp;gt;/dev/null; then&lt;br /&gt;
		cp &amp;quot;${HAMFILE}&amp;quot; &amp;quot;${TMPFILE}&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
	HAM_COUNT=$((HAM_COUNT + 1))&lt;br /&gt;
done&lt;br /&gt;
sa-learn --ham ${TMPDIR}/ham/*&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Training erfolgte mit ${SPAM_COUNT} Spam, ${HAM_COUNT} (max ${MAX_HAM}) Ham Mails.&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei werden Mails verarbeitet, unabhängig davon, ob sie durch Procmail (unkomprimiert) oder über den Mailclient (komprimiert) verschoben vorliegen.&lt;br /&gt;
Für Ham wird ein Teil des Inhalts der Inbox verwendet, wobei die empfohlene Maximalanzahl von zweimal der Spammailanzahl und ein minimales Alter in Tagen gilt. Das Mindestalter garantiert ein inzwischen erfolgtes manuelles Aussortieren des Spams. Der verarbeitete Spam wird anschließend in ein separates Verzeichnis verschoben um den späteren Zugriff auf False Positives zu ermöglichen.&lt;br /&gt;
&lt;br /&gt;
Das Skript wird über einen systemd-Timer täglich ausgeführt, der pro Mailbox eingerichtet werden muss.&lt;br /&gt;
&lt;br /&gt;
= Alternative 3: SecureMX zubuchen =&lt;br /&gt;
&lt;br /&gt;
Über unseren Domain-Anbieter &amp;quot;Partnergate&amp;quot; bietet Hostsharing als dritte Alternative die kommerzielle Spam-Appliance von Cisco an. Das Produkt heißt bei Partnergate &amp;quot;SecureMX&amp;quot;: https://www.hostsharing.net/loesungen/email/spam-abwehr/&lt;br /&gt;
&lt;br /&gt;
Die Nutzung von SecureMX ist kostenpflichtig und wird auf Wunsch vom Hostsharing-Service eingerichtet. &lt;br /&gt;
&lt;br /&gt;
Es ist zu beachten, dass bei der Nutzung von SecureMX alle eingehenden E-Mail Nachrichten über Server geleitet werden, die nicht unter der Kontrolle von Hostsharing stehen und proprietäre Software einsetzen. Dieser Sachverhalt muss vom Mitglied ggf. datenschutzrechtlich bewertet werden.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Glossar]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Spamfilter&amp;diff=7595</id>
		<title>Spamfilter</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Spamfilter&amp;diff=7595"/>
		<updated>2026-06-24T08:14:00Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Den Filter trainieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Einrichtung, Konfiguration und Optimierung eines Spamfilters auf den Hostsharing Servern. Der Artikel beschreibt drei alternative Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
1. Die Nutzung der &amp;quot;xmailin&amp;quot;-Server für eine komplette Domain&lt;br /&gt;
&lt;br /&gt;
2. Die Einrichtung von Spamassassin für das persönliche Postfach&lt;br /&gt;
&lt;br /&gt;
3. Nutzung der Spam-Appliance &amp;quot;SecureMX&amp;quot; für eine komplette Domain&lt;br /&gt;
&lt;br /&gt;
= Alternative 1: Maileingangsserver mit Spamfilter nutzen =&lt;br /&gt;
&lt;br /&gt;
Diese Alternative kann von einer Domain-Administration oder vom &amp;quot;Webmaster on Demand&amp;quot; für eine oder mehrere E-Mail-Domains eingerichtet werden. Ein globaler Sieve-Filter für markiete Spam-Nachrichten ist in der Standard-Konfiguration voreingestellt, &lt;br /&gt;
so dass Nachrichten mit Spam-Bewertung in einen vorhandenen Spam-Ordner einsortiert werden.&lt;br /&gt;
&lt;br /&gt;
Seit einigen Jahren betreibt Hostsharing zusätzlich zu den vorkonfigurierte Maileingangsservern einen zweiten Satz von Maileingangsservern, bei denen Spamassassin bereits beim Annehmen einer E-Mail ausgeführt wird. Anfang 2026 ist eine Gruppe von Eingangsserver mit der Software &amp;quot;rspamd&amp;quot; hinzugekommen. Eingehende Nachrichten mit Malware oder sehr hoher Bewertung als Spam werden bereits im SMTP-Dialog abgewiesen. Nachrichten mit einem geringeren Spam-Score werden angenommen und zugestellt. Spamassassin fügt die Bewertung für diese Nachrichten in die Header der Nachricht ein, zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
X-Spam-Status: Yes, score=11.29&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der globale Sieve-Filter schiebt Nachrichten mit der Markierung &amp;quot;X-Spam-Status: Yes&amp;quot; in einen Ordner &amp;quot;Junk&amp;quot;, wenn der Ordner vorhanden ist. Viele Mailprogramme legen beim ersten Verbinden mit dem IMAP-Server einen solchen Ordner an. Unser &amp;quot;Roundcube&amp;quot;&lt;br /&gt;
unter https://webmail.hostsharing.net ist entsprechend eingerichtet, so dass der Ordner nach einer Nutzung von Webmail vorhanden ist.&lt;br /&gt;
&lt;br /&gt;
== Eingangsserver konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Die Maileingangsserver mit Rspamd lassen sich pro Domain konfigurieren, indem die MX-Records im DNS-Zonefile gegenüber dem Default-Zonefile angepasst werden.&lt;br /&gt;
&lt;br /&gt;
Im Zonefile entfällt der Platzhalter &amp;quot;{MX_RR}&amp;quot;. Stattdessen werden die folgenden MX-Records eingefügt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
{DOM_HOSTNAME}.    IN  MX  30  xmailin1.hostsharing.net.&lt;br /&gt;
{DOM_HOSTNAME}.    IN  MX  30  xmailin2.hostsharing.net.&lt;br /&gt;
{DOM_HOSTNAME}.    IN  MX  30  xmailin3.hostsharing.net.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur Änderung der DNS-Zone siehe: https://www.hostsharing.net/doc/managed-operations-platform/zonefile/&lt;br /&gt;
Wer sich die Aktion auf der Shell nicht zutraut, möge bitte den &amp;quot;Webmaster on Demand&amp;quot; beauftragen.&lt;br /&gt;
&lt;br /&gt;
Die Änderung des Zonefile kann für eine Domain &amp;quot;hs-example.de&amp;quot; wie folgt überprüft werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
dig +short -t MX hs-example.de @dns1.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die folgende Ausgabe wird erwartet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
30 xmailin2.hostsharing.net.&lt;br /&gt;
30 xmailin3.hostsharing.net.&lt;br /&gt;
30 xmailin1.hostsharing.net.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Reihenfolge der drei Eingangsserver kann variieren. &lt;br /&gt;
Die führende Zahl ist die Priorität im MX-Record (hier der Wert &amp;quot;30&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Den Filter trainieren ==&lt;br /&gt;
Wer auch am Trainieren des Filters mitwirken möchte, sendet den/die Benutzername/n xyz00-name (das ist der eMail Benutzername) an:&lt;br /&gt;
service (at) hostsharing (dot) net&lt;br /&gt;
&lt;br /&gt;
Das bedeutet dann, dass das Verschieben einer E-Mail in den Spam-Ordner (Junk) darauf Einfluß hat, das zukünftige E-Mails in dieser Art besser als Spam erkannt werden. Andersrum genauso: wenn ich eine E-Mail aus dem Spam-Ordner (Junk) in einen anderen Ordner verschiebe, werden in Zukunft ähnliche E-Mails auch nicht mehr als Spam erkannt.&lt;br /&gt;
&lt;br /&gt;
Da das Training gemeinschaftlich ist, sollte bitte darauf geachtet werden, Newsletter nicht in den Junk Ordner zu schieben, sondern sich davon abzumelden und die E-Mail zu löschen. Nur weil du den Newsletter der Firma xy nicht mehr magst, soll er für andere Benutzer nicht automatisch als Spam erkannt werden.&lt;br /&gt;
&lt;br /&gt;
== Konfiguration pro Domain ==&lt;br /&gt;
&lt;br /&gt;
= Alternative 2: Persönlichen Spamfilter einrichten =&lt;br /&gt;
&lt;br /&gt;
Hier geht es darum, wie Personen mit (grundlegenden) Kenntnissen in der Shell-Bedienung für ihr persönliches Postfach einen Spam-Filter einrichten können. Spamassassin kann für jedes Postfach individuell konfiguriert werden. Für die Einrichtung und Pflege ist Shell-Zugang zur Mailbox erforderlich.  &lt;br /&gt;
&lt;br /&gt;
Ein Bayesfilter kann mit den persönlichen Nachrichten angelernt werden. Dazu sind tiefergehende Shell-Kenntnisse erforderlich (Shell-Skript und Einrichtung eines systemd-Timers).&lt;br /&gt;
&lt;br /&gt;
== Spamassassin Konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Der Spamfilter &amp;quot;Spamassassin&amp;quot; ist bei HS vorinstalliert. Es muss über das Kommando &amp;quot;spamc&amp;quot;, das Kommando zur Nutzung des Spamassassin-Daemon, in der Datei &amp;quot;.forward&amp;quot; eines Mail-Users aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
&amp;quot;|/usr/bin/spamc -U /var/run/spamd -e /usr/lib/dovecot/deliver&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Effekt: Spammassassin schreibt seine Testergebnisse in die Headerzeilen jeder E-Mail und leitet die E-Mails weiter an das Programm &amp;quot;deliver&amp;quot; aus dem Dovecot-Paket. Das Sortieren von Spam-EMail in einen Spam-Ordner lässt sich mit Sieve-Filtern umsetzen.&lt;br /&gt;
&lt;br /&gt;
In dieser Variante kann man Spamassassin individuell konfigurieren. Dazu legt man im $HOME des Mailbox-Account ein Verzeichnis &amp;quot;$HOME/.spamassassin&amp;quot; an. Die Konfiguration erfolgt in der Datei &amp;quot;$HOME/.spamassassin/user_prefs&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Konfigurationsbeispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
required_score          4.0&lt;br /&gt;
report_safe             0&lt;br /&gt;
use_bayes               1&lt;br /&gt;
bayes_auto_learn        1&lt;br /&gt;
skip_rbl_checks         0&lt;br /&gt;
use_razor2              1&lt;br /&gt;
use_pyzor               1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bayesfilter anlernen ==&lt;br /&gt;
&lt;br /&gt;
Wenn der Bayesfilter eingeschaltet ist, macht es Sinn den Filter mit den Befehlen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
sa-learn --spam &amp;lt;platzhalter-spam-nachricht-oder-verzeichnis&amp;gt;&lt;br /&gt;
sa-learn --ham &amp;lt;platzhalter-erwünschte-nachricht-oder-verzeichnis&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
anzulernen. Ein Bash-Skript für das Erlernen von Spam/Nonspam kann wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
HAM_MIN_AGE_DAYS=5&lt;br /&gt;
MAILDIR_HAM=${HOME}/Maildir/cur&lt;br /&gt;
TMPDIR=${HOME}/sa-learn-tmp&lt;br /&gt;
SPAMFOLDER=Junk&lt;br /&gt;
SPAMFOLDER_LEARNED=${SPAMFOLDER}.sa-learned&lt;br /&gt;
MAILDIR_SPAM=${HOME}/Maildir/.${SPAMFOLDER}&lt;br /&gt;
&lt;br /&gt;
# Learn spam from MAILDIR_SPAM&lt;br /&gt;
mkdir -p ${TMPDIR}/spam&lt;br /&gt;
rm -f ${TMPDIR}/spam/*&lt;br /&gt;
SPAM_COUNT=0&lt;br /&gt;
for DIR in &amp;quot;cur&amp;quot; &amp;quot;new&amp;quot;; do&lt;br /&gt;
	DIR=&amp;quot;${MAILDIR_SPAM}/${DIR}&amp;quot;&lt;br /&gt;
	cd ${DIR}&lt;br /&gt;
	# echo &amp;quot;---&amp;quot; DIR ${DIR}&lt;br /&gt;
	for SPAMFILE in $( ls ); do&lt;br /&gt;
		# echo &amp;quot;   &amp;quot; ${SPAMFILE}&lt;br /&gt;
		TMPFILE=&amp;quot;${TMPDIR}/spam/${SPAMFILE}&amp;quot;&lt;br /&gt;
		if ! zcat &amp;quot;${SPAMFILE}&amp;quot; &amp;gt; &amp;quot;${TMPFILE}&amp;quot; 2&amp;gt;/dev/null; then&lt;br /&gt;
			cp &amp;quot;${SPAMFILE}&amp;quot; &amp;quot;${TMPFILE}&amp;quot;&lt;br /&gt;
		fi&lt;br /&gt;
		SPAM_COUNT=$((SPAM_COUNT + 1))&lt;br /&gt;
	done&lt;br /&gt;
done&lt;br /&gt;
sa-learn --spam ${TMPDIR}/spam/*&lt;br /&gt;
&lt;br /&gt;
# Move processed spam to keep it in another folder&lt;br /&gt;
doveadm move -u $(whoami) INBOX.${SPAMFOLDER_LEARNED} mailbox INBOX.${SPAMFOLDER} all 2&amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
# Learn ham from MAILDIR_HAM (&amp;gt; HAM_MIN_AGE_DAYS days; max. 2x spam count)&lt;br /&gt;
mkdir -p ${TMPDIR}/ham&lt;br /&gt;
rm -f ${TMPDIR}/ham/*&lt;br /&gt;
cd ${MAILDIR_HAM}&lt;br /&gt;
MAX_HAM=$((SPAM_COUNT * 2))&lt;br /&gt;
HAM_COUNT=0&lt;br /&gt;
for HAMFILE in $( find . -type f -mtime +${HAM_MIN_AGE_DAYS} -printf &#039;%T@ %p\n&#039; | sort -rn | cut -d&#039; &#039; -f2- | head -n ${MAX_HAM} ); do&lt;br /&gt;
	TMPFILE=&amp;quot;${TMPDIR}/ham/${HAMFILE}&amp;quot;&lt;br /&gt;
	if ! zcat &amp;quot;${HAMFILE}&amp;quot; &amp;gt; &amp;quot;${TMPFILE}&amp;quot; 2&amp;gt;/dev/null; then&lt;br /&gt;
		cp &amp;quot;${HAMFILE}&amp;quot; &amp;quot;${TMPFILE}&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
	HAM_COUNT=$((HAM_COUNT + 1))&lt;br /&gt;
done&lt;br /&gt;
sa-learn --ham ${TMPDIR}/ham/*&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Training erfolgte mit ${SPAM_COUNT} Spam, ${HAM_COUNT} (max ${MAX_HAM}) Ham Mails.&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei werden Mails verarbeitet, unabhängig davon, ob sie durch Procmail (unkomprimiert) oder über den Mailclient (komprimiert) verschoben vorliegen.&lt;br /&gt;
Für Ham wird ein Teil des Inhalts der Inbox verwendet, wobei die empfohlene Maximalanzahl von zweimal der Spammailanzahl und ein minimales Alter in Tagen gilt. Das Mindestalter garantiert ein inzwischen erfolgtes manuelles Aussortieren des Spams. Der verarbeitete Spam wird anschließend in ein separates Verzeichnis verschoben um den späteren Zugriff auf False Positives zu ermöglichen.&lt;br /&gt;
&lt;br /&gt;
Das Skript wird über einen systemd-Timer täglich ausgeführt, der pro Mailbox eingerichtet werden muss.&lt;br /&gt;
&lt;br /&gt;
= Alternative 3: SecureMX zubuchen =&lt;br /&gt;
&lt;br /&gt;
Über unseren Domain-Anbieter &amp;quot;Partnergate&amp;quot; bietet Hostsharing als dritte Alternative die kommerzielle Spam-Appliance von Cisco an. Das Produkt heißt bei Partnergate &amp;quot;SecureMX&amp;quot;: https://www.hostsharing.net/loesungen/email/spam-abwehr/&lt;br /&gt;
&lt;br /&gt;
Die Nutzung von SecureMX ist kostenpflichtig und wird auf Wunsch vom Hostsharing-Service eingerichtet. &lt;br /&gt;
&lt;br /&gt;
Es ist zu beachten, dass bei der Nutzung von SecureMX alle eingehenden E-Mail Nachrichten über Server geleitet werden, die nicht unter der Kontrolle von Hostsharing stehen und proprietäre Software einsetzen. Dieser Sachverhalt muss vom Mitglied ggf. datenschutzrechtlich bewertet werden.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Glossar]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Spamfilter&amp;diff=7594</id>
		<title>Spamfilter</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Spamfilter&amp;diff=7594"/>
		<updated>2026-06-24T08:13:12Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Den Filter trainieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Einrichtung, Konfiguration und Optimierung eines Spamfilters auf den Hostsharing Servern. Der Artikel beschreibt drei alternative Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
1. Die Nutzung der &amp;quot;xmailin&amp;quot;-Server für eine komplette Domain&lt;br /&gt;
&lt;br /&gt;
2. Die Einrichtung von Spamassassin für das persönliche Postfach&lt;br /&gt;
&lt;br /&gt;
3. Nutzung der Spam-Appliance &amp;quot;SecureMX&amp;quot; für eine komplette Domain&lt;br /&gt;
&lt;br /&gt;
= Alternative 1: Maileingangsserver mit Spamfilter nutzen =&lt;br /&gt;
&lt;br /&gt;
Diese Alternative kann von einer Domain-Administration oder vom &amp;quot;Webmaster on Demand&amp;quot; für eine oder mehrere E-Mail-Domains eingerichtet werden. Ein globaler Sieve-Filter für markiete Spam-Nachrichten ist in der Standard-Konfiguration voreingestellt, &lt;br /&gt;
so dass Nachrichten mit Spam-Bewertung in einen vorhandenen Spam-Ordner einsortiert werden.&lt;br /&gt;
&lt;br /&gt;
Seit einigen Jahren betreibt Hostsharing zusätzlich zu den vorkonfigurierte Maileingangsservern einen zweiten Satz von Maileingangsservern, bei denen Spamassassin bereits beim Annehmen einer E-Mail ausgeführt wird. Anfang 2026 ist eine Gruppe von Eingangsserver mit der Software &amp;quot;rspamd&amp;quot; hinzugekommen. Eingehende Nachrichten mit Malware oder sehr hoher Bewertung als Spam werden bereits im SMTP-Dialog abgewiesen. Nachrichten mit einem geringeren Spam-Score werden angenommen und zugestellt. Spamassassin fügt die Bewertung für diese Nachrichten in die Header der Nachricht ein, zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
X-Spam-Status: Yes, score=11.29&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der globale Sieve-Filter schiebt Nachrichten mit der Markierung &amp;quot;X-Spam-Status: Yes&amp;quot; in einen Ordner &amp;quot;Junk&amp;quot;, wenn der Ordner vorhanden ist. Viele Mailprogramme legen beim ersten Verbinden mit dem IMAP-Server einen solchen Ordner an. Unser &amp;quot;Roundcube&amp;quot;&lt;br /&gt;
unter https://webmail.hostsharing.net ist entsprechend eingerichtet, so dass der Ordner nach einer Nutzung von Webmail vorhanden ist.&lt;br /&gt;
&lt;br /&gt;
== Eingangsserver konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Die Maileingangsserver mit Rspamd lassen sich pro Domain konfigurieren, indem die MX-Records im DNS-Zonefile gegenüber dem Default-Zonefile angepasst werden.&lt;br /&gt;
&lt;br /&gt;
Im Zonefile entfällt der Platzhalter &amp;quot;{MX_RR}&amp;quot;. Stattdessen werden die folgenden MX-Records eingefügt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
{DOM_HOSTNAME}.    IN  MX  30  xmailin1.hostsharing.net.&lt;br /&gt;
{DOM_HOSTNAME}.    IN  MX  30  xmailin2.hostsharing.net.&lt;br /&gt;
{DOM_HOSTNAME}.    IN  MX  30  xmailin3.hostsharing.net.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur Änderung der DNS-Zone siehe: https://www.hostsharing.net/doc/managed-operations-platform/zonefile/&lt;br /&gt;
Wer sich die Aktion auf der Shell nicht zutraut, möge bitte den &amp;quot;Webmaster on Demand&amp;quot; beauftragen.&lt;br /&gt;
&lt;br /&gt;
Die Änderung des Zonefile kann für eine Domain &amp;quot;hs-example.de&amp;quot; wie folgt überprüft werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
dig +short -t MX hs-example.de @dns1.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die folgende Ausgabe wird erwartet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
30 xmailin2.hostsharing.net.&lt;br /&gt;
30 xmailin3.hostsharing.net.&lt;br /&gt;
30 xmailin1.hostsharing.net.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Reihenfolge der drei Eingangsserver kann variieren. &lt;br /&gt;
Die führende Zahl ist die Priorität im MX-Record (hier der Wert &amp;quot;30&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Den Filter trainieren ==&lt;br /&gt;
Wer auch am Trainieren des Filters mitwirken möchte, sendet den/die Benutzername/n xyz00-name (das ist der eMail Benutzername) an:&lt;br /&gt;
service (at) hostsharing (dot) net&lt;br /&gt;
&lt;br /&gt;
Das bedeutet dann, dass das Verschieben einer E-Mail in den Spam-Ordner (Junk) darauf Einfluß hat, das zukünftige E-Mails in dieser Art besser als Spam erkannt werden. Andersrum genauso: wenn ich eine E-Mail aus dem Spam-Ordner (Junk) in einen anderen Ordner verschiebe, werden in Zukunft ähnliche E-Mails auch nicht mehr als Spam erkannt.&lt;br /&gt;
&lt;br /&gt;
Da das Training gemeinschaftlich ist, sollte bitte darauf geachtet werden, Newsletter nicht in den Junk Ordner zu schieben, sondern sich davon abzumelden und die E-Mail zu löschen. Nur weil du den Newsletter der Firma xy nicht mehr magst, soll er für andere Benutzer nicht automatisch als Spam erkannt werden.&lt;br /&gt;
&lt;br /&gt;
= Alternative 2: Persönlichen Spamfilter einrichten =&lt;br /&gt;
&lt;br /&gt;
Hier geht es darum, wie Personen mit (grundlegenden) Kenntnissen in der Shell-Bedienung für ihr persönliches Postfach einen Spam-Filter einrichten können. Spamassassin kann für jedes Postfach individuell konfiguriert werden. Für die Einrichtung und Pflege ist Shell-Zugang zur Mailbox erforderlich.  &lt;br /&gt;
&lt;br /&gt;
Ein Bayesfilter kann mit den persönlichen Nachrichten angelernt werden. Dazu sind tiefergehende Shell-Kenntnisse erforderlich (Shell-Skript und Einrichtung eines systemd-Timers).&lt;br /&gt;
&lt;br /&gt;
== Spamassassin Konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Der Spamfilter &amp;quot;Spamassassin&amp;quot; ist bei HS vorinstalliert. Es muss über das Kommando &amp;quot;spamc&amp;quot;, das Kommando zur Nutzung des Spamassassin-Daemon, in der Datei &amp;quot;.forward&amp;quot; eines Mail-Users aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
&amp;quot;|/usr/bin/spamc -U /var/run/spamd -e /usr/lib/dovecot/deliver&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Effekt: Spammassassin schreibt seine Testergebnisse in die Headerzeilen jeder E-Mail und leitet die E-Mails weiter an das Programm &amp;quot;deliver&amp;quot; aus dem Dovecot-Paket. Das Sortieren von Spam-EMail in einen Spam-Ordner lässt sich mit Sieve-Filtern umsetzen.&lt;br /&gt;
&lt;br /&gt;
In dieser Variante kann man Spamassassin individuell konfigurieren. Dazu legt man im $HOME des Mailbox-Account ein Verzeichnis &amp;quot;$HOME/.spamassassin&amp;quot; an. Die Konfiguration erfolgt in der Datei &amp;quot;$HOME/.spamassassin/user_prefs&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Konfigurationsbeispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
required_score          4.0&lt;br /&gt;
report_safe             0&lt;br /&gt;
use_bayes               1&lt;br /&gt;
bayes_auto_learn        1&lt;br /&gt;
skip_rbl_checks         0&lt;br /&gt;
use_razor2              1&lt;br /&gt;
use_pyzor               1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bayesfilter anlernen ==&lt;br /&gt;
&lt;br /&gt;
Wenn der Bayesfilter eingeschaltet ist, macht es Sinn den Filter mit den Befehlen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
sa-learn --spam &amp;lt;platzhalter-spam-nachricht-oder-verzeichnis&amp;gt;&lt;br /&gt;
sa-learn --ham &amp;lt;platzhalter-erwünschte-nachricht-oder-verzeichnis&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
anzulernen. Ein Bash-Skript für das Erlernen von Spam/Nonspam kann wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
HAM_MIN_AGE_DAYS=5&lt;br /&gt;
MAILDIR_HAM=${HOME}/Maildir/cur&lt;br /&gt;
TMPDIR=${HOME}/sa-learn-tmp&lt;br /&gt;
SPAMFOLDER=Junk&lt;br /&gt;
SPAMFOLDER_LEARNED=${SPAMFOLDER}.sa-learned&lt;br /&gt;
MAILDIR_SPAM=${HOME}/Maildir/.${SPAMFOLDER}&lt;br /&gt;
&lt;br /&gt;
# Learn spam from MAILDIR_SPAM&lt;br /&gt;
mkdir -p ${TMPDIR}/spam&lt;br /&gt;
rm -f ${TMPDIR}/spam/*&lt;br /&gt;
SPAM_COUNT=0&lt;br /&gt;
for DIR in &amp;quot;cur&amp;quot; &amp;quot;new&amp;quot;; do&lt;br /&gt;
	DIR=&amp;quot;${MAILDIR_SPAM}/${DIR}&amp;quot;&lt;br /&gt;
	cd ${DIR}&lt;br /&gt;
	# echo &amp;quot;---&amp;quot; DIR ${DIR}&lt;br /&gt;
	for SPAMFILE in $( ls ); do&lt;br /&gt;
		# echo &amp;quot;   &amp;quot; ${SPAMFILE}&lt;br /&gt;
		TMPFILE=&amp;quot;${TMPDIR}/spam/${SPAMFILE}&amp;quot;&lt;br /&gt;
		if ! zcat &amp;quot;${SPAMFILE}&amp;quot; &amp;gt; &amp;quot;${TMPFILE}&amp;quot; 2&amp;gt;/dev/null; then&lt;br /&gt;
			cp &amp;quot;${SPAMFILE}&amp;quot; &amp;quot;${TMPFILE}&amp;quot;&lt;br /&gt;
		fi&lt;br /&gt;
		SPAM_COUNT=$((SPAM_COUNT + 1))&lt;br /&gt;
	done&lt;br /&gt;
done&lt;br /&gt;
sa-learn --spam ${TMPDIR}/spam/*&lt;br /&gt;
&lt;br /&gt;
# Move processed spam to keep it in another folder&lt;br /&gt;
doveadm move -u $(whoami) INBOX.${SPAMFOLDER_LEARNED} mailbox INBOX.${SPAMFOLDER} all 2&amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
# Learn ham from MAILDIR_HAM (&amp;gt; HAM_MIN_AGE_DAYS days; max. 2x spam count)&lt;br /&gt;
mkdir -p ${TMPDIR}/ham&lt;br /&gt;
rm -f ${TMPDIR}/ham/*&lt;br /&gt;
cd ${MAILDIR_HAM}&lt;br /&gt;
MAX_HAM=$((SPAM_COUNT * 2))&lt;br /&gt;
HAM_COUNT=0&lt;br /&gt;
for HAMFILE in $( find . -type f -mtime +${HAM_MIN_AGE_DAYS} -printf &#039;%T@ %p\n&#039; | sort -rn | cut -d&#039; &#039; -f2- | head -n ${MAX_HAM} ); do&lt;br /&gt;
	TMPFILE=&amp;quot;${TMPDIR}/ham/${HAMFILE}&amp;quot;&lt;br /&gt;
	if ! zcat &amp;quot;${HAMFILE}&amp;quot; &amp;gt; &amp;quot;${TMPFILE}&amp;quot; 2&amp;gt;/dev/null; then&lt;br /&gt;
		cp &amp;quot;${HAMFILE}&amp;quot; &amp;quot;${TMPFILE}&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
	HAM_COUNT=$((HAM_COUNT + 1))&lt;br /&gt;
done&lt;br /&gt;
sa-learn --ham ${TMPDIR}/ham/*&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Training erfolgte mit ${SPAM_COUNT} Spam, ${HAM_COUNT} (max ${MAX_HAM}) Ham Mails.&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei werden Mails verarbeitet, unabhängig davon, ob sie durch Procmail (unkomprimiert) oder über den Mailclient (komprimiert) verschoben vorliegen.&lt;br /&gt;
Für Ham wird ein Teil des Inhalts der Inbox verwendet, wobei die empfohlene Maximalanzahl von zweimal der Spammailanzahl und ein minimales Alter in Tagen gilt. Das Mindestalter garantiert ein inzwischen erfolgtes manuelles Aussortieren des Spams. Der verarbeitete Spam wird anschließend in ein separates Verzeichnis verschoben um den späteren Zugriff auf False Positives zu ermöglichen.&lt;br /&gt;
&lt;br /&gt;
Das Skript wird über einen systemd-Timer täglich ausgeführt, der pro Mailbox eingerichtet werden muss.&lt;br /&gt;
&lt;br /&gt;
= Alternative 3: SecureMX zubuchen =&lt;br /&gt;
&lt;br /&gt;
Über unseren Domain-Anbieter &amp;quot;Partnergate&amp;quot; bietet Hostsharing als dritte Alternative die kommerzielle Spam-Appliance von Cisco an. Das Produkt heißt bei Partnergate &amp;quot;SecureMX&amp;quot;: https://www.hostsharing.net/loesungen/email/spam-abwehr/&lt;br /&gt;
&lt;br /&gt;
Die Nutzung von SecureMX ist kostenpflichtig und wird auf Wunsch vom Hostsharing-Service eingerichtet. &lt;br /&gt;
&lt;br /&gt;
Es ist zu beachten, dass bei der Nutzung von SecureMX alle eingehenden E-Mail Nachrichten über Server geleitet werden, die nicht unter der Kontrolle von Hostsharing stehen und proprietäre Software einsetzen. Dieser Sachverhalt muss vom Mitglied ggf. datenschutzrechtlich bewertet werden.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Glossar]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Spamfilter&amp;diff=7593</id>
		<title>Spamfilter</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Spamfilter&amp;diff=7593"/>
		<updated>2026-06-24T08:09:10Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Filtern lernen teilnehmen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Einrichtung, Konfiguration und Optimierung eines Spamfilters auf den Hostsharing Servern. Der Artikel beschreibt drei alternative Möglichkeiten: &lt;br /&gt;
&lt;br /&gt;
1. Die Nutzung der &amp;quot;xmailin&amp;quot;-Server für eine komplette Domain&lt;br /&gt;
&lt;br /&gt;
2. Die Einrichtung von Spamassassin für das persönliche Postfach&lt;br /&gt;
&lt;br /&gt;
3. Nutzung der Spam-Appliance &amp;quot;SecureMX&amp;quot; für eine komplette Domain&lt;br /&gt;
&lt;br /&gt;
= Alternative 1: Maileingangsserver mit Spamfilter nutzen =&lt;br /&gt;
&lt;br /&gt;
Diese Alternative kann von einer Domain-Administration oder vom &amp;quot;Webmaster on Demand&amp;quot; für eine oder mehrere E-Mail-Domains eingerichtet werden. Ein globaler Sieve-Filter für markiete Spam-Nachrichten ist in der Standard-Konfiguration voreingestellt, &lt;br /&gt;
so dass Nachrichten mit Spam-Bewertung in einen vorhandenen Spam-Ordner einsortiert werden.&lt;br /&gt;
&lt;br /&gt;
Seit einigen Jahren betreibt Hostsharing zusätzlich zu den vorkonfigurierte Maileingangsservern einen zweiten Satz von Maileingangsservern, bei denen Spamassassin bereits beim Annehmen einer E-Mail ausgeführt wird. Anfang 2026 ist eine Gruppe von Eingangsserver mit der Software &amp;quot;rspamd&amp;quot; hinzugekommen. Eingehende Nachrichten mit Malware oder sehr hoher Bewertung als Spam werden bereits im SMTP-Dialog abgewiesen. Nachrichten mit einem geringeren Spam-Score werden angenommen und zugestellt. Spamassassin fügt die Bewertung für diese Nachrichten in die Header der Nachricht ein, zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
X-Spam-Status: Yes, score=11.29&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der globale Sieve-Filter schiebt Nachrichten mit der Markierung &amp;quot;X-Spam-Status: Yes&amp;quot; in einen Ordner &amp;quot;Junk&amp;quot;, wenn der Ordner vorhanden ist. Viele Mailprogramme legen beim ersten Verbinden mit dem IMAP-Server einen solchen Ordner an. Unser &amp;quot;Roundcube&amp;quot;&lt;br /&gt;
unter https://webmail.hostsharing.net ist entsprechend eingerichtet, so dass der Ordner nach einer Nutzung von Webmail vorhanden ist.&lt;br /&gt;
&lt;br /&gt;
== Eingangsserver konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Die Maileingangsserver mit Rspamd lassen sich pro Domain konfigurieren, indem die MX-Records im DNS-Zonefile gegenüber dem Default-Zonefile angepasst werden.&lt;br /&gt;
&lt;br /&gt;
Im Zonefile entfällt der Platzhalter &amp;quot;{MX_RR}&amp;quot;. Stattdessen werden die folgenden MX-Records eingefügt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
{DOM_HOSTNAME}.    IN  MX  30  xmailin1.hostsharing.net.&lt;br /&gt;
{DOM_HOSTNAME}.    IN  MX  30  xmailin2.hostsharing.net.&lt;br /&gt;
{DOM_HOSTNAME}.    IN  MX  30  xmailin3.hostsharing.net.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur Änderung der DNS-Zone siehe: https://www.hostsharing.net/doc/managed-operations-platform/zonefile/&lt;br /&gt;
Wer sich die Aktion auf der Shell nicht zutraut, möge bitte den &amp;quot;Webmaster on Demand&amp;quot; beauftragen.&lt;br /&gt;
&lt;br /&gt;
Die Änderung des Zonefile kann für eine Domain &amp;quot;hs-example.de&amp;quot; wie folgt überprüft werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
dig +short -t MX hs-example.de @dns1.hostsharing.net&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die folgende Ausgabe wird erwartet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
30 xmailin2.hostsharing.net.&lt;br /&gt;
30 xmailin3.hostsharing.net.&lt;br /&gt;
30 xmailin1.hostsharing.net.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Reihenfolge der drei Eingangsserver kann variieren. &lt;br /&gt;
Die führende Zahl ist die Priorität im MX-Record (hier der Wert &amp;quot;30&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Den Filter trainieren ==&lt;br /&gt;
Wer auch am Trainieren des Filters mitwirken möchte, sendet den/die Benutzername/n xyz00-name (das ist der eMail Benutzername) an:&lt;br /&gt;
service (at) hostsharing (dot) net&lt;br /&gt;
&lt;br /&gt;
= Alternative 2: Persönlichen Spamfilter einrichten =&lt;br /&gt;
&lt;br /&gt;
Hier geht es darum, wie Personen mit (grundlegenden) Kenntnissen in der Shell-Bedienung für ihr persönliches Postfach einen Spam-Filter einrichten können. Spamassassin kann für jedes Postfach individuell konfiguriert werden. Für die Einrichtung und Pflege ist Shell-Zugang zur Mailbox erforderlich.  &lt;br /&gt;
&lt;br /&gt;
Ein Bayesfilter kann mit den persönlichen Nachrichten angelernt werden. Dazu sind tiefergehende Shell-Kenntnisse erforderlich (Shell-Skript und Einrichtung eines systemd-Timers).&lt;br /&gt;
&lt;br /&gt;
== Spamassassin Konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Der Spamfilter &amp;quot;Spamassassin&amp;quot; ist bei HS vorinstalliert. Es muss über das Kommando &amp;quot;spamc&amp;quot;, das Kommando zur Nutzung des Spamassassin-Daemon, in der Datei &amp;quot;.forward&amp;quot; eines Mail-Users aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
&amp;quot;|/usr/bin/spamc -U /var/run/spamd -e /usr/lib/dovecot/deliver&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Effekt: Spammassassin schreibt seine Testergebnisse in die Headerzeilen jeder E-Mail und leitet die E-Mails weiter an das Programm &amp;quot;deliver&amp;quot; aus dem Dovecot-Paket. Das Sortieren von Spam-EMail in einen Spam-Ordner lässt sich mit Sieve-Filtern umsetzen.&lt;br /&gt;
&lt;br /&gt;
In dieser Variante kann man Spamassassin individuell konfigurieren. Dazu legt man im $HOME des Mailbox-Account ein Verzeichnis &amp;quot;$HOME/.spamassassin&amp;quot; an. Die Konfiguration erfolgt in der Datei &amp;quot;$HOME/.spamassassin/user_prefs&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Konfigurationsbeispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
required_score          4.0&lt;br /&gt;
report_safe             0&lt;br /&gt;
use_bayes               1&lt;br /&gt;
bayes_auto_learn        1&lt;br /&gt;
skip_rbl_checks         0&lt;br /&gt;
use_razor2              1&lt;br /&gt;
use_pyzor               1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bayesfilter anlernen ==&lt;br /&gt;
&lt;br /&gt;
Wenn der Bayesfilter eingeschaltet ist, macht es Sinn den Filter mit den Befehlen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
sa-learn --spam &amp;lt;platzhalter-spam-nachricht-oder-verzeichnis&amp;gt;&lt;br /&gt;
sa-learn --ham &amp;lt;platzhalter-erwünschte-nachricht-oder-verzeichnis&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
anzulernen. Ein Bash-Skript für das Erlernen von Spam/Nonspam kann wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
HAM_MIN_AGE_DAYS=5&lt;br /&gt;
MAILDIR_HAM=${HOME}/Maildir/cur&lt;br /&gt;
TMPDIR=${HOME}/sa-learn-tmp&lt;br /&gt;
SPAMFOLDER=Junk&lt;br /&gt;
SPAMFOLDER_LEARNED=${SPAMFOLDER}.sa-learned&lt;br /&gt;
MAILDIR_SPAM=${HOME}/Maildir/.${SPAMFOLDER}&lt;br /&gt;
&lt;br /&gt;
# Learn spam from MAILDIR_SPAM&lt;br /&gt;
mkdir -p ${TMPDIR}/spam&lt;br /&gt;
rm -f ${TMPDIR}/spam/*&lt;br /&gt;
SPAM_COUNT=0&lt;br /&gt;
for DIR in &amp;quot;cur&amp;quot; &amp;quot;new&amp;quot;; do&lt;br /&gt;
	DIR=&amp;quot;${MAILDIR_SPAM}/${DIR}&amp;quot;&lt;br /&gt;
	cd ${DIR}&lt;br /&gt;
	# echo &amp;quot;---&amp;quot; DIR ${DIR}&lt;br /&gt;
	for SPAMFILE in $( ls ); do&lt;br /&gt;
		# echo &amp;quot;   &amp;quot; ${SPAMFILE}&lt;br /&gt;
		TMPFILE=&amp;quot;${TMPDIR}/spam/${SPAMFILE}&amp;quot;&lt;br /&gt;
		if ! zcat &amp;quot;${SPAMFILE}&amp;quot; &amp;gt; &amp;quot;${TMPFILE}&amp;quot; 2&amp;gt;/dev/null; then&lt;br /&gt;
			cp &amp;quot;${SPAMFILE}&amp;quot; &amp;quot;${TMPFILE}&amp;quot;&lt;br /&gt;
		fi&lt;br /&gt;
		SPAM_COUNT=$((SPAM_COUNT + 1))&lt;br /&gt;
	done&lt;br /&gt;
done&lt;br /&gt;
sa-learn --spam ${TMPDIR}/spam/*&lt;br /&gt;
&lt;br /&gt;
# Move processed spam to keep it in another folder&lt;br /&gt;
doveadm move -u $(whoami) INBOX.${SPAMFOLDER_LEARNED} mailbox INBOX.${SPAMFOLDER} all 2&amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
# Learn ham from MAILDIR_HAM (&amp;gt; HAM_MIN_AGE_DAYS days; max. 2x spam count)&lt;br /&gt;
mkdir -p ${TMPDIR}/ham&lt;br /&gt;
rm -f ${TMPDIR}/ham/*&lt;br /&gt;
cd ${MAILDIR_HAM}&lt;br /&gt;
MAX_HAM=$((SPAM_COUNT * 2))&lt;br /&gt;
HAM_COUNT=0&lt;br /&gt;
for HAMFILE in $( find . -type f -mtime +${HAM_MIN_AGE_DAYS} -printf &#039;%T@ %p\n&#039; | sort -rn | cut -d&#039; &#039; -f2- | head -n ${MAX_HAM} ); do&lt;br /&gt;
	TMPFILE=&amp;quot;${TMPDIR}/ham/${HAMFILE}&amp;quot;&lt;br /&gt;
	if ! zcat &amp;quot;${HAMFILE}&amp;quot; &amp;gt; &amp;quot;${TMPFILE}&amp;quot; 2&amp;gt;/dev/null; then&lt;br /&gt;
		cp &amp;quot;${HAMFILE}&amp;quot; &amp;quot;${TMPFILE}&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
	HAM_COUNT=$((HAM_COUNT + 1))&lt;br /&gt;
done&lt;br /&gt;
sa-learn --ham ${TMPDIR}/ham/*&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Training erfolgte mit ${SPAM_COUNT} Spam, ${HAM_COUNT} (max ${MAX_HAM}) Ham Mails.&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei werden Mails verarbeitet, unabhängig davon, ob sie durch Procmail (unkomprimiert) oder über den Mailclient (komprimiert) verschoben vorliegen.&lt;br /&gt;
Für Ham wird ein Teil des Inhalts der Inbox verwendet, wobei die empfohlene Maximalanzahl von zweimal der Spammailanzahl und ein minimales Alter in Tagen gilt. Das Mindestalter garantiert ein inzwischen erfolgtes manuelles Aussortieren des Spams. Der verarbeitete Spam wird anschließend in ein separates Verzeichnis verschoben um den späteren Zugriff auf False Positives zu ermöglichen.&lt;br /&gt;
&lt;br /&gt;
Das Skript wird über einen systemd-Timer täglich ausgeführt, der pro Mailbox eingerichtet werden muss.&lt;br /&gt;
&lt;br /&gt;
= Alternative 3: SecureMX zubuchen =&lt;br /&gt;
&lt;br /&gt;
Über unseren Domain-Anbieter &amp;quot;Partnergate&amp;quot; bietet Hostsharing als dritte Alternative die kommerzielle Spam-Appliance von Cisco an. Das Produkt heißt bei Partnergate &amp;quot;SecureMX&amp;quot;: https://www.hostsharing.net/loesungen/email/spam-abwehr/&lt;br /&gt;
&lt;br /&gt;
Die Nutzung von SecureMX ist kostenpflichtig und wird auf Wunsch vom Hostsharing-Service eingerichtet. &lt;br /&gt;
&lt;br /&gt;
Es ist zu beachten, dass bei der Nutzung von SecureMX alle eingehenden E-Mail Nachrichten über Server geleitet werden, die nicht unter der Kontrolle von Hostsharing stehen und proprietäre Software einsetzen. Dieser Sachverhalt muss vom Mitglied ggf. datenschutzrechtlich bewertet werden.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Glossar]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=NGinX_installieren&amp;diff=7592</id>
		<title>NGinX installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=NGinX_installieren&amp;diff=7592"/>
		<updated>2026-06-17T03:34:01Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Betreiben des Nginx als Apache Ersatz mit Letsencrypt und HTTP Challenge */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
Mit der Option &amp;quot;eigener Daemon&amp;quot; ist es möglich in einem Paket statt des Apache Webserver, den Hostsharing zentral zur Verfügung stellt, einen Nginx (oder einen anderen Webserver) in einem Webspace zu nutzen.&lt;br /&gt;
&lt;br /&gt;
=== Port-Weiterleitung als Apache Ersatz ===&lt;br /&gt;
&lt;br /&gt;
Mit der Bestellung des eigenen Daemon gibt man an, mit den Rechten welcher Nutzerkennung der Nginx-Prozess laufen soll. Die Nutzerkennung muss bereits angelegt sein. Ich verwende hier: &#039;&#039;xyz00-nginx&#039;&#039;. Weiterhin bittet man die Hostmaster eine Portweiterleitung über IPTables-Regeln einzurichten. Ich verwende in dieser Wikiseite 38080 für HTTP und 38443 für HTTPS. Nach Einrichtung der IPTables Regeln in der Firewall wird euer NGinX unter den normalen Ports für HTTPS und HTTPS 80 und 443 erreichbar sein.&lt;br /&gt;
&lt;br /&gt;
==== Konfiguration ====&lt;br /&gt;
&lt;br /&gt;
Nginx ist auf allen Managed Servern vorinstalliert. Wir müssen also lediglich eine Konfigurationsdatei anlegen und anschliessend eine eigene Instanz des Dienstes starten.&lt;br /&gt;
&lt;br /&gt;
Eine Beispielkonfiguration sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nginx&amp;quot; line&amp;gt;&lt;br /&gt;
error_log /home/pacs/xyz00/users/nginx/var/error.log warn;&lt;br /&gt;
pid /home/pacs/xyz00/users/nginx/var/nginx.pid;&lt;br /&gt;
events {&lt;br /&gt;
  worker_connections 4096;&lt;br /&gt;
}&lt;br /&gt;
http {&lt;br /&gt;
  include /etc/nginx/mime.types;&lt;br /&gt;
  access_log /home/pacs/xyz00/users/nginx/var/access.log;&lt;br /&gt;
  server_names_hash_bucket_size 64;&lt;br /&gt;
  server {&lt;br /&gt;
    listen xyz00.hostsharing.net:38080 default_server;&lt;br /&gt;
    server_name _;&lt;br /&gt;
    return 301 https://$host$request_uri;&lt;br /&gt;
  }&lt;br /&gt;
  server {&lt;br /&gt;
    listen xyz00.hostsharing.net:38443 ssl http2;&lt;br /&gt;
    server_name www.hs-example.de;&lt;br /&gt;
    ssl_certificate /home/pacs/xyz00/users/nginx/etc/xyz00.hs-example.de.crt;&lt;br /&gt;
    ssl_certificate_key /home/pacs/xyz00/users/nginx/etc/xyz00.hs-example.de.key;&lt;br /&gt;
    root /home/pacs/xyz00/users/nginx/htdocs;&lt;br /&gt;
    index index.html;&lt;br /&gt;
    location / {&lt;br /&gt;
      ssi on;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Betreiben des Nginx als Apache Ersatz mit Letsencrypt und HTTP Challenge ===&lt;br /&gt;
In dem Fall, dass man für einen Kunden ein Projekt auf einer Domain hostet, dessen DNS woanders eingerichtet ist,&lt;br /&gt;
dann hat man das Problem, dass das Let&#039;s Encrypt mit DNS Challenge bei Hostsharing erstmal nicht tut.&lt;br /&gt;
&lt;br /&gt;
Es gibt natürlich die Möglichkeit, die Subdomain per DNS Zonen-Delegation (siehe https://de.wikipedia.org/wiki/NS_Resource_Record#Zonendelegation) zu Hostsharing zu delegieren.&lt;br /&gt;
Falls das aber dem Kunden zu kompliziert ist, kann man auch mit der folgenden Nginx Variante arbeiten:&lt;br /&gt;
&lt;br /&gt;
Die Subdomain mit dem eigenen Nginx konfigurieren, auf den die Standardports 80 und 443 weitergeleitet werden, wie im vorhergehenden Abschnitt beschrieben.&lt;br /&gt;
&lt;br /&gt;
Dann kann man auch wieder Let&#039;s Encrypt mit HTTP Challenge einsetzen.&lt;br /&gt;
&lt;br /&gt;
Hier gibt es ein Ansible Projekt, das diesen Fall umsetzt: https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/nginx&lt;br /&gt;
&lt;br /&gt;
Es gibt dort ein Skript &amp;lt;code&amp;gt;~/bin/addwebsite.sh&amp;lt;/code&amp;gt;, das eine Subdomain entsprechend einrichtet, und automatisch das Let&#039;s Encrypt Zertifikat signiert und einrichtet.&lt;br /&gt;
&lt;br /&gt;
Ein Systemd Timer wird eingerichtet, der täglich die Gültigkeit des Zertifikates überprüft und gegebenenfalls das Zertifikat erneuert.&lt;br /&gt;
&lt;br /&gt;
Das Ansible Projekt richtet ebenfalls den systemd Service ein, der für den Start des Nginx Servers zuständig ist.&lt;br /&gt;
&lt;br /&gt;
=== Betreiben eines lokalen Nginx ===&lt;br /&gt;
&lt;br /&gt;
Es gibt Konstellationen, da soll die Webseite auf dem zentralen Apache Webserver ausgeliefert werden, aber die Dienste dahinter sind leichter mit Nginx zu konfigurieren.&lt;br /&gt;
Das macht auf einem Managed Server Sinn, wo man die Ports frei wählen kann, ohne Rücksicht auf andere Benutzer.&lt;br /&gt;
In diesem Beispiel wurde der Port 18003 gewählt, um dort intern den Nginx hören zu lassen.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall kann die Weiterleitung für den Apache so aussehen:&lt;br /&gt;
&lt;br /&gt;
Datei &amp;lt;code&amp;gt;xyz00-nginx@h99:~/doms/demo.example.org/htdocs-ssl/.htaccess&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot; line&amp;gt;&lt;br /&gt;
DirectoryIndex index.html&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteRule ^(.*) http://127.0.0.1:18003/$1 [proxy,last]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die entsprechende Nginx Konfiguration sieht so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nginx&amp;quot; line&amp;gt;&lt;br /&gt;
error_log /home/pacs/xyz00/users/nginx/var/error.log warn;&lt;br /&gt;
pid /home/pacs/xyz00/users/nginx/var/nginx.pid;&lt;br /&gt;
events {&lt;br /&gt;
  worker_connections 4096;&lt;br /&gt;
}&lt;br /&gt;
http {&lt;br /&gt;
  include /etc/nginx/mime.types;&lt;br /&gt;
  access_log /home/pacs/xyz00/nginx/var/access.log;&lt;br /&gt;
  server_names_hash_bucket_size 64;&lt;br /&gt;
  server {&lt;br /&gt;
    listen 127.0.0.1:18003;&lt;br /&gt;
    server_name _;&lt;br /&gt;
    root /home/pacs/xyz00/users/nginx/htdocs;&lt;br /&gt;
    index index.html;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier gibt es ein Ansible Projekt, das diesen Fall umsetzt: https://codeberg.org/tpokorra/hs.ansible/src/branch/main/roles/nginx&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
*[https://www.nginx.com/resources/wiki/ Offizielles Wiki von Nginx]&lt;br /&gt;
*[https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/nginx Ansible Playbook für Hostsharing]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7590</id>
		<title>Discourse installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7590"/>
		<updated>2026-06-11T20:29:08Z</updated>

		<summary type="html">&lt;p&gt;Tim00: workaround for issue with pnpm 10&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Textkasten|gelb|Für Managed Server|Ein funktionierender Discourse-Server erfordert mehrere laufende Server-Dienste. Für den Betrieb ist ein Managed Server sinnvoll.}}&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|rot|Support von der Discourse-Community|Die Discourse-Entwickler haben sich entschieden, nur eine mehr oder weniger genormte Installationsmethode (via docker) zu unterstützen. Dies ist so auf der hostsharing-Architektur aufgrund mehrerer Bedenken und Überlegungen nicht möglich. Die Community ist durchaus hilfreich, geht aber davon aus, dass quasi alle Nutzer* eine &amp;quot;supported&amp;quot;e Installation durchgeführt haben. Wenn man in entsprechenden Kanälen nach Hilfe fragt, sollte man unbedingt erwähnen, dass man discourse selber anhand dieser hier lesbaren Anleitung installiert hat, um bereits entsprechenden Kommentaren und Nachfragen vorzugreifen.}}&lt;br /&gt;
&lt;br /&gt;
== Über ==&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel wird die Installation von discourse, Version 2.1.0 (September 2018) beschrieben.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von HSAdmin wird angelegt:&lt;br /&gt;
# Ein User als Service-User mit &#039;&#039;/bin/bash&#039;&#039; als Shell, zum Beispiel Beispiel: &#039;&#039;xyz00-discourse&#039;&#039;&lt;br /&gt;
# Eine Domain mit &#039;&#039;xyz00-discourse&#039; als Domain-Administrator, zum Beispiel &#039;&#039;beispiel.discussion&#039;&#039;&lt;br /&gt;
# Einen Postgresql-User &#039;&#039;xyz00_discourseuser&#039;&#039; mit Passwort &#039;&#039;meinPasswort&#039;&#039;&lt;br /&gt;
# Eine Postgresql-Datenbank &#039;&#039;xyz00_discoursedb&#039;&#039; mit Datenbank-Owner &#039;&#039;xyz00_discourseuser&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verwendete IP-Ports der Server-Dienste:&lt;br /&gt;
# Redis: localhost:32002&lt;br /&gt;
# Discourse-Web: localhost:13000&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der PostgreSQL Datenbank ==&lt;br /&gt;
&lt;br /&gt;
Es müssen noch Erweiterungen für Postgresql installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA public;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration des Redis Server ==&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gelb|Firewall/Redis Port|Leider unterstützt discourse nicht die Kommunikation mit Redis über Unix-Sockets. Dementsprechend muss der für Redis konfigurierte Port von dem hostsharing-Support in der Firewall freigegeben werden.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd&lt;br /&gt;
mkdir redis/etc redis/lib redis/log redis/run&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/redis/etc/redis.conf&#039;&#039; mit folgendem Inhalt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
daemonize no&lt;br /&gt;
pidfile /home/pacs/xyz00/users/discourse/redis/run/redis-server.pid&lt;br /&gt;
port 32002&lt;br /&gt;
tcp-backlog 128&lt;br /&gt;
bind 127.0.0.1&lt;br /&gt;
timeout 300&lt;br /&gt;
loglevel notice&lt;br /&gt;
logfile /home/pacs/xyz00/users/discourse/redis/log/redis.log&lt;br /&gt;
databases 16&lt;br /&gt;
save 900 1&lt;br /&gt;
save 300 10&lt;br /&gt;
save 60 10000&lt;br /&gt;
slave-serve-stale-data yes&lt;br /&gt;
appendonly no&lt;br /&gt;
dbfilename dump.rdb&lt;br /&gt;
dir /home/pacs/xyz00/users/discourse/redis/lib&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für Discourse 3.x gilt: &amp;quot;Discourse requires Redis 6.2.0 or up&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Für Debian Buster und Bullseye ist daher das Installieren eines neueren Binaries erforderlich. Bei Debian Bookwork ist bereits Redis 7.0 enthalten (siehe https://packages.debian.org/search?keywords=redis-server).&lt;br /&gt;
&lt;br /&gt;
Hier steht ein entsprechendes Binary für Debian Buster zur Verfügung, das mit dem Public Key von Timotheus geprüft werden kann:&lt;br /&gt;
&lt;br /&gt;
* https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
* Prüfsignatur: https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz.sig&lt;br /&gt;
&lt;br /&gt;
Prüfen der Signatur:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gpg --verify redis-server-6.2.12-debian-buster.tar.gz.sig redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Binary muss nach &amp;lt;code&amp;gt;$HOME/bin&amp;lt;/code&amp;gt; verschoben werden, und entsprechend beim Starten des Dienstes eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
== Installation von Ruby ==&lt;br /&gt;
&lt;br /&gt;
Als User &#039;&#039;xyz00-discourse&#039;&#039;:  Installation von Ruby mit &#039;&#039;rbenv&#039;&#039; mit folgenden Befehlen:&lt;br /&gt;
&lt;br /&gt;
Zunächst &#039;&#039;rbenv&#039;&#039; and &#039;&#039;ruby-build&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/rbenv.git ~/.rbenv&lt;br /&gt;
cd ~/.rbenv &amp;amp;&amp;amp; src/configure &amp;amp;&amp;amp; make -C src&lt;br /&gt;
echo &#039;export PATH=&amp;quot;$HOME/.rbenv/bin:$PATH&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
echo &#039;eval &amp;quot;$(rbenv init -)&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
starte neue Shell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
exec bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Überprüfe rbenv-Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
type rbenv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installiere ruby-build als rbenv-Plugin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun kann die benötigte Ruby-Version installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
rbenv install 2.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation von Discourse selber ==&lt;br /&gt;
&lt;br /&gt;
Weiterhin Als User &#039;&#039;xyz00-discourse&#039;&#039;:  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~&lt;br /&gt;
git clone https://github.com/discourse/discourse.git discourse&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die stabile Version auschecken:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git checkout stable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ruby Pakete installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gem install bundler&lt;br /&gt;
bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without development test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der Discourse Software ==&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/discourse/config/discourse.conf&#039;&#039; anhand der Beispiel-Datei:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
cp config/discourse_defaults.conf config/discourse.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anpassen folgender Inhalte:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
db_host = 127.0.0.1&lt;br /&gt;
db_port = 5432&lt;br /&gt;
#db_backup_port = 5432 #(auskommentieren)&lt;br /&gt;
db_name = xyz00_discoursedb&lt;br /&gt;
db_username = xyz00_discourseuser&lt;br /&gt;
db_password = &amp;quot;&amp;quot; #db password&lt;br /&gt;
hostname = &amp;quot;discourse.xyz00&amp;quot; # hostname&lt;br /&gt;
smtp_address = localhost&lt;br /&gt;
smtp_enable_start_tls = false&lt;br /&gt;
smtp_openssl_verify_mode = &#039;none&#039;&lt;br /&gt;
developer_emails = # your email-address&lt;br /&gt;
redis_host = 127.0.0.1&lt;br /&gt;
redis_port = 32002&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===TODO: Secrets setzen! ===&lt;br /&gt;
Die Zufallswerte für die Variablen SECRET_KEY_BASE und OTP_SECRET erzeugt man durch zwei Aufrufe des Kommandos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rake secret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq für Hintergrund-Aufgaben konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;config/sidekiq.conf&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wichtig: development auf production ändern.&lt;br /&gt;
&lt;br /&gt;
Mit diesem Dienst werden z.B. die E-Mails zur Aktivierung oder zum Passwort Reset verschickt.&lt;br /&gt;
&lt;br /&gt;
=== Problem mit Content Security Policy ===&lt;br /&gt;
&lt;br /&gt;
Um ein Problem mit Content Security Policy zu lösen, weil manche Dateien über http nachgeladen werden, muss in der Datei &amp;lt;code&amp;gt;config/site_settings.yml&amp;lt;/code&amp;gt; der Default Wert für force_https auf True gesetzt werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
force_https:&lt;br /&gt;
    default: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Problem beim Aufsetzen der Datenbank vermeiden ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;→ Notiz Mai 2024:&#039;&#039;&#039; dies scheint aktuell nicht aufzutreten. &lt;br /&gt;
&lt;br /&gt;
Aus irgendeinem Grund wird beim Initialisieren der Datenbank versucht, den TYPE hotlinked_media_status zweimal in der Datenbank anzulegen. Der Grund ist nicht ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Es kann folgende Änderung an der Datei &amp;lt;code&amp;gt;db/migrate/20220428094026_create_post_hotlinked_media.rb&amp;lt;/code&amp;gt; vorgenommen werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
reversible do |dir|&lt;br /&gt;
  dir.up { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DO $$ BEGIN CREATE TYPE hotlinked_media_status AS ENUM(&#039;downloaded&#039;, &#039;too_large&#039;, &#039;download_failed&#039;, &#039;upload_create_failed&#039;); EXCEPTION WHEN duplicate_object THEN null; END $$;&lt;br /&gt;
    SQL&lt;br /&gt;
  dir.down { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DROP TYPE hotlinked_media_status&lt;br /&gt;
    SQL&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Initialisieren der Datenbank ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
export SAFETY_ASSURED=1&lt;br /&gt;
# In Version 2.0.4 funktioniert db:migrate noch, ansonsten db:schema:load und seed nutzen!&lt;br /&gt;
# In Version 3.0.3 funktioniert db:migrate auch noch, db:schema:load ging nicht weil die Datei structure.sql fehlte&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:schema:load&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:seed&lt;br /&gt;
RAILS_ENV=production bundle exec rails db:migrate&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kompilieren der Assets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rails assets:precompile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration des Web-Servers (am Beispiel Puma)  ===&lt;br /&gt;
&lt;br /&gt;
Die Datei &#039;&#039;config/puma.conf&#039;&#039; anpassen (hier nur Änderungen angezeigt):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini&amp;gt;&lt;br /&gt;
APP_ROOT = &#039;/home/pacs/xyz00/users/discourse/discourse&#039;&lt;br /&gt;
daemonize false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starten der Dienste  ==&lt;br /&gt;
&lt;br /&gt;
Zum Start aller notwendigen Dienste sollte systemd benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Dateien müssen nach &amp;lt;code&amp;gt;.config/systemd/user/&amp;lt;/code&amp;gt; kopiert werden (überlange Zeilen werden hier im Wiki umgebrochen)&lt;br /&gt;
&lt;br /&gt;
redis.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Redis User Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/var/redis&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
ExecStart=%h/bin/redis-server %h/etc/redis.conf&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sidekiq.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Sidekiq Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;DB_POOL=8&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec sidekiq -C %h/discourse/config/sidekiq.yml&lt;br /&gt;
StandardOutput=append:%h/var/log/sidekiq.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
discourse.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Web Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;WEB_CONCURRENCY=2&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MAX_THREADS=5&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec puma -C config/puma.rb -e production -b tcp://127.0.0.1:13000&lt;br /&gt;
StandardOutput=append:%h/var/log/puma.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einrichten des Apache VHost ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/doms/beispiel.discuss&lt;br /&gt;
rm -rf htdocs-ssl subs/www subs-ssl/www&lt;br /&gt;
ln -s ~/live/public htdocs-ssl&lt;br /&gt;
touch htdocs-ssl/.htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann die &#039;&#039;htdocs-ssl/.htaccess&#039;&#039; (durch das gelinkte Verzeichnis entspricht das dem Pfad /home/pacs/xyz00/users/discourse/discourse/public/.htaccess ) mit dem Editor der Wahl öffnen und folgende Konfiguration einfügen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
  &lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RewriteRule .* http://127.0.0.1:13000%{REQUEST_URI} [proxy,last]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wartung ==&lt;br /&gt;
=== Backup ===&lt;br /&gt;
&lt;br /&gt;
Discourse macht selbstätig backups und legt diese unter &#039;public/backups&#039; ab. Enthalten ist ein Datenbank-Dump und die hochgeladenen Dateien.&lt;br /&gt;
&lt;br /&gt;
Im Admin-Bereich lassen sich backups auch manuell antreten.&lt;br /&gt;
&lt;br /&gt;
=== Admin Benutzer einladen ===&lt;br /&gt;
&lt;br /&gt;
Manchmal brauchen wir einen neuen Admin Benutzer, den wir von der Kommandozeile aus einladen möchten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd /discourse&lt;br /&gt;
RAILS_ENV=production rake admin:invite[admin@example.org]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Import aus mbox Archiven ===&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel ein Mailman2 Archiv zu importieren, wo die Nachrichten als .mbox Datei vorliegen, sind folgende Schritte nötig:&lt;br /&gt;
&lt;br /&gt;
Vorbereitungen an Discourse:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
bundle config set frozen false&lt;br /&gt;
IMPORT=1 bundle install&lt;br /&gt;
bundle config set frozen true&lt;br /&gt;
nano script/import_scripts/mbox/settings.yml&lt;br /&gt;
#  dort ändern:&lt;br /&gt;
#    data_dir: /home/pacs/xyz00/users/discourse/list-archiv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hochladen der Mailinglisten-Archive:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/list-archiv&lt;br /&gt;
# dort muss es Unterordner mit dem Namen der gewünschten Kategorie geben,&lt;br /&gt;
# und die mbox Datei muss auch diesen Namen haben, z.B.:&lt;br /&gt;
# ~/list-archiv/beispiel/beispiel.mbox&lt;br /&gt;
# ~/list-archiv/example/example.mbox&lt;br /&gt;
# um die Beiträge in den entsprechenden Kategorien beispiel und example einzufügen.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durchführen des Imports:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
RAILS_ENV=production IMPORT=1 bundle exec rails runner \&lt;br /&gt;
    script/import_scripts/mbox.rb script/import_scripts/mbox/settings.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Export ===&lt;br /&gt;
* Wenn ein Forum beendet wird, möchte man evtl. eine Sicherung als statische HTML Seiten. &lt;br /&gt;
** Das wird hier diskutiert: https://meta.discourse.org/t/how-do-i-export-the-complete-forum-as-static-html-pages/71007/3&lt;br /&gt;
* Um ein Forum von Discourse zu Flarum umzuziehen, hat Timotheus ein Skript geschrieben.&lt;br /&gt;
** Das Migrations-Skript: https://github.com/SolidCharity/discourse_to_flarum&lt;br /&gt;
** siehe auch https://discuss.flarum.org/d/4930-discourse-to-flarum-migration-support/29&lt;br /&gt;
&lt;br /&gt;
=== Updates ===&lt;br /&gt;
&lt;br /&gt;
Discourse wird über update via mail informieren (dies kann man m.W. abschalten).&lt;br /&gt;
&lt;br /&gt;
Achtung: bei größeren Updates auch immer Änderungen an der Datei site_settings.yml (https://github.com/discourse/discourse/blob/main/config/site_settings.yml) beachten!&lt;br /&gt;
&lt;br /&gt;
Siehe auch die unterstützten Releases: https://releases.discourse.org/ und die Tags: https://github.com/discourse/discourse/tags&lt;br /&gt;
&lt;br /&gt;
==== Am Beispiel von 2026.1.3 auf 2026.1.4 ====&lt;br /&gt;
&lt;br /&gt;
# Im Web-Backend unter Administration-&amp;gt;Backups-&amp;gt; Read-Only Mouds setzen (oder Web Server so konfigurieren, dass keine Zugriffe mehr stattfinden können)&lt;br /&gt;
# Backup&lt;br /&gt;
# Die lokalen Änderungen sichern:&lt;br /&gt;
# cd discourse&lt;br /&gt;
# mv ~/plugins.bak/discourse-ai plugins&lt;br /&gt;
# git diff v2026.1.3 &amp;gt; diff-2026.1.3.txt&lt;br /&gt;
# git fetch&lt;br /&gt;
# git checkout -b hostsharing-deployment-v2026.1.4 v2026.1.4&lt;br /&gt;
# evtl. Änderungen aus diff-2026.1.3.txt wieder übernehmen und committen&lt;br /&gt;
# patch -p1 &amp;lt; diff-2026.1.3.txt&lt;br /&gt;
# git commit -a -m &amp;quot;spezifische Änderungen für diese Instanz&amp;quot; --no-verify&lt;br /&gt;
# Schauen, ob discourse eine neue Ruby-Version nutzt (z.B. in https://github.com/discourse/discourse_docker/blob/main/image/base/Dockerfile bzw. https://github.com/discourse/discourse/blob/v2026.1.4/Gemfile)&lt;br /&gt;
# Ist dies der Fall, dann:&lt;br /&gt;
# rbenv install 3.3.8&lt;br /&gt;
# rbenv global 3.3.8&lt;br /&gt;
# rbenv rehash&lt;br /&gt;
# echo &amp;quot;3.3.8&amp;quot; &amp;gt; .ruby-version&lt;br /&gt;
# installiere Node 22: https://codeberg.org/tpokorra/hostsharing-scripts/src/branch/main/install-nodejs.sh&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# gem update --system&lt;br /&gt;
# bundle install&lt;br /&gt;
# npm install -g terser uglify-js pnpm@10&lt;br /&gt;
#&lt;br /&gt;
# to avoid this error: ERR_PNPM_INVALID_DEPENDENCY_NAME  The current package contains a dependency with an invalid name: &amp;quot;@types/@glimmer__component&amp;quot;&lt;br /&gt;
# vi frontend/discourse-types/package.json&lt;br /&gt;
&lt;br /&gt;
 -    &amp;quot;@types/@glimmer__component&amp;quot;: &amp;quot;npm:@glimmer/component@^2.0.0&amp;quot;,&lt;br /&gt;
 -    &amp;quot;@types/@glint__ember-tsc&amp;quot;: &amp;quot;npm:@glint/ember-tsc@^1.0.7&amp;quot;,&lt;br /&gt;
 -    &amp;quot;@types/@glint__template&amp;quot;: &amp;quot;npm:@glint/template@^1.7.2&amp;quot;&lt;br /&gt;
 +    &amp;quot;@types/glimmer__component&amp;quot;: &amp;quot;npm:@glimmer/component@^2.0.0&amp;quot;,&lt;br /&gt;
 +    &amp;quot;@types/glint__ember-tsc&amp;quot;: &amp;quot;npm:@glint/ember-tsc@^1.0.7&amp;quot;,&lt;br /&gt;
 +    &amp;quot;@types/glint__template&amp;quot;: &amp;quot;npm:@glint/template@^1.7.2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# corepack use pnpm@latest-10&lt;br /&gt;
# pnpm install&lt;br /&gt;
# export $(grep -v &#039;^#&#039; ~/discourse.env | xargs -d &#039;\n&#039;)&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# Falls die pg extension pg_vector nicht installiert ist: deaktiviere das Plugin während migrate, aber auch für später damit /admin/settings funktioniert (ansonsten in salt pillar pg_vector installieren, und als postgres user: create extension vector;)&lt;br /&gt;
## mkdir -p ~/plugins.bak&lt;br /&gt;
## mv plugins/discourse-ai ~/plugins.bak&lt;br /&gt;
# RAILS_ENV=production bundle exec rake db:migrate&lt;br /&gt;
# RAILS_ENV=production bundle exec rake assets:precompile&lt;br /&gt;
# Services neu starten&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user restart puma&lt;br /&gt;
systemctl --user restart sidekiq&lt;br /&gt;
systemctl --user restart redis&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zuletzt: Read-Only Modus wieder deaktivieren&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
&lt;br /&gt;
Es können folgende Einstellungen in der Datei config/environments/production.rb vorgenommen werden. Danach den Puma Dienst neustarten. Fehlermeldungen und Stacktraces werden dann im Browser ausgegeben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
config.log_level = :debug&lt;br /&gt;
config.action_dispatch.show_exceptions = :all&lt;br /&gt;
config.action_dispatch.debug_exception_log_level = :error&lt;br /&gt;
&lt;br /&gt;
# Full error reports are enabled and caching is turned off&lt;br /&gt;
config.consider_all_requests_local = true&lt;br /&gt;
config.action_controller.perform_caching = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erforderliche Anpassungen ===&lt;br /&gt;
Weil wir bei Debian Bookworm noch mit ImageMagick 6.9 arbeiten, muss dieser [https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119 Patch] rückgängig gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line&amp;gt;&lt;br /&gt;
wget https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119.patch -O ~/imagemagick.patch&lt;br /&gt;
patch -p1 --reverse &amp;lt; ~/imagemagick.patch&lt;br /&gt;
git commit -a -m &amp;quot;revert imagemagick patch&amp;quot;  --no-verify&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ToDos ==&lt;br /&gt;
&lt;br /&gt;
* Ein Patch, um Discourse auch via Unix-Socket mit Redis sprechen lassen zu können dürfte relativ einfach sein (es wird ein Wrapper um das redis-gem genutzt).&lt;br /&gt;
* Konfiguration von discourse, um mit postgresql via Unix-Socket zu kommunizieren (DISCOURSE_DB_SOCKET environment variable)&lt;br /&gt;
* Performance-tuning an diversen Stellen, anhand der discourse_docker-Vorgaben (https://github.com/discourse/discourse_docker), z.B.&lt;br /&gt;
** thpoff (huge page settings)&lt;br /&gt;
** unicorn (hat eine wesentlich ausgefeiltere Konfigurations-Vorlage, wahrscheinlich bereits ordentlich optimiert)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://help.skysilk.com/support/solutions/articles/9000120927-how-to-install-discourse-without-docker-using-skysilk-vps-&lt;br /&gt;
* https://github.com/discourse/discourse_docker&lt;br /&gt;
* https://github.com/discourse/discourse&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/discourse&lt;br /&gt;
&lt;br /&gt;
== Historie ==&lt;br /&gt;
&lt;br /&gt;
* 2018, 14 . September: Initiale Fassung&lt;br /&gt;
* 2019, Januar: Update-Informationen ergänzt&lt;br /&gt;
* 2022, Juni: systemd Dienste, Discourse 3.0&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:RubyOnRails]]&lt;br /&gt;
[[Kategorie:Webforen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
	<entry>
		<id>https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7589</id>
		<title>Discourse installieren</title>
		<link rel="alternate" type="text/html" href="https://wiki.hostsharing.net/index.php?title=Discourse_installieren&amp;diff=7589"/>
		<updated>2026-06-11T20:06:06Z</updated>

		<summary type="html">&lt;p&gt;Tim00: /* Am Beispiel von 2026.1.3 auf 2026.1.4 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Textkasten|gelb|Für Managed Server|Ein funktionierender Discourse-Server erfordert mehrere laufende Server-Dienste. Für den Betrieb ist ein Managed Server sinnvoll.}}&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|rot|Support von der Discourse-Community|Die Discourse-Entwickler haben sich entschieden, nur eine mehr oder weniger genormte Installationsmethode (via docker) zu unterstützen. Dies ist so auf der hostsharing-Architektur aufgrund mehrerer Bedenken und Überlegungen nicht möglich. Die Community ist durchaus hilfreich, geht aber davon aus, dass quasi alle Nutzer* eine &amp;quot;supported&amp;quot;e Installation durchgeführt haben. Wenn man in entsprechenden Kanälen nach Hilfe fragt, sollte man unbedingt erwähnen, dass man discourse selber anhand dieser hier lesbaren Anleitung installiert hat, um bereits entsprechenden Kommentaren und Nachfragen vorzugreifen.}}&lt;br /&gt;
&lt;br /&gt;
== Über ==&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel wird die Installation von discourse, Version 2.1.0 (September 2018) beschrieben.&lt;br /&gt;
&lt;br /&gt;
== Vorbereitungen ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von HSAdmin wird angelegt:&lt;br /&gt;
# Ein User als Service-User mit &#039;&#039;/bin/bash&#039;&#039; als Shell, zum Beispiel Beispiel: &#039;&#039;xyz00-discourse&#039;&#039;&lt;br /&gt;
# Eine Domain mit &#039;&#039;xyz00-discourse&#039; als Domain-Administrator, zum Beispiel &#039;&#039;beispiel.discussion&#039;&#039;&lt;br /&gt;
# Einen Postgresql-User &#039;&#039;xyz00_discourseuser&#039;&#039; mit Passwort &#039;&#039;meinPasswort&#039;&#039;&lt;br /&gt;
# Eine Postgresql-Datenbank &#039;&#039;xyz00_discoursedb&#039;&#039; mit Datenbank-Owner &#039;&#039;xyz00_discourseuser&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Verwendete IP-Ports der Server-Dienste:&lt;br /&gt;
# Redis: localhost:32002&lt;br /&gt;
# Discourse-Web: localhost:13000&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der PostgreSQL Datenbank ==&lt;br /&gt;
&lt;br /&gt;
Es müssen noch Erweiterungen für Postgresql installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public;&amp;quot;&lt;br /&gt;
psql --user xyz00_discourseuser  -c &amp;quot;CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA public;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration des Redis Server ==&lt;br /&gt;
&lt;br /&gt;
{{Textkasten|gelb|Firewall/Redis Port|Leider unterstützt discourse nicht die Kommunikation mit Redis über Unix-Sockets. Dementsprechend muss der für Redis konfigurierte Port von dem hostsharing-Support in der Firewall freigegeben werden.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd&lt;br /&gt;
mkdir redis/etc redis/lib redis/log redis/run&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/redis/etc/redis.conf&#039;&#039; mit folgendem Inhalt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
daemonize no&lt;br /&gt;
pidfile /home/pacs/xyz00/users/discourse/redis/run/redis-server.pid&lt;br /&gt;
port 32002&lt;br /&gt;
tcp-backlog 128&lt;br /&gt;
bind 127.0.0.1&lt;br /&gt;
timeout 300&lt;br /&gt;
loglevel notice&lt;br /&gt;
logfile /home/pacs/xyz00/users/discourse/redis/log/redis.log&lt;br /&gt;
databases 16&lt;br /&gt;
save 900 1&lt;br /&gt;
save 300 10&lt;br /&gt;
save 60 10000&lt;br /&gt;
slave-serve-stale-data yes&lt;br /&gt;
appendonly no&lt;br /&gt;
dbfilename dump.rdb&lt;br /&gt;
dir /home/pacs/xyz00/users/discourse/redis/lib&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für Discourse 3.x gilt: &amp;quot;Discourse requires Redis 6.2.0 or up&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Für Debian Buster und Bullseye ist daher das Installieren eines neueren Binaries erforderlich. Bei Debian Bookwork ist bereits Redis 7.0 enthalten (siehe https://packages.debian.org/search?keywords=redis-server).&lt;br /&gt;
&lt;br /&gt;
Hier steht ein entsprechendes Binary für Debian Buster zur Verfügung, das mit dem Public Key von Timotheus geprüft werden kann:&lt;br /&gt;
&lt;br /&gt;
* https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
* Prüfsignatur: https://download.solidcharity.com/tarballs/tpokorra/hostsharing/redis-server-6.2.12-debian-buster.tar.gz.sig&lt;br /&gt;
&lt;br /&gt;
Prüfen der Signatur:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gpg --verify redis-server-6.2.12-debian-buster.tar.gz.sig redis-server-6.2.12-debian-buster.tar.gz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Binary muss nach &amp;lt;code&amp;gt;$HOME/bin&amp;lt;/code&amp;gt; verschoben werden, und entsprechend beim Starten des Dienstes eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
== Installation von Ruby ==&lt;br /&gt;
&lt;br /&gt;
Als User &#039;&#039;xyz00-discourse&#039;&#039;:  Installation von Ruby mit &#039;&#039;rbenv&#039;&#039; mit folgenden Befehlen:&lt;br /&gt;
&lt;br /&gt;
Zunächst &#039;&#039;rbenv&#039;&#039; and &#039;&#039;ruby-build&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell line&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/rbenv.git ~/.rbenv&lt;br /&gt;
cd ~/.rbenv &amp;amp;&amp;amp; src/configure &amp;amp;&amp;amp; make -C src&lt;br /&gt;
echo &#039;export PATH=&amp;quot;$HOME/.rbenv/bin:$PATH&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
echo &#039;eval &amp;quot;$(rbenv init -)&amp;quot;&#039; &amp;gt;&amp;gt; ~/.profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
starte neue Shell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
exec bash&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Überprüfe rbenv-Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
type rbenv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installiere ruby-build als rbenv-Plugin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun kann die benötigte Ruby-Version installiert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
rbenv install 2.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation von Discourse selber ==&lt;br /&gt;
&lt;br /&gt;
Weiterhin Als User &#039;&#039;xyz00-discourse&#039;&#039;:  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~&lt;br /&gt;
git clone https://github.com/discourse/discourse.git discourse&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die stabile Version auschecken:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
git checkout stable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ruby Pakete installieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
gem install bundler&lt;br /&gt;
bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without development test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration der Discourse Software ==&lt;br /&gt;
&lt;br /&gt;
Anlegen einer Datei &#039;&#039;/home/pacs/xyz00/users/discourse/discourse/config/discourse.conf&#039;&#039; anhand der Beispiel-Datei:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/discourse&lt;br /&gt;
cp config/discourse_defaults.conf config/discourse.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anpassen folgender Inhalte:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
db_host = 127.0.0.1&lt;br /&gt;
db_port = 5432&lt;br /&gt;
#db_backup_port = 5432 #(auskommentieren)&lt;br /&gt;
db_name = xyz00_discoursedb&lt;br /&gt;
db_username = xyz00_discourseuser&lt;br /&gt;
db_password = &amp;quot;&amp;quot; #db password&lt;br /&gt;
hostname = &amp;quot;discourse.xyz00&amp;quot; # hostname&lt;br /&gt;
smtp_address = localhost&lt;br /&gt;
smtp_enable_start_tls = false&lt;br /&gt;
smtp_openssl_verify_mode = &#039;none&#039;&lt;br /&gt;
developer_emails = # your email-address&lt;br /&gt;
redis_host = 127.0.0.1&lt;br /&gt;
redis_port = 32002&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===TODO: Secrets setzen! ===&lt;br /&gt;
Die Zufallswerte für die Variablen SECRET_KEY_BASE und OTP_SECRET erzeugt man durch zwei Aufrufe des Kommandos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rake secret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sidekiq für Hintergrund-Aufgaben konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;config/sidekiq.conf&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wichtig: development auf production ändern.&lt;br /&gt;
&lt;br /&gt;
Mit diesem Dienst werden z.B. die E-Mails zur Aktivierung oder zum Passwort Reset verschickt.&lt;br /&gt;
&lt;br /&gt;
=== Problem mit Content Security Policy ===&lt;br /&gt;
&lt;br /&gt;
Um ein Problem mit Content Security Policy zu lösen, weil manche Dateien über http nachgeladen werden, muss in der Datei &amp;lt;code&amp;gt;config/site_settings.yml&amp;lt;/code&amp;gt; der Default Wert für force_https auf True gesetzt werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=yaml line&amp;gt;&lt;br /&gt;
force_https:&lt;br /&gt;
    default: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Problem beim Aufsetzen der Datenbank vermeiden ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;→ Notiz Mai 2024:&#039;&#039;&#039; dies scheint aktuell nicht aufzutreten. &lt;br /&gt;
&lt;br /&gt;
Aus irgendeinem Grund wird beim Initialisieren der Datenbank versucht, den TYPE hotlinked_media_status zweimal in der Datenbank anzulegen. Der Grund ist nicht ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Es kann folgende Änderung an der Datei &amp;lt;code&amp;gt;db/migrate/20220428094026_create_post_hotlinked_media.rb&amp;lt;/code&amp;gt; vorgenommen werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ruby line&amp;gt;&lt;br /&gt;
reversible do |dir|&lt;br /&gt;
  dir.up { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DO $$ BEGIN CREATE TYPE hotlinked_media_status AS ENUM(&#039;downloaded&#039;, &#039;too_large&#039;, &#039;download_failed&#039;, &#039;upload_create_failed&#039;); EXCEPTION WHEN duplicate_object THEN null; END $$;&lt;br /&gt;
    SQL&lt;br /&gt;
  dir.down { execute &amp;lt;&amp;lt;~SQL }&lt;br /&gt;
      DROP TYPE hotlinked_media_status&lt;br /&gt;
    SQL&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Initialisieren der Datenbank ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
export SAFETY_ASSURED=1&lt;br /&gt;
# In Version 2.0.4 funktioniert db:migrate noch, ansonsten db:schema:load und seed nutzen!&lt;br /&gt;
# In Version 3.0.3 funktioniert db:migrate auch noch, db:schema:load ging nicht weil die Datei structure.sql fehlte&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:schema:load&lt;br /&gt;
#RAILS_ENV=production bundle exec rails db:seed&lt;br /&gt;
RAILS_ENV=production bundle exec rails db:migrate&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kompilieren der Assets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
RAILS_ENV=production bundle exec rails assets:precompile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration des Web-Servers (am Beispiel Puma)  ===&lt;br /&gt;
&lt;br /&gt;
Die Datei &#039;&#039;config/puma.conf&#039;&#039; anpassen (hier nur Änderungen angezeigt):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini&amp;gt;&lt;br /&gt;
APP_ROOT = &#039;/home/pacs/xyz00/users/discourse/discourse&#039;&lt;br /&gt;
daemonize false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starten der Dienste  ==&lt;br /&gt;
&lt;br /&gt;
Zum Start aller notwendigen Dienste sollte systemd benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Dateien müssen nach &amp;lt;code&amp;gt;.config/systemd/user/&amp;lt;/code&amp;gt; kopiert werden (überlange Zeilen werden hier im Wiki umgebrochen)&lt;br /&gt;
&lt;br /&gt;
redis.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Redis User Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/var/redis&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
ExecStart=%h/bin/redis-server %h/etc/redis.conf&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sidekiq.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Sidekiq Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;DB_POOL=8&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec sidekiq -C %h/discourse/config/sidekiq.yml&lt;br /&gt;
StandardOutput=append:%h/var/log/sidekiq.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
discourse.service:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=ini line&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Discourse Web Service&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
WorkingDirectory=%h/discourse&lt;br /&gt;
Environment=&amp;quot;PATH=/usr/local/bin:/usr/bin:/bin&amp;quot;&lt;br /&gt;
Environment=&amp;quot;RAILS_ENV=production&amp;quot;&lt;br /&gt;
Environment=&amp;quot;WEB_CONCURRENCY=2&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MAX_THREADS=5&amp;quot;&lt;br /&gt;
Environment=&amp;quot;MALLOC_ARENA_MAX=2&amp;quot;&lt;br /&gt;
ExecStart=%h/.rbenv/shims/bundle exec puma -C config/puma.rb -e production -b tcp://127.0.0.1:13000&lt;br /&gt;
StandardOutput=append:%h/var/log/puma.out.log&lt;br /&gt;
StandardError=inherit&lt;br /&gt;
Restart=always&lt;br /&gt;
PrivateTmp=true&lt;br /&gt;
NoNewPrivileges=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=default.target&lt;br /&gt;
After=redis.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Einrichten des Apache VHost ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd ~/doms/beispiel.discuss&lt;br /&gt;
rm -rf htdocs-ssl subs/www subs-ssl/www&lt;br /&gt;
ln -s ~/live/public htdocs-ssl&lt;br /&gt;
touch htdocs-ssl/.htaccess&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann die &#039;&#039;htdocs-ssl/.htaccess&#039;&#039; (durch das gelinkte Verzeichnis entspricht das dem Pfad /home/pacs/xyz00/users/discourse/discourse/public/.htaccess ) mit dem Editor der Wahl öffnen und folgende Konfiguration einfügen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=apache line&amp;gt;&lt;br /&gt;
DirectoryIndex disabled&lt;br /&gt;
  &lt;br /&gt;
RequestHeader set X-Forwarded-Proto &amp;quot;https&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
RewriteEngine On&lt;br /&gt;
RewriteBase /&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-l&lt;br /&gt;
RewriteRule .* http://127.0.0.1:13000%{REQUEST_URI} [proxy,last]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Wartung ==&lt;br /&gt;
=== Backup ===&lt;br /&gt;
&lt;br /&gt;
Discourse macht selbstätig backups und legt diese unter &#039;public/backups&#039; ab. Enthalten ist ein Datenbank-Dump und die hochgeladenen Dateien.&lt;br /&gt;
&lt;br /&gt;
Im Admin-Bereich lassen sich backups auch manuell antreten.&lt;br /&gt;
&lt;br /&gt;
=== Admin Benutzer einladen ===&lt;br /&gt;
&lt;br /&gt;
Manchmal brauchen wir einen neuen Admin Benutzer, den wir von der Kommandozeile aus einladen möchten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
cd /discourse&lt;br /&gt;
RAILS_ENV=production rake admin:invite[admin@example.org]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Import aus mbox Archiven ===&lt;br /&gt;
&lt;br /&gt;
Um zum Beispiel ein Mailman2 Archiv zu importieren, wo die Nachrichten als .mbox Datei vorliegen, sind folgende Schritte nötig:&lt;br /&gt;
&lt;br /&gt;
Vorbereitungen an Discourse:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
bundle config set frozen false&lt;br /&gt;
IMPORT=1 bundle install&lt;br /&gt;
bundle config set frozen true&lt;br /&gt;
nano script/import_scripts/mbox/settings.yml&lt;br /&gt;
#  dort ändern:&lt;br /&gt;
#    data_dir: /home/pacs/xyz00/users/discourse/list-archiv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hochladen der Mailinglisten-Archive:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
mkdir ~/list-archiv&lt;br /&gt;
# dort muss es Unterordner mit dem Namen der gewünschten Kategorie geben,&lt;br /&gt;
# und die mbox Datei muss auch diesen Namen haben, z.B.:&lt;br /&gt;
# ~/list-archiv/beispiel/beispiel.mbox&lt;br /&gt;
# ~/list-archiv/example/example.mbox&lt;br /&gt;
# um die Beiträge in den entsprechenden Kategorien beispiel und example einzufügen.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durchführen des Imports:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
source .profile&lt;br /&gt;
cd discourse&lt;br /&gt;
RAILS_ENV=production IMPORT=1 bundle exec rails runner \&lt;br /&gt;
    script/import_scripts/mbox.rb script/import_scripts/mbox/settings.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Export ===&lt;br /&gt;
* Wenn ein Forum beendet wird, möchte man evtl. eine Sicherung als statische HTML Seiten. &lt;br /&gt;
** Das wird hier diskutiert: https://meta.discourse.org/t/how-do-i-export-the-complete-forum-as-static-html-pages/71007/3&lt;br /&gt;
* Um ein Forum von Discourse zu Flarum umzuziehen, hat Timotheus ein Skript geschrieben.&lt;br /&gt;
** Das Migrations-Skript: https://github.com/SolidCharity/discourse_to_flarum&lt;br /&gt;
** siehe auch https://discuss.flarum.org/d/4930-discourse-to-flarum-migration-support/29&lt;br /&gt;
&lt;br /&gt;
=== Updates ===&lt;br /&gt;
&lt;br /&gt;
Discourse wird über update via mail informieren (dies kann man m.W. abschalten).&lt;br /&gt;
&lt;br /&gt;
Achtung: bei größeren Updates auch immer Änderungen an der Datei site_settings.yml (https://github.com/discourse/discourse/blob/main/config/site_settings.yml) beachten!&lt;br /&gt;
&lt;br /&gt;
Siehe auch die unterstützten Releases: https://releases.discourse.org/ und die Tags: https://github.com/discourse/discourse/tags&lt;br /&gt;
&lt;br /&gt;
==== Am Beispiel von 2026.1.3 auf 2026.1.4 ====&lt;br /&gt;
&lt;br /&gt;
# Im Web-Backend unter Administration-&amp;gt;Backups-&amp;gt; Read-Only Mouds setzen (oder Web Server so konfigurieren, dass keine Zugriffe mehr stattfinden können)&lt;br /&gt;
# Backup&lt;br /&gt;
# Die lokalen Änderungen sichern:&lt;br /&gt;
# cd discourse&lt;br /&gt;
# mv ~/plugins.bak/discourse-ai plugins&lt;br /&gt;
# git diff v2026.1.3 &amp;gt; diff-2026.1.3.txt&lt;br /&gt;
# git fetch&lt;br /&gt;
# git checkout -b hostsharing-deployment-v2026.1.4 v2026.1.4&lt;br /&gt;
# evtl. Änderungen aus diff-2026.1.3.txt wieder übernehmen und committen&lt;br /&gt;
# patch -p1 &amp;lt; diff-2026.1.3.txt&lt;br /&gt;
# git commit -a -m &amp;quot;spezifische Änderungen für diese Instanz&amp;quot; --no-verify&lt;br /&gt;
# Schauen, ob discourse eine neue Ruby-Version nutzt (z.B. in https://github.com/discourse/discourse_docker/blob/main/image/base/Dockerfile bzw. https://github.com/discourse/discourse/blob/v2026.1.4/Gemfile)&lt;br /&gt;
# Ist dies der Fall, dann:&lt;br /&gt;
# rbenv install 3.3.8&lt;br /&gt;
# rbenv global 3.3.8&lt;br /&gt;
# rbenv rehash&lt;br /&gt;
# echo &amp;quot;3.3.8&amp;quot; &amp;gt; .ruby-version&lt;br /&gt;
# installiere Node 22: https://codeberg.org/tpokorra/hostsharing-scripts/src/branch/main/install-nodejs.sh&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# gem update --system&lt;br /&gt;
# bundle install&lt;br /&gt;
# npm install -g terser uglify-js pnpm@10&lt;br /&gt;
# corepack use pnpm@latest-10&lt;br /&gt;
# pnpm install&lt;br /&gt;
# export $(grep -v &#039;^#&#039; ~/discourse.env | xargs -d &#039;\n&#039;)&lt;br /&gt;
# source ~/.profile&lt;br /&gt;
# Falls die pg extension pg_vector nicht installiert ist: deaktiviere das Plugin während migrate, aber auch für später damit /admin/settings funktioniert (ansonsten in salt pillar pg_vector installieren, und als postgres user: create extension vector;)&lt;br /&gt;
## mkdir -p ~/plugins.bak&lt;br /&gt;
## mv plugins/discourse-ai ~/plugins.bak&lt;br /&gt;
# RAILS_ENV=production bundle exec rake db:migrate&lt;br /&gt;
# RAILS_ENV=production bundle exec rake assets:precompile&lt;br /&gt;
# Services neu starten&lt;br /&gt;
&amp;lt;syntaxhighlight lang=shell&amp;gt;&lt;br /&gt;
systemctl --user restart puma&lt;br /&gt;
systemctl --user restart sidekiq&lt;br /&gt;
systemctl --user restart redis&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Zuletzt: Read-Only Modus wieder deaktivieren&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
&lt;br /&gt;
Es können folgende Einstellungen in der Datei config/environments/production.rb vorgenommen werden. Danach den Puma Dienst neustarten. Fehlermeldungen und Stacktraces werden dann im Browser ausgegeben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; line&amp;gt;&lt;br /&gt;
config.log_level = :debug&lt;br /&gt;
config.action_dispatch.show_exceptions = :all&lt;br /&gt;
config.action_dispatch.debug_exception_log_level = :error&lt;br /&gt;
&lt;br /&gt;
# Full error reports are enabled and caching is turned off&lt;br /&gt;
config.consider_all_requests_local = true&lt;br /&gt;
config.action_controller.perform_caching = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erforderliche Anpassungen ===&lt;br /&gt;
Weil wir bei Debian Bookworm noch mit ImageMagick 6.9 arbeiten, muss dieser [https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119 Patch] rückgängig gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line&amp;gt;&lt;br /&gt;
wget https://github.com/discourse/discourse/commit/17aa831337e352dfd875f1b4ddc4492bd0835119.patch -O ~/imagemagick.patch&lt;br /&gt;
patch -p1 --reverse &amp;lt; ~/imagemagick.patch&lt;br /&gt;
git commit -a -m &amp;quot;revert imagemagick patch&amp;quot;  --no-verify&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ToDos ==&lt;br /&gt;
&lt;br /&gt;
* Ein Patch, um Discourse auch via Unix-Socket mit Redis sprechen lassen zu können dürfte relativ einfach sein (es wird ein Wrapper um das redis-gem genutzt).&lt;br /&gt;
* Konfiguration von discourse, um mit postgresql via Unix-Socket zu kommunizieren (DISCOURSE_DB_SOCKET environment variable)&lt;br /&gt;
* Performance-tuning an diversen Stellen, anhand der discourse_docker-Vorgaben (https://github.com/discourse/discourse_docker), z.B.&lt;br /&gt;
** thpoff (huge page settings)&lt;br /&gt;
** unicorn (hat eine wesentlich ausgefeiltere Konfigurations-Vorlage, wahrscheinlich bereits ordentlich optimiert)&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* https://help.skysilk.com/support/solutions/articles/9000120927-how-to-install-discourse-without-docker-using-skysilk-vps-&lt;br /&gt;
* https://github.com/discourse/discourse_docker&lt;br /&gt;
* https://github.com/discourse/discourse&lt;br /&gt;
* https://codeberg.org/tpokorra/hs.ansible/src/branch/main/playbooks/discourse&lt;br /&gt;
&lt;br /&gt;
== Historie ==&lt;br /&gt;
&lt;br /&gt;
* 2018, 14 . September: Initiale Fassung&lt;br /&gt;
* 2019, Januar: Update-Informationen ergänzt&lt;br /&gt;
* 2022, Juni: systemd Dienste, Discourse 3.0&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Kategorie:HSDoku]]&lt;br /&gt;
[[Kategorie:Installationsanleitungen]]&lt;br /&gt;
[[Kategorie:RubyOnRails]]&lt;br /&gt;
[[Kategorie:Webforen]]&lt;br /&gt;
[[Kategorie:Ansible Playbook]]&lt;/div&gt;</summary>
		<author><name>Tim00</name></author>
	</entry>
</feed>