Thomas Kramer

IT-COW | All posts tagged 'Reverse-Proxy'

Aufsetzen eines Nextcloud-Servers mit SWAG als SSL-Reverse-Proxy

By Administrator at November 03, 2021 22:09
Filed Under:

Nextcloud eignet sich um einen eigenen, privaten Cloud-Server aufzusetzen. Man kann so etwas fertig mieten, aber ich habe meinen eigenen Server neu aufgesetzt. Als Virtualisierungsplattform benutze ich mittlerweile Proxmox mit einem NUC, auf dem ich einige Server-Anwendungen in Dockern laufen lasse.

 

Als erstes braucht man für seinen Server einen Eintrag in einem öffentlichen DNS-Server, wenn man ihn nicht über eine häufig wechselnde, öffentliche IP-Adresse ansprechen will. Wer eine Fritzbox benutzt kann es mit MyFritz versuchen, dem hauseigenen DNS-Dienst von AVM.

 

In meinem Fall habe ich es nun mit DuckDNS umgesetzt, einem kostenlosen DNS-Dienst. Die Benutzung von DuckDNS könne viel einfacher nicht sein. Zunächst muss man sich über einen externen Account einloggen, dazu gibt es mehrere Möglichkeiten wie GitHub, Reddit oder Twitter. Wer ein Android-Handy benutzt, kann sich auch mit seinem GMail-Account von Google einloggen.

 

Sobald man eingeloggt ist bekommt man ein sogenanntes Token zugeordnet, eine längere Buchstaben-/Zahlenkombination. Danach braucht man nur noch die gewünschten Domains zu reservieren, natürlich alle mit der Endung .duckdns.org:

image

Dabei sieht man dann auch, welche IP-Adresse man von seinem Internetprovider aktuell zugewiesen bekommen hat. Die registrierten Domänen zeigen alle auf diese IP-Adresse. Als Privatanwender muss man dabei berücksichtigen dass die eigene öffentliche IP-Adresse nicht fix ist, sondern häufiger wechselt.

 

Da der Dienst kostenlos ist und man ihn sich mit Millionen anderer Anwender teilen muss, ist die Wahrscheinlichkeit hoch dass man seinen gewünschten Domänennamen nicht bekommt und man eine unsinnige Buchstaben-/Zahlenkombination anhängen muss. Wer das nicht wünscht kann sich natürlich woanders auch eine eigene Domäne mieten, muss dann aber Geld bezahlen.

 

Wie erwähnt arbeitete ich mit Docker-Containern unter Linux. Mit dem Kommandozeilen-Befehl

docker ps

lässt sich grundsätzlich eine Übersicht aller laufenden Docker anzeigen, mit der Information welche Ports sie jeweils belegen, aus Host- und aus Docker-Sicht.

 

Nachfolgend beschreibe ich die Einrichtung der einzelnen Docker-Container für die Verwendung von Nextcloud. Alle Container sollen untereinander über den Namen kommunizieren können, anstatt nur über die IP-Adressen. Daher legt man zunächst ein sogenanntes “User defined Bridge Network” an:

docker network create lsio

 

Als ersten Container legt man den Reverse-Proxy SWAG für die SSL-Verschlüsselung an. SWAG holt automatisiert über Cronjobs die SSL-Zertifikate von der freien Zertifizierungsstelle Let’s Encrypt und benötigt dazu das Token von dem DuckDNS-Account. Am Rande will ich erwähnen dass SWAG nicht auf DuckDNS festgelegt ist.

 

Bei allen unten folgenden Einträgen sollte man die von den Containern genutzten UserIDs/GroupIDs anpassen, so dass ein bereits vorhandener User des Hosts genutzt wird.

 

docker create \
  --name=swag \
  --cap-add=NET_ADMIN \
  --net=lsio \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Europe/Berlin \
  -e URL=$DOMAIN.duckdns.org \
  -e SUBDOMAINS=wildcard \
  -e VALIDATION=duckdns \
  -e DUCKDNSTOKEN=$TOKEN \
  -p 443:443 \
  -v $HOST_MAP_PATH:/config \
  --restart unless-stopped \
  ghcr.io/linuxserver/swag

 

Der Slash \ bedeutet dass der Befehl noch weiter über die nächste Zeile geht. Für $DOMAIN, $TOKEN und $HOST_MAP_PATH müsst Ihr natürlich eure eigenen Werte eintragen. Danach kommt die Einrichtung von MariaDB und Nextcloud dran. Grundsätzlich kann man auch alle drei Container über eine YAML-Datei auf einmal anlegen lassen, siehe die Dokumentation von SWAG. Die Parameter müsst Ihr trotzdem anpassen.

 

Der Container muss natürlich auch gestartet werden:

docker start swag

 

Grundsätzlich kann man mit dem Befehl

docker exec -it $Containername bash

eine Kommandozeile in die interne Sicht der Container öffnen. Manchmal muss man in den Containern noch Einstellungsdateien editieren, und nicht immer ist ein Texteditor vorinstalliert. Daher empfiehlt sich mit

apt-get update
apt-get install nano

die Paketquellen upzudaten und den Nano-Texteditor zu installieren.

 

Danach macht Ihr eine Bash in die interne Sicht des SWAG-Containers auf:

docker exec -it swag bash

Wechselt in den Pfad

cd /config/nginx/proxy-confs

und benennt die vorgefertigte Sample-Datei für Nextcloud um:

mv nextcloud.subdomain.conf.sample nextcloud.subdomain.conf

 

Dann bearbeitet Ihr die Datei mit

nano nextcloud.subdomain.conf

und ändert diese zwei Parameter, die zuvor auf 443 und https standen:
set $upstream_port 80;
set $upstream_proto http;

 

Auf der SWAG-Seite gibt es eine eigene Installationsanleitung für die Benutzung von SWAG mit Nextcloud, aber die Anleitung scheint unvollständig zu sein. Die Einrichtung des Nextcloud-Containers für SSL-Datenverkehr fehlt, denn ich erhielt “Connection refused”-Fehlermeldungen vom nginx-Webserver von SWAG in /config/log/nginx, wenn er versucht SSL-Verbindungen zu Nextcloud aufzubauen. Per Default ist ein Nextcloud-Container auch nicht fertig für SSL-Datenverkehr eingerichtet, denn dazu benötigt man natürlich ein eigenes SSL-Zertifikat.

 

Daher habe ich den Upstream-Port für die Weiterleitung des Datenverkehrs von SWAG zu Nextcloud in dieser Datei auf 80 geändert und das Upstream-Protokoll auf HTTP. Das sieht dann so aus, dass die Kommunikation nach draußen nur über den SSL-Port 443 erfolgt, aber zwischen den Containern unverschlüsselt über den HTTP-Port 80. Aus meiner Sicht ist das sicherheitstechnisch unbedenklich, denn es reicht aus die externe Kommunikation nach draußen zu verschlüsseln.

 

Bei den meisten beigefügten Sample-Dateien innerhalb des SWAG-Containers wird auch auf unverschlüsselte HTTP-Kommunikation zwischen den Containern gesetzt, aber bei der Beispieldatei für die Nextcloud-Weiterleitung war per Default eben HTTPS angegeben. Es scheint daher durchaus üblich zu sein nur die Kommunikation nach draußen zu verschlüsseln, u. a. dafür benutzt man ja auch den SWAG-Container damit man sich nicht um die SSL-Konfiguration der anderen Container kümmern muss.

 

Natürlich müsst Ihr den SSL-Port 443 auch in eurem Router freigeben, den unverschlüsselten Port 80 gebt Ihr nicht frei. Der SWAG-Container kümmert sich dann automatisch um die Aktualisierung der Let’s Encrypt-Zertifikate, denn diese Zertifikate sind nur drei Monate gültig. Mit exit könnt ihr die Bash aus dem Container wieder verlassen.

 

Die Einrichtung des MariaDB-Containers kann so erfolgen:

docker run --name mariadb \
--net=lsio \
-p 3306:3306 \
-v $HOST_MAP_PATH1:/etc/mysql/conf.d \
-v $HOST_MAP_PATH2:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=$Password \

--restart unless-stopped \
-d mariadb:latest

 

Bei den Variablen müsst Ihr natürlich wieder eigene Werte einsetzen. Wer will kann auch die Ports anders mappen, das Mapping geschieht über HOST_PORT:CONTAINER_PORT.  Danach sollte man in die Logs der einzelnen Container mit

docker logs $Containername

grundsätzlich einmal reinschauen und kontrollieren, ob sie ohne Fehlermeldung hochfahren.

 

Dann habe ich mich in den MariaDB-Container eingeloggt und eine Nextcloud-Datenbank angelegt:

docker exec -it mariadb bash

mysql -u root –p
show databases;
create database nextcloud;
create user nextcloud;

 

Wenn der Nextcloud-Einrichtungsdialog später bei euch auch anzeigt dass er sich nicht über eine bestimmte interne IP-Adresse in die Datenbank einloggen kann, benötigt Ihr auch diesen Befehl:
GRANT ALL ON nextcloud.* to 'nextcloud'@'localhost' IDENTIFIED BY '$PASSWORD' WITH GRANT OPTION;

Mit ifconfig könnt Ihr euch die vom System verwendeten IP-Adressen auch anzeigen lassen.

 

Außerdem zeigte mir Nextcloud beim Login auch die Fehlermeldung

“InnoDB refuses to write tables with ROW_FORMAT=COMPRESSED or KEY_BLOCK_SIZE”

an und ich musste mit

nano /etc/mysql/my.cnf

die Einstellungsdatei bearbeiten und den Befehl

innodb_read_only_compressed=OFF

hinzufügen.

 

Nachfolgend die Einrichtung des Nextcloud-Containers:

docker run -d \
--name=nextcloud \
--net=lsio \
-e PUID=1000 \
-e PGID=1000 \
-p 443:443  \
-p 80:80  \
-v $HOST_MAP_PATH:/var/www/html \

--restart unless-stopped \
nextcloud

 

Macht dann eine Bash in den Nextcloud-Container auf:

docker exec -it nextcloud bash

Anschließend wieder die Paketquellen aktualisieren und nano als Texteditor installieren:
apt-get update
apt-get install nano


Dann bearbeitet die Einstellungsdatei von Nextcloud mit
nano /var/www/html/config/config.php

und fügt bei Trusted Domains eine Zeile hinzu:

'trusted_domains' =>
array (
  0 => '$IP-ADRESS:80',
  1 => 'nextcloud.$DOMAIN.duckdns.org',
),

 

Der 0.-Eintrag sollte schon vorhanden sein, fügt den 1.-Eintrag mit dem von DuckDNS vergebenen DNS-Eintrag hinzu.

Weitere Parameter die Ihr in dieser Datei hinzufügen müsst:

'overwrite.cli.url' => 'https://nextcloud.$DOMAIN.duckdns.org',
'overwritehost' => 'nextcloud.$DOMAIN.duckdns.org',
'overwriteprotocol' => 'https',
'trusted_proxies' => ['swag'], 

 

Wenn Ihr von Nextcloud später nicht die Warnung

“Der “Strict-Transport-Security” HTTP-Header ist nicht auf mindestens “15552000” Sekunden eingestellt”

bekommen wollt, müsst Ihr auch die Datei

nano /config/nginx/ssl.conf

bearbeiten und die Zeile

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

hinzufügen. Das hat dann den Effekt, dass nur noch verschlüsselte HTTPS-Verbindungen akzeptiert werden.

 

In Nextcloud kann auch die Warnung

“Dem Modul php-imagick fehlt die SVG-Unterstützung. Für eine bessere Kompatibilität wird empfohlen, es zu installieren.”

kommen, dann ist (optional) in dem Nextcloud-Container dieses Modul zu installieren:

apt-get install libmagickcore-6.q16-6-extra

Dann den Container mit exit verlassen.

 

Bei der Nextcloud-App auf meinem Android-Handy gab es außerdem einen Hänger beim Klick auf den “Zugriff gewähren”-Button. Das kann man über den Befehl

docker exec -it -u www-data nextcloud bash -c './occ config:system:set overwriteprotocol --value="https"'

beheben. Das müsste derselbe Parameter wie bei der Bearbeitung der config.php weiter oben angegeben sein.

 

Falls Ihr die Nextcloud-Webseite noch nicht aufgerufen habt, solltet Ihr das jetzt versuchen. Beim ersten Aufruf ist Nextcloud noch nicht vollständig installiert und Ihr könnt die bevorzugte Datenbank auswählen. Da Ihr MariaDB installiert habt wählt Ihr das dort aus. Falls Ihr die Datenbank-Ports anders gemappt habt solltet Ihr das berücksichtigen, die Datenbank ist natürlich mit $ADRESSE:$PORT anzugeben.

 

Beim ersten Login wird Nextcloud die Einrichtung erst noch abschließen. Wenn alles funktioniert hat könnt Ihr das SSL-Zertifkat von Let’s Encrypt über das Schloss-Symbol in eurem Firefox aufrufen. Schaut dann in Nextcloud in den Einstellungen bei der Übersicht rein, denn dort prüft Nextcloud die Installation und zeigt Warnungen bei Installationsproblemen an.

 

Die IP-Adresse die Ihr von eurem Internetprovider zugeordnet bekommen habt wird sich regelmäßig ändern, es ist daher notwendig den DuckDNS-Dienst über die IP-Änderung zu informieren. Dazu setzt man zuletzt einen eigenen Docker für DuckDNS auf:

 

docker run -d \
  --name=duckdns \
  -e PUID=1000  \
  -e PGID=1000  \
  -e TZ=Europe/Berlin \
  -e SUBDOMAINS=$DOMAIN \
  -e TOKEN=$TOKEN \
  -e LOG_FILE=true  \
  -v $HOST_MAP_PATH:/config \
  --restart unless-stopped \
  lscr.io/linuxserver/duckdns

 

Am Rande möchte ich noch erwähnen dass sich die Nextcloud-App auf eurem Handy durch die Google Play Services automatisch aktualisieren wird. Entsprechend ist serverseitig auch eine automatische Aktualisierung eurer Docker-Container zu empfehlen, wie das einzurichten geht habe ich im vorherigen Eintrag beschrieben.

 

Übrigens gibt es in SWAG viele weitere vorgefertigte Sample-Dateien für diverse Dienste, wie Adguard, Emby, Duplicati und Dokuwiki.


Nextcloud kann man neben MariaDB auch mit PostgreSQL betreiben. Auf dieser Seite wird beschrieben wie man die MariaDB-Datenbank von Nextcloud nach PostgreSQL migrieren kann.

 

Die Anleitung von bitblokes sieht auch gut aus, falls jemand Nextcloud mit Reverse Proxy nativ ohne Docker einspielen möchte.

 

Ergänzung 19.11.2021: Die Hintergrundjobs in Nextcloud werden standardmäßig über die Seitenaufrufe getriggert, aber es gibt auch die bessere Möglichkeit sie über Cronjobs triggern zu lassen. Dann werden die Seitenaufrufe nicht deswegen ausgebremst.

 

Dazu geht man in Nextcloud auf die Grundeinstellungen-Seite und wählt bei Hintergrund-Aufgaben Cron aus. Der Nextcloud Container enthält für den User www-data zwar eine Cron-Datei in /var/spool/cron/crontabs, aber es gibt keinen Cron-Prozess der sie regelmäßig aufrufen würde.

 

Man kann aber über die Cronjobs des Hosts Skripte in den Docker-Containern automatisch aufrufen lassen. Dazu loggt man sich als root auf dem Host ein und gibt crontab –e ein, und fügt in der Crontab dann die folgende Zeile hinzu:

 

*/5 * * * * docker exec --user www-data nextcloud php -f /var/www/html/cron.php

 

Dadurch werden die Hintergrundjobs von Nextcloud alle fünf Minuten durchgeführt. Um zu sehen ob es funktioniert, schaut auf der Einstellungen-Seite nach ein paar Minuten vorbei:

 

image

 

Falls es nicht funktioniert, wird hier dann ein Fehler angezeigt.

 

Ergänzung 21.11.2021: Auch Collaboara Online zu installieren, ist nicht so schwer. Dabei handelt es sich quasi um LibreOffice im Webbrowser. Man kann damit über den Webbrowser Text-/ oder Tabellendokumente bearbeiten.

 

Für die Installation führt man diesen Befehl aus:

 

docker run --name=collabora -t -d -p $IP-Adresse:9980:9980 -e "domain=nextcloud\\.$Domain\\.duckdns\\.org" -e "username=admin" -e "password=$Password" --net=lsio --restart always collabora/code

 

Dann loggt man sich in den SWAG-Container ein:

docker exec –it swag bash

 

Dann geht man in das Verzeichnis mit den Konfigurationsdateien:

cd /config/nginx/proxy-confs

und benennt die bereits vorhandene Beispieldatei um:

mv collabora.subdomain.conf.sample collabora.subdomain.conf

 

Dann geht Ihr mit exit aus dem Container raus und lasst mit

docker restart swag

SWAG neu starten.

 

Anschließend geht Ihr bei Nextcloud in die Einstellungenseite für Collabora und tragt eure Domain ein:

 

image

 

Danach könnt Ihr Textdokumente im Webbrowser über Nextcloud bearbeiten. Die Adminkonsole von Collabora Online erreicht man über

https://$IP-Adressse:9980/loleaflet/dist/admin/admin.html#

 

Ergänzung 26.11.2021: Hatte beim Nextcloud-Container vergessen die Zeitzone mit dem TZ-Parameter zu übergeben, daher wurde mir eine falsche Uhrzeit in Nextcloud angezeigt.

 

Man kann es aber auch nachträglich im Container ändern, zuerst in den Container einloggen:

docker exec –it nextcloud bash

 

Dann den symbolischen Link löschen:

rm –rf /etc/localtime

 

Dann einen neuen Link anlegen:

ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime

Danach kann man den Container mit exit wieder verlassen.

 

Wenn der Container über Watchtower aktualisiert wurde ist diese Einstellung aber wieder weg, daher besser über einen Cronjob des Hosts aktualisieren lassen, siehe Ergänzung vom 01.12. weiter unten. Oder den Container mit angepassten Einstellungen neu erstellen, da die Datenverzeichnisse auf den Host gemappt wurden sollten dabei eigentlich auch keine Einstellungen verloren gehen.

 

Ergänzung 28.11.2021: In der SWAG-Anleitung gibt es auch einen Abschnitt: “Using certs in other containers”, falls man auch die Kommunikation der Container untereinander verschlüsseln möchte.

 

Alternativ kann man auch die Reverse Proxys “Traefik” oder “Nginx Proxy Manager” benutzen, von denen es auch einen Docker-Container gibt. Diese beiden haben auch ein schönes Dashboard, das fehlt SWAG leider.

 

Ergänzung 01.12.2021: Bei Goneuland gibt es auch eine Anleitung für Nextcloud unter Docker mit Traefik, falls das jemanden interessiert.

 

Das automatische Updaten gezielter Container über einen Watchtower-Aufruf in der Crontab schien nicht korrekt zu funktionieren, daher habe ich Watchtower nun über Docker-Compose eingebunden. Dazu erstellt man in einem neuen Verzeichnis eine Datei docker-compose.yml und fügt folgende Inhalte hinzu:

 

version: "3"

services:
  watchtower:
    image: containrrr/watchtower
    container_name: watchtower   
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    command: watchtower $WeitererContainer1 $WeitererContainer2 --schedule '0 0 5 * * *'  --cleanup --debug     
    environment:  
      TZ: "Europe/Berlin"
    restart: always

 

Dann lässt man Watchtower mit “docker-compose up –d” erstellen. Nur die explizit erwähnten Container werden dann noch automatisch aktualisiert, jeden morgen um 5 Uhr.

 

Die Versionsinformationen des installierten Nextcloud-Containers kann man dann mit folgendem Befehl überprüfen: “docker inspect nextcloud”. Weit unten in der Ausgabe findet man dann die Zeile

 

image 

 

Vergleichen kann man mit der DockerHub-Seite, der Container ist (noch) aktuell. Die Nextcloud-Instanz war anschließend aber im Wartungsmodus, und mir war nicht unmittelbar klar warum:

 

nextcloud_wartungsmodus

 

Ich habe mich dann mit dem Befehl

docker exec -it -u www-data nextcloud bash

in die Nextcloud-Instanz als User www-data eingeloggt und den Maintenance-Modus deaktiviert:

php occ maintenance:mode –off

 

Daraufhin bekam ich im Webbrower folgendes zu sehen:

 

nextcloud_update

 

Dann war mir auch klar warum: Watchtower kann zwar den Anwendungscontainer automatisch updaten, aber zu der Anwendung gehört auch eine MariaDB-Datenbank und das Schema da drin kann nicht automatisch auf die neueste Programmversion aktualisiert werden, jedenfalls nicht von Watchtower.

 

Über den Browserbutton kann man auch updaten, aber ich habe mich erneut in den Nextcloud-Container als user www-data eingeloggt und das Update dort versucht über “./occ upgrade” zu triggern. Das ging aber noch nicht, denn der oben erwähnte Fehler trat dabei wieder auf:

 

“InnoDB refuses to write tables with ROW_FORMAT=COMPRESSED or KEY_BLOCK_SIZE”

 

Wie man den Fehler im MariaDB-Container behebt, habe ich weiter oben beschrieben. Durch das Update des MariaDB-Containers trat der Fehler erneut auf. In der docker-compose.yml von Watchtower sollte man daher den MariaDB-Container von den automatischen Updates ausschließen, dann sollte man die Datenbank aber auch nicht direkt übers Internet freigeben.

 

Danach habe ich mich wieder in den Nextcloud-Container als User www-data eingeloggt und das Update getriggert:

./occ upgrade

 

Danach war Nextcloud erneut im Wartungsmodus, den habe ich deaktiviert:

php occ maintenance:mode –off

Und danach ging Nextcloud dann wieder.

 

Wer die Nextcloud-Datenbankupdates nicht manuell triggern will, kann diese über einen Cronjob auf dem Host automatisch triggern:

 

0 6 * * * docker exec --user www-data nextcloud /var/www/html/occ upgrade ; docker exec --user www-data nextcloud /var/www/html/occ db:add-missing-indices ; docker exec --user www-data nextcloud /var/www/html/occ db:add-missing-columns ; docker exec --user www-data nextcloud /var/www/html/occ db:convert-filecache-bigint

15 6 * * * docker exec --user www-data nextcloud /var/www/html/occ app:update --all

30 6 * * * docker exec nextcloud apt-get update ; docker exec nextcloud apt-get install libmagickcore-6.q16-6-extra –yes ; docker exec nextcloud apt-get install nano --yes

0 7 * * * docker exec nextcloud rm -rf /etc/localtime && docker exec nextcloud ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime

 

Etwaige Fehlermeldungen gehen dann natürlich auch unter, aber ein Backup sollte man ja eh immer machen.

 

Ergänzung 04.12.2021: Laut der Duck DNS-Anleitung reicht ein simpler HTTPS-Get aus, um die IP bei Duck DNS zu aktualisieren. Bei BITblokes haben sie dafür einen curl-Aufruf verwendet. Einen eigenen Docker dafür laufen zu lassen könnte man daher wohl als Overkill ansehen, sieht aber nicht danach aus als ob der viele Ressourcen benötigt.

 

Ergänzung 06.12.2021: Standardmäßig wird man in Nextcloud bei einer längeren Untätigkeit nicht ausgeloggt, was ich unsicher und auch ungewohnt empfand. Eine Einstellung innerhalb der Weboberfläche hatte ich nicht gefunden; um das zu ändern kann man aber in der ./config/config.php-Datei innerhalb des Containers die drei Zeilen:

 

'session_lifetime' => 3600,
'session_keepalive' => false,
'auto_logout' => true,

 

hinzufügen. Die Einheit bei session_lifetime ist Sekunden, 3600 ist demnach der Wert für eine Stunde Untätigkeit, ab der man automatisch ausgeloggt wird. Das Verzeichnis /var/www/html (mit Unterverzeichnissen) wird mit den oben aufgeführten Docker-Einstellungen auf den Host gemappt, so dass diese Einstellung dauerhaft ist.

 

By the Way, Swag mag im Vergleich zu den anderen Reverse Proxys Traefik und Nginx Proxy Manager keine grafische Weboberfläche haben, aber immerhin hat es Fail2ban integriert, was man bei den anderen nachrüsten muss. Eventuell teste ich die Alternativen irgendwann aber auch noch.

 

Update 14.12.2021: Ich habe mein Setup nochmal überarbeitet und alle Docker in eine YAML-Datei gepackt, damit ich die Docker nicht einzeln starten muss. Die mit $ gekennzeichneten Bezeichner sind als Variablen gedacht, die müsst Ihr bei euch anpassen.

 

Folgende Datei mit dem Namen docker-compose.yml in einem neuen Verzeichnis erstellen und abspeichern. Wenn Ihr das über Windows erledigt solltet Ihr übrigens (z. B. über Notepad++) die richtigen Zeilenumbruch-Zeichen verwenden, denn die weichen unter Windows im Vergleich zu Linux ab:

 

Zeilenumbruch

 

Nachfolgend der Inhalt der Datei, bitte beachten die PUID und PGID noch zu ändern:

 

version: "3"
services:
  database.mariadb:
    image: mariadb:latest
    container_name: mariadb
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=$Password
      - TZ=Europe/Berlin     
    volumes:
      - $Hostpath1:/etc/mysql/conf.d
      - $Hostpath2:/var/lib/mysql
    restart: always
    networks:
      - lsio   


  database.redis:
    image: bitnami/redis
    container_name: redis
    ports:
      - 6379:6379     
    environment:
      - TZ=Europe/Berlin   

      - REDIS_PASSWORD=$Password
    volumes:
      - $Hostpath:/bitnami/redis/data
    restart: always
    networks:
      - lsio   

 

  service.collabora:
    image: collabora/code
    container_name: collabora
    ports:
      - 9980:9980     
    environment:
      - TZ=Europe/Berlin 
      - domain=nextcloud\\.$Domain\\.duckdns\\.org
      - username=admin
      - password=$Password
    restart: always
    networks:
      - lsio      


  service.nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    ports:
      - 8443:443
      - 8008:80
    environment:
      - PUID=1000
      - PGID=1000 
      - TZ=Europe/Berlin

               - REDIS_HOST=localhost
      - REDIS_HOST_PORT=6379
      - REDIS_HOST_PASSWORD=$Password
    volumes:
      - $Hostpath:/var/www/html
    restart: always
    networks:
      - lsio   

 

  service.swag:
    image: ghcr.io/linuxserver/swag
    container_name: swag
    ports:
      - 443:443
    cap_add:
      - NET_ADMIN     
    environment:
      - TZ=Europe/Berlin
      - URL=$Domain.duckdns.org
      - SUBDOMAINS=wildcard
      - VALIDATION=duckdns
      - DUCKDNSTOKEN=$Token    
    volumes:
      - $Hostpath:/config
    restart: always
    networks:
      - lsio

 

  service.duckdns:
    image: lscr.io/linuxserver/duckdns 
    container_name: duckdns
    environment:
      - TZ=Europe/Berlin
      - SUBDOMAINS=$Domain
      - TOKEN=$Token
      - LOG_FILE=true     
    volumes:
      - $Hostpath:/config
    restart: always
    networks:
      - lsio

 

service.clamav:
  image: clamav/clamav
  container_name: clamav
  ports:
    - 3310:3310
  restart: always
  networks:
    - lsio   

              
networks:
  lsio:
    external: true

 

Mit dem Befehl

docker-compose up –d

könnt Ihr dann alle Docker automatisch erstellen und hochfahren lassen.

Mit dem Befehl

docker-compose down

werden dagegen die Docker-Instanzen heruntergefahren und die Container wieder gelöscht. Achtung, Einstellungen in den Containern, die nicht auf den Host gemappt wurden, gehen dabei verloren. Das geschieht aber auch bei jedem Update des Containers über Watchtower.

 

Wenn ich die Container neu erstellen lasse muss ich danach zumindest zwei Schritte jedesmal neu durchführen:

1. In der MariaDB-Datenbank den Befehl

GRANT ALL ON nextcloud.* to 'nextcloud'@'localhost' IDENTIFIED BY '$PASSWORD' WITH GRANT OPTION;

durchführen.

2. Im MariaDB-Container die Datei

nano /etc/mysql/my.cnf

bearbeiten und den Befehl

innodb_read_only_compressed=OFF

hinzufügen.

 

Nur für das Hoch/Runterfahren reicht aber auch ein

docker start/stop/restart $Name

 

Eventuell überprüfe ich das nochmal, aber im Moment stört mich das nicht weil ich die MariaDB-Datenbank von der automatischen Aktualisierung ausgenommen habe (das ist sowieso problematisch, weil die Datafiles nach einem Major-Update nicht weiterverwendet werden können, siehe vorherigen Beitrag). Wie bereits erwähnt sollte man die Datenbank dann aber auch nicht übers Internet freigeben.

 

Wie man sehen kann habe ich dabei auch die Redis-Datenbank über einen separaten Docker mit aufgenommen. Die Redis-Datenbank ist eine Key/Value-Datenbank die im Arbeitsspeicher betrieben wird, und dient bei Nextcloud als (optionaler) Cache für eine höhere Geschwindigkeit.

 

Dazu erstmal die Links, zuerst von dem Bitnami-Docker-Container. Dazu Verweise auf die Blogs von DasNetzUndIch, Vaahsen und Taste-of-It.

 

Entweder setzt man die Redis-Verbindungsparameter über die Docker-Variablen von Nextcloud:

      - REDIS_HOST=localhost
      - REDIS_HOST_PORT=6379
      - REDIS_HOST_PASSWORD=$Password

oder man bearbeitet die config.php des Nextcloud-Containers direkt und ergänzt die folgenden Einträge:

  'memcache.local' => '\\OC\\Memcache\\APCu',
  'memcache.distributed' => '\\OC\\Memcache\\Redis',
  'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' => [
'host' => 'localhost’,
'port' => 6379,
'password' => '$Password',
],

 

Außerdem muss man für den gemappten Redis-Pfad auf dem Host ein

chown 1001 ./$Pfad

absetzen damit es funktioniert, weil der Container nicht mit root-Rechten läuft. Siehe auch die oben verlinkte Docker-Dokumentation. Mit Redis habe ich jedenfalls eine spürbar höhere Geschwindigkeit in Nextcloud bemerkt.

 

In Nextcloud selber scheint man nicht zu sehen zu können, dass Redis verwendet wird. Man bemerkt aber spätestens dann, wenn man Redis beendet und Nextcloud nicht mehr läuft, dass es genutzt wird. Man kann sich auch in den Redis-Container einloggen und sieht mit dem Befehl

ps ax | grep redis
dass ein Serverprozess von Redis läuft.

 

Ansonsten empfehle ich noch, die App “Preview Generator” über den Nextcloud-Appstore zu installieren, denn Foto-Gallerien werden damit spürbar schneller geladen. Nach der Installation führt man erstmalig folgenden Befehl auf dem Host aus:

 

docker exec --user www-data nextcloud /var/www/html/occ preview:generate-all

 

Das dauert dann durchaus eine Viertelstunde oder länger, um die Vorschaubilder zu generieren. Über die Crontab des Hosts habe ich dann noch folgenden Befehl hinzugefügt, damit das automatisch geschieht:

 

0 23 * * * docker exec --user www-data nextcloud /var/www/html/occ preview:pre-generate

 

Es gibt noch weitere Möglichkeiten, Nextcloud zu optimieren, z. B. indem man das “High Performance Backend” einrichtet, siehe z. B. den Apfelcast-Workshop. Den in einen bereits vorhandenen Reverse Proxy zu integrieren soll aber etwas aufwendiger sein. Für die private Cloud mit ein paar Benutzern sollte das eigentlich nicht notwendig sein.

 

Ergänzung 28.12.2021: Bei Decatec habe ich auch eine gute Anleitung gefunden, falls man alles von Grund auf selber installieren möchte.

 

Ergänzung 25.03.2022: Ich habe in der oben aufgeführten YML-Datei noch einen ClamAV-Docker als Virenscanner hinzugefügt. In Nextcloud kann man dazu im Appstore die App “Antivirus for files” downloaden.

 

In Nextcloud muss man dann bei den Einstellungen unter Sicherheit folgende Änderungen vornehmen:

 

image

 

 

Ein Malware-Testfile kann man dann unter

https://www.eicar.org/?page_id=3950

herunterladen. Diese Datei wird dann auch von Windows automatisch schnell gelöscht.

 

Wenn man versucht diese Datei in Nextcloud hochzuladen erscheint dann folgende Fehlermeldung:

 

image

 

Und das wird dann natürlich auch unter Protokollierung geloggt:

 

image 

Ergänzung 07.04.2022: Habe noch den Hinweis ergänzt die PUID und PGID bei den Docker-Containern zu ändern: Link. Denn um Rechteprobleme mit den gemappten Volume-Pfaden zu vermeiden, wird empfohlen die User-ID und Group-Id des Users in den Container zu übergeben, mit dem der Volume-Pfad auf dem Host erstellt wurde. Wenn man das macht werden neue Dateien, die vom Docker erstellt wurden, mit dem richtigen Eigentümer erstellt.

 

Es ist aber nicht bei jedem Docker möglich die UserID zu übergeben, bei den Dockern von Linuxserver.io geht es über die Umgebungsvariablen PUID und PGID. Da muss man die Dokumentation zu jedem Docker lesen.

 

Man kann auch im YML-File die Userid übergeben, dann läuft der gesamte Docker über den angegebenen User. Das wird wohl bei jedem Docker funktionieren:

user: "UID:GID"

Aber zumindest der offizielle MariaDB-Docker startet dann wegen Rechteproblemen gar nicht mehr hoch.

 

Ergänzung 01.05.2022: Es gibt sicher mehrere Möglichkeiten, ein Backup der Datenbank von Nextcloud durchzuführen. Bei PostgreSQL habe ich es mit einem separaten Docker gelöst, bei dem nur der Backup-Prozess in einer Schleife läuft. Die Nextcloud-Datenbank läuft bei mir über MariaDB, auch wenn Nextcloud ebenfalls PostgreSQL unterstützt.

 

Die Nextcloud-Datenbank dumpe ich über diesen Befehl über einen Cronjob, die ich dann mitsichere:

docker exec mariadb mysqldump --user=root --password=$PASSWORD --all-databases > $HOSTPATH/mariadb-dump-$(date +\%F_\%H-\%M-\%S).sql. Wenn der Befehl in der Crontab steht, müssen die %-Zeichen mit \ gequotet werden.

 

Bei techoverflow.net gibt es zu dem Optionen des Befehls einen Überblick. In Zukunft will ich außerdem einen Proxmox-Backupserver installieren, aber das wird noch etwas dauern.

 

Ergänzung 05.05.2022: Automatische Updates sind nicht immer unproblematisch. Heute wurde der Docker von Nextcloud auf die Version 24 aktualisiert, und nach dem Update startete mein Nextcloud nicht mehr:

 

image

 

Der Prozess hing in einer Dauerschleife fest, was man nur über die Docker Logs einsehen konnte. Ich habe dann auf Stackoverflow den Hinweis gefunden, die Lockdatei /var/www/html/nextcloud-init-sync.lock zu löschen. Je nachdem, auf welchen Hostpfad /var/www/html/ gemappt ist, muss man natürlich woanders nachsehen.

 

Danach startete Nextcloud einen Schritt weiter, aber das Update war noch nicht vollständig abgeschlossen. Selbst wenn der Nextcloud-Docker aktualisiert wurde, bleibt da immer noch die Nextcloud-Datenbank über, die auch upgedatet werden muss. Da ich das über einen Cronjob des Hosts automatisiert habe hätte ich einfach bis morgen warten können, habe aber dann die restlichen Updatebefehle händisch ausgeführt. Die dafür notwendigen occ-Befehle sind weiter oben aufgelistet.

 

Danach startete mein Nextcloud wieder wie gewohnt. Nach einem Major-Update sollte man einmal in den Einstellungen unter Übersicht die Selbstkontrolle einmal prüfen:

 

image

 

Außerdem kann auch ein Blick in das Nextcloud-Protokoll nicht schaden.

 

Ergänzung 11.06.2022: Da bei mir Nextcloud wiederholt mit dieser Meldung nach einem automatischen Update hing, bin ich dazu übergegangen vor den Updates die Lockdatei automatisch zu löschen und den Container neu zu starten:

 

0 5 * * * rm -rf $HOSTPATH/nextcloud-init-sync.lock ; docker restart nextcloud

 

Wahrscheinlich ist das aber keine Lösung die für eine Produktivumgebung geeignet ist.

   

Tag-Wolke

Monats-Liste