traefik, noip, duckdns, wordpress, nextcloud, bitwardenrs – ohne datenbank in der vm

Änderungsstand: 2020-09-18

18.09.2020 Fehler im crontab behoben!

17.09.2020: Jetzt NEU! WordPress Multisite einrichten. Mehrere Seiten in einer WordPress-Instanz. Ich richte 3 verschiedene WordPress-Domains in einer WordPress-Installation ein!

Debian-Server-VM, Compose, NO-IP, DuckDNS, Traefik, Nextcloud, WordPress, Whoami, Bitwardenrs inkl. Letsencrypt, Dockerupdates und das UNRAID- Backup der VM

Übrigens: In diesem Setup verwende ich meine erstellte Datenbank, die direkt in Unraid als Docker installiert wurde. Die VM bleibt quasi Datenbankfrei.

In Sachen Aufwand sprengt dieser Guide alle Ketten 🙂 . Ich zeige, wie man mittels Traefik 2.2 in einer VM, mit NoIp und DuckDNS, gleichzeitig verschiedene DynDNS-Anbieter verwenden kann. Ursprünglich sollte nur die Vorgehensweise mit NoIp erscheinen. Doch es führte wieder einmal das Eine zum Anderen 🙂 .

Info: NoIP hat in der Kostenlosen Version gegenüber DuckDNS einige Nachteile.

  • Die erstellten Domains müssen monatlich bestätigt werden, sonst sind diese wieder weg.
  • Keine Subdomains nutzbar wie z.B. subdomain.domain.sytes.net

Den Vorteil möchte ich natürlich nicht vorenthalten.

  • Mega viele Domainnamen verfügbar, wie z.B. *.sytes.net, *.hopto.org, *.ddns usw. (bei DUCKDNS gibt es nur domain.duckdns.org.

.

Zuerst erstelle ich einen Freigabeordner in Unraid, der später als zusätzlicher Speicherplatz, Hauptsächlich für die Nextcloud-Daten, in der VM dient. Dann wird die VM erstellt, der SSH-Zugang für das Terminal aktiviert, für die VM eine feste IP-Adresse vergeben und der Freigabeordner in der VM eingebunden. Dann gibt es Vorbereitungen für Traefik, Passwortschutz, Einrichtung für NoIp, Installation des Traefik-Dockers, Portfreigaben im Router, Erstellung von Nextcloud-Docker und WordPress-Docker und zum Schluss die Handhabung, parallel mit DuckDNS zu arbeiten, mit dem Beispiel von Whoami und einer Subdomain, das automatische Update aller Docker mittels Scriptdatei und das Backup der VM in Unraid.

  • Unraid-Freigabeordner erstellen: /data/vmdata
  • VM erstellen (2 Core & mind. 4GB zugewiesener Ram)
    • VM Größe: 16G
    • Unraid Share: /mnt/user/data/vmdata
    • Unraid Mount tag: vmdata
  • CREATE

VM installieren. Ich benötige bei der Softwareauswahl nur den SSH server. Wenn fertig, VM einrichten.

nano /etc/ssh/sshd_config

Diese Zeile suchen:

#PermitRootLogin prohibit-password

Ändern in:

PermitRootLogin yes

Dann

STRG-x, y, Enter

reboot

Jetzt die IP-Adresse des Servers herausfinden (Login mit root und

ip a

eingeben). Jetzt hat man die IP-Adresse und kann auch über Putty oder Kitty den SSH-Zugang verwenden.

Statische IP zuweisen:

nano /etc/network/interfaces

Folgende Einträge dürften in der Standardkonfiguraion stehen:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug enp2s0
iface enp2s0 inet dhcp

Diese Einträge ändere ich in:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
 
source /etc/network/interfaces.d/*
 
# The loopback network interface
auto lo
iface lo inet loopback
 
# The primary network interface
allow-hotplug enp2s0
iface enp2s0 inet static
  address 192.168.252.128
  netmask 255.255.255.0
  gateway 192.168.252.1
  dns-nameservers 192.168.252.1

STRG-x, y, Enter

VM im Unraid neu starten.

Einbinden des zusätzlichen Freigabeordners in der VM. Als root einloggen:

cp /etc/fstab /etc/fstab.original
mkdir /mnt/sharedfolders
nano /etc/fstab

Folgende Zeile am Ende der Datei einfügen:

vmdata /mnt/sharedfolders 9p trans=virtio,version=9p2000.L,_netdev,rw 0 0

STRG-x, y, Enter

mount -a

Erscheint jetzt keine Fehlermeldung, ist der Freigabeordner verfügbar und auch beim Start der VM automatisch eingebunden.

Vorbereitung für Traefik:

  • Zeile 3 = optional (benötige ich für weitere Sachen)
  • Zeile 4 = Gast-Agent für Unraid (optional)
apt update && apt upgrade -y
apt install --no-install-recommends -y apache2-utils
apt install sudo wget -y
sudo apt install qemu-guest-agent -y
sudo apt install docker docker-compose curl jq mc -y
sudo mkdir -p /home/dockervolumes
sudo mkdir -p /home/dockervolumes/traefik
sudo touch /home/dockervolumes/traefik/acme.json
sudo chmod 600 /home/dockervolumes/traefik/acme.json
sudo touch /home/dockervolumes/traefik/.htpasswd
sudo touch /var/log/traefik.log
sudo chmod 600 /var/log/traefik.log
sudo docker network create traefik-net
sudo docker network create intern

Middlewares (optional):

Kommen wir zum Passwortschutz für unserer Web-Zugriffe von Aussen. Auch hier wieder eine etwas andere Methode, als man sie aus anderen Guides von mir kennt.

Ich möchte nun, dass beim Aufruf einiger meiner gewünschten Sites, ein Passwortschutz erscheint, weil ich paranoid bin. Natürlich nicht. Ich möchte demonstrieren, wie das funktioniert. Da ich die dazu benötigte .htpasswd schon angelegt habe, reicht hierfür ein einfacher Befehl. „-B“ bedeuted, dass bcrypt als Verschlüsselung verwendet wird und die Pfadangabe sagt, wohin der Benutzername, in meinem Beispiel der User FerdinandAdmiN, inkl. dazugehörigem Passwort, welches gleich anschließend, nach Befehlseingabe, eingegeben werden muss, abgespeichert wird:

sudo htpasswd -B /home/dockervolumes/traefik/.htpasswd FerdinandAdmiN

Möchte man jetzt weitere Benutzer mit separaten Passwörtern hinzufügen, dann diesen Befehl einfach wiederholt, mit einem weiteren Benutzer, verwenden. In meinem Beispiel verwende ich FerdinandAdmiNzWei:

sudo htpasswd -B /home/dockervolumes/traefik/.htpasswd FerdinandAdmiNzWei

Für weitere Benutzer fährt man einfach so weiter. Die Benutzer sind in der .htpasswd-Datei eingetragen. Öffnet man die Datei, können auch einzelne Benutzer mit dem dazugehörigem generiertem bcrypt-Passwortfile gelöscht werden, falls diese nicht mehr benötigt werden. Jeder Benutzer belegt eine Zeile.

Hierbei sollte beachtet werden, dass man kein $-Zeichen im Passwort, welches man eingeben muss, verwendet. Das macht Probleme beim generierten bcrypt-Passwort bzw. beim Auslesen des Passwortes und funktionierte bei mir (mehrmals getestet) nicht. Damit kann ich aber sehr gut zurecht kommen 🙂 . Weitere Einschränkungen, bei der Verfahrensweise mit Sonderzeichen, sind mir jetzt nicht bekannt, aber auch nicht ausgeschlossen.

Die wichtigsten Vorbereitungen wären abgeschlossen.

Erstellen des NO-IP-Dockers direkt in Unraid:

Hier ist es relativ egal, ob dieser Docker in der VM oder direkt in Unraid gestartet wird. Ich entscheide mich mich für die Installation direkt in UNRAID, da sich der Ablauf einfacher gestaltet.

Das muss vorher erledigt sein!

  • „Apps“
  • Im Suchfeld noip eingeben
  • NoIp (coppit) auf Download-Symbol klicken
  • „Apply“

Wenn fertig heruntergeladen,

  • „Done“ klicken
  • „Docker“
  • Autostart „ON“

Jetzt im Ordner /mnt/user/appdata/NoIP die Datei noip mit z.B. Notepad++ öffnen und die Einträge ändern. Vorrausgesetzt ist ein erstelltes No-IP-Konto auf https://www.noip.com/ und 3 erstellte Domains in diesem Konto.

Mehr als eine Domain wird normalerweise mit der Verwendung von Traefik nicht benötigt, da Traefik hervorragend über Subdomains agiert, was die Sache sehr angenehm macht.

Leider funktioniert das, in der kostenlosen Version, nicht bei NoIp!

Dafür muss man ein Erweiterungspaket kaufen, was momentan mit 25$ pro Jahr keine Option für mich ist. Mit der Verwendung von DuckDNS gibt es da keine Probleme. Da ich aber eine kostenlose Alternative zu DuckDNS zeigen möchte, muss ich hier mit dieser Einschränkung leben. Am Ende des Guides zeige ich, wie mann NoIp und DuckDNS parallel betreiben kann.

Ich benutze für meine Beispiele 3 Domains bei NoIp. Das sind:

  • traefik.ddns.net (für die Traefik-Benutzeroberfläche)
  • wordpress.ddns.net (für WordPress)
  • nextcloud.ddns.net (für Nextcloud)

Natürlich sind das nur fiktive Beispiele.

Zurück zur Datei im /mnt/user/appdata/NoIP-Verzeichnis.

Standardmässig sind folgende Einträge in dieser Datei zu finden:

# This is an email address
USERNAME='email@example.com'

PASSWORD='your password here'

# Your hostname, group name, or a comma-delimited list of a mix of them.
DOMAINS='foo.ddns.net'

# Examples: 5 m, 5 h, 5 d. Minimum is 5 minutes.
INTERVAL='30m'

Ich ändere die Einträge nun mit meinen eigenen Werten:

# This is an email address
USERNAME='angelegter user bei NoIP' #(Email-Adresse dürfte auch funktionieren)

PASSWORD='dazugehöriges passwort'

# Your hostname, group name, or a comma-delimited list of a mix of them.
DOMAINS='meine-erstellte-group'

# Examples: 5 m, 5 h, 5 d. Minimum is 5 minutes.
INTERVAL='5m'

Zur Info: Ich erstellte in meinen No-IP-Konto eine Group. Damit werden die IP’s aller erstellten Domains aktualisiert, die sich in dieser Group befinden.

Wenn erledigt, den NoIp-Docker neu starten. Im Protokoll kann man sehen, ob alles soweit funktioniert.

Wenn erledigt, zurück zum Terminal der VM.

Erstellen des Traefik-Dockers, inkl. Features, komplett eingerichtet:

sudo nano /home/dockervolumes/traefik/dynamic_conf.yml
tls:
  options:
    default:
      minVersion: VersionTLS12
      cipherSuites:
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
        - TLS_AES_128_GCM_SHA256
        - TLS_AES_256_GCM_SHA384
        - TLS_CHACHA20_POLY1305_SHA256
      curvePreferences:
        - CurveP521
        - CurveP384
      sniStrict: true
http:
  middlewares:
    secHeaders:
      headers:
        browserXssFilter: true
        contentTypeNosniff: true
        frameDeny: true
        sslRedirect: true
        #HSTS Configuration
        customFrameOptionsValue: "SAMEORIGIN"
        stsIncludeSubdomains: true
        stsPreload: true
        stsSeconds: 31536000
    https-redirect:
      redirectScheme:
        scheme: https

STRG-x, y, Enter

Vielen Dank an dieser Stelle an https://goneuland.de/traefik-v2-https-verschluesselung-sicherheit-verbessern/. Ohne diesen Tip wäre es hier nicht so einfach weiter gegangen. Ganz speziell die Header-Sache hat mich am WordPress fast zum Verzweifeln gebracht. Ich habe diese Datei um ein kleines Extra erweitert (die letzten 3 Zeilen).

In folgender Datei die Email-Adresse nicht vergessen einzutragen!

sudo nano /home/dockervolumes/traefik/traefik.yml
## STATIC CONFIGURATION
log:
  level: INFO
  filePath: "/traefik.log"
  
api:
  insecure: true
  dashboard: true
  
entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"
  
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    network: traefik-net
    exposedByDefault: false
  file:
    filename: "/dynamic_conf.yml"
  
certificatesResolvers:
  lets-encr:
    acme:
      storage: acme.json
      email: EMAIL@EMAIL.COM
  
      httpChallenge:
        entryPoint: http

STRG-x, y, Enter

Passen wir die traefik-docker-compose.yml noch an. Traefik wird nun von Innen und von Aussen erreichbar sein. Natürlich hier unbedingt von Aussen Passwortgeschützt und mit einer sicheren Verbindung. Wartet bitte ca. 1 Minute nach dem Start von Traefik, dass Letsencrypt genügent Zeit hat, die Zertifikate anzulegen. Das gilt auch für die anderen Docker. Zeile 33 und Zeile 37, Grün markiert, beinhalten den Passwortschutz. Bei Zeile 33 muss nach users= die geänderte Zeichenfolge , mit dem jeweils zusätzlichen $-Zeichen, eingetragen werden. Das “ am Ende der Zeile nicht vergessen! Und natürlich Eure eigene Domain in den Zeilen 32 und 36 verwenden.

sudo nano /home/dockervolumes/traefik/docker-compose.yml
version: '3'
  
services:
  traefik:
    image: "traefik:v2.2"
    container_name: "traefik"
    hostname: "traefik"
    restart: unless-stopped
  
    security_opt:
      - no-new-privileges:true
  
    networks:
      - traefik-net
  
    ports:
      - 80:80
      - 443:443
      - 8080:8080
  
    volumes:
      - "/etc/localtime:/etc/localtime:ro"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "/var/log/traefik.log:/traefik.log"
      - "./traefik.yml:/traefik.yml:ro"
      - "./acme.json:/acme.json"
      - "./dynamic_conf.yml:/dynamic_conf.yml:ro"
  
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=http"
      - "traefik.http.routers.traefik.rule=Host(`traefik.ddns.net`)"
# folgende Zeile gehört zur Passwortabfrage
      - "traefik.http.middlewares.traefik-auth.basicauth.usersfile=.htpasswd"
      - "traefik.http.routers.traefik.middlewares=https-redirect@file"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.rule=Host(`traefik.ddns.net`)"
# folgende Zeile gehört ebenfalls zur Passwortabfrage
      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=lets-encr"
      - "traefik.http.routers.traefik-secure.service=api@internal"
  
networks:
  traefik-net:
    external: true

STRG-x, y, Enter

Bevor nun der Docker gestartet wird, müssen 2 Portfreigaben im Router erstellt werden. Da die Portfreigabe eines bestimmten Portes immer nur auf einem Gerät weitergeleitet werden kann, muss, falls schon für Unraid eine externe Portfreigabe für Port 80 und 443 eingerichtet wurde, diese vorher gelöscht werden. Hier gibt es ein Beispiel für eine Portfreigabe in der Fritz!Box 7590.

Wurde die Portfreigabe erstellt, kann der Traefik-Docker gestartet werden:

cd /home/dockervolumes/traefik && sudo docker-compose up -d

Wurde der Docker gestartet, empfehle ich ca. 1 Minute zu warten, bevor man die Website aufruft. Aufruf der Website in meinem Beispiel:

knilix.sytes.net

Eine automatische Weiterleitung zu http s erfolgt und es erscheint eine Passwortabfrage.

Login:

Benutzername: FerdinandAdmiN

Kennwort: Das eingegebene Passwort (htpasswd…(nicht das verschlüsselte Passwort))

Willkommen im Benutzermenu von Traefik.

Intern ist das Benutzermenu auch erreichbar:

VM-IP-Adresse:8080

Da Traefik nun läuft, komme ich zu Nextcloud und WordPress. Für diese Docker benötige ich noch eine MariaDB-Datenbank und ein Tool, um die Datenbank(en) zu administrieren. Wie am Anfang schon angekündigt, erstelle ich in meiner VM keine Datenbank, sondern nutze die schon vorhandene DB, die ich direkt in Unraid als Docker installierte. Hier ist der Guide dazu. PHPMyAdmin findet man hier. Und wie man eine Datenbank mittels PHPMyAdmin erstellt, zeige ich jetzt noch einmal.

Anlegen einer Datenbank:

Phpmyadmin startet und knallt uns prompt einen kleinen Warnhinweis um die Ohren. Doch das ist normal.

Einfach auf „Finden Sie heraus, warum“ klicken

Und jetzt auf „anlegen“ klicken – Fertig. Es erscheinen ganz viele „OK’s“.

Dann auf Datenbanken (oberes Menufeld) klicken, einen Datenbanknamen im Eingabefeld eintragen (nextcloud) und utf8_general_ci und auf „Anlegen“ klicken.

Jetzt im linken Menu auf „Neu“ und im oberen Menu auf „Benutzerkonten“ klicken. Nun auf „Neu – Benutzerkonto hinzufügen“

Benutzername und Passwort angeben. Hostname gebe ich mit % an. Authentifizierung ist „Native MYSQL.Authentifizierung“.

Jetzt ganz runter scrollen und auf „OK“ klicken. Alles was mit „Globale Rechte“ zu tun hat, bleibt bitte AUS! Auch Datenbank für Benutzerrechte lassen wir unberührt.

Jetzt legen wir noch für unseren soeben erstellten Benutzer die Datenbankrechte an. Links im Menu auf „Neu“ und oben im Menu auf „Benutzerkonten“. Jetzt an den soeben erstellten Benutzernamen „Rechte ändern“ klicken, oben, in der zweiten Reihe, den Reiter „Datenbank“ wählen, im Auswahlmenu „nextcloud“ selektieren und OK. Jetzt bei „Datenbankspezifife Rechte“ – „Alle auswählen“ und OK.

Soeben wurde eine Datenbank für nextcloud erstellt, mit einem Benutzer, der NUR Rechte für die Datenbank nextcloud besitzt.

Da wir jetzt wissen, wie es funktioniert, legen wir auch gleich eine Datenbank und einen Benutzernamen für WordPress an 🙂

Tip: In der Datenbank gibt es einen User, der da definitiv nicht hingehört. Diesen User bitte löschen.

  • Links auf „Neu“ klicken
  • Oben auf „Benutzerkonten“ klicken
  • Beim User „Jeder“ das Kästchen selektieren und OK bei „Die ausgewählten Benutzerkonten löschen“ klicken

Des Weiteren sollte dem User „mariadb.sys“, wenn ein Warnhinweis steht, dass kein Passwort vergeben ist, ein Passwort vergeben werden.

  • Beim User „mariadb.sys“ auf „Rechte ändern“
  • Oben auf „Passwort ändern“ klicken
  • Passwort vergeben und auf „OK“ klicken

Wenn fertig, kann das phpmadmin-Fenster geschlossen werden.

Nextcloud-Docker:

Wer unbedingt einen zusätzlichen Website-Passwortschutz benötigt, muss das #-Zeichen in den Zeilen 21 und 26 entfernen.

sudo mkdir /home/dockervolumes/nextcloud
cd /home/dockervolumes/nextcloud && sudo nano docker-compose.yml
version: "3.3"

services:
   nextcloud:
    image: nextcloud
    container_name: nextcloud
    hostname: nextcloud
    restart: unless-stopped
    ports:
      - 8082:80
    volumes:
      - /var/lib/Nextcloud/html:/var/www/html
      - /var/lib/Nextcloud/apps:/var/www/html/custom_apps
      - /var/lib/Nextcloud/config:/var/www/html/config
      - /mnt/sharedfolders/NextcloudData:/var/www/html/data

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nextcloud.entrypoints=http"
      - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.ddns.net`)"
#      - "traefik.http.middlewares.nextcloud-auth.basicauth.usersfile=.htpasswd"
      - "traefik.http.routers.nextcloud.middlewares=https-redirect@file"
      - "traefik.http.routers.nextcloud-secure.entrypoints=https"
      - "traefik.http.routers.nextcloud-secure.middlewares=calcarddav,secHeaders@file"
      - "traefik.http.routers.nextcloud-secure.rule=Host(`nextcloud.ddns.net`)"
#      - "traefik.http.routers.nextcloud-secure.middlewares=nextcloud-auth"
      - "traefik.http.routers.nextcloud-secure.tls=true"
      - "traefik.http.routers.nextcloud-secure.tls.certresolver=lets-encr"
# Traefik-Redirects für CalDAV / CardDAV:
      - "traefik.http.middlewares.calcarddav.redirectregex.permanent=true"
      - "traefik.http.middlewares.calcarddav.redirectregex.regex=https://(.*)/.well-known/(card|cal)dav"
      - "traefik.http.middlewares.calcarddav.redirectregex.replacement=https://$$1/remote.php/dav/"
 
    networks:
      - traefik-net
 
networks:
  traefik-net:
    external: true

STRG-x, y, Enter

cd /home/dockervolumes/nextcloud && sudo docker-compose up -d

Auf zur Einrichtung Nextcloud

Dazu die erstellte Domain im Browser eingeben. In meinem Fall wäre das:

nextcloud.ddns.net

Eine automatische Weiterleitung zu http s erfolgt.

Administrator-Konto anlegen: lasst Euch was einfallen. Statt admin kann man auch etwas komplizierteres nehmen, wie z.B. aDmiNfeRdiNand

Datenverzeichnis: /var/www/html/data

Speicher & Datenbank: MySQL/MARIADB

Datenbankbenutzer: Euren Benutzer, der in Unraid mittels phpmyadmin für diese Nextcloud-VM-Instanz erstellt wurde

Datenbankpasswort: Das dazugehörige Passwort

Datenbankname: nextcloud (bzw. das, was gewählt wurde)

Datenbank-Host: UNRAID-Server-IP:3306

Jetzt auf „Installation abschließen“ klicken. Das dauert dauert jetzt etwas. Nach einiger Zeit springt das Anmeldefenster um und es werden noch empfohlene Apps installiert, weil ich den Haken bei „Empfohlene Apps installieren“ gesetzt habe. Irgendwas ist doch immer^^.

Die gesamte Ersteinrichtung dauerte ca. 4 Minuten.

Fertig!

Ein Tip!

Das Login mit dem Benutzernamen, welchen wir für Nextcloud in der *.yml angelegt haben, gilt NUR für den Datenbankzugriff (z.B über phpmyadmin). Der Login im Nextcloud ist das Administrator-Login, welches während der Ersteinrichtung im Browser angelegt wurde.

Sicherheits- & Einrichtungswarnungen in Nextcloud:

Einige Sachen werden hier behoben.

Ein weiterer Tip (Login-Problem Handy-App)!

Nach dem Browser-Login im Nextcloud, erstelle ich einen weiteren Benutzer, der keine admin-Rechte hat. Dann logge ich mit diesem Benutzer ein, gehe auf Einstellungen (rechts oben) und dann links auf Sicherheit. Dort im Hauptfenster, ziemlich weit unten auf App-Name, dort gebe ich einen Namen ein, klicke auf „Neues App-Passwort erstellen“ und dann auf „QR-Code für mobile Apps anzeigen“. Diesen QR-Code verwende ich dann für das erste Login in der Nextcloud-App am Handy. Somit wäre binnen Sekunden die Einrichtung der Handy-App erledigt.

WordPress-Docker:

sudo mkdir -p /home/dockervolumes/wordpress-1
sudo nano /home/dockervolumes/wordpress-1/docker-compose.yml
version: '3.1'
 
services:
 
  wordpress:
    image: wordpress
    restart: unless-stopped
 
    ports:
      - 8085:80

    environment:
      WORDPRESS_DB_HOST: 192.168.252.118:3306  # Unraid-IP:Port
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: 1234569867 # Das Passwort für die WP-DB
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - /var/lib/Wordpress_1:/var/www/html
 
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wordpress-app.entrypoints=http"
      - "traefik.http.routers.wordpress-app.rule=Host(`wordpress.sytes.net`)"
      - "traefik.http.middlewares.wordpress-app-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.wordpress-app.middlewares=wordpress-app-https-redirect"
      - "traefik.http.routers.wordpress-app-secure.entrypoints=https"
      - "traefik.http.routers.wordpress-app-secure.rule=Host(`wordpress.sytes.net`)"
      - "traefik.http.routers.wordpress-app-secure.tls=true"
      - "traefik.http.routers.wordpress-app-secure.tls.certresolver=lets-encr"
      - "traefik.http.routers.wordpress-app-secure.service=wordpress-app"
      - "traefik.http.services.wordpress-app.loadbalancer.server.port=80"
      - "traefik.docker.network=traefik-net"
      - "traefik.http.routers.wordpress-app-secure.middlewares=secHeaders@file"
 
    networks:
      - traefik-net

networks:
  traefik-net:
    external: true

STRG-x, y, Enter

cd /home/dockervolumes/wordpress-1 && sudo docker-compose up -d

Aufruf (bei mir):

http://wordpress.sytes.net

Eine automatische Weiterleitung zu http s erfolgt.

Jetzt noch ein Check auf SSL Labs (https://www.ssllabs.com/ssltest/)

A+, wie immer ein sehr gutes Ergebnis.

Wer WordPress mit einem Passwort schützen möchte, muss die Label-Einträge ändern. Bei mir sehen diese dann so aus:

.

labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wordpress-app.entrypoints=http"
      - "traefik.http.routers.wordpress-app.rule=Host(`wordpress.sytes.net`)"
      - "traefik.http.middlewares.wordpress-app-auth.basicauth.usersfile=.htpasswd"
      - "traefik.http.routers.wordpress-app.middlewares=https-redirect@file"
      - "traefik.http.routers.wordpress-app-secure.entrypoints=https"
      - "traefik.http.routers.wordpress-app-secure.rule=Host(`wordpress.sytes.net`)"
      - "traefik.http.routers.wordpress-app-secure.middlewares=wordpress-app-auth"
      - "traefik.http.routers.wordpress-app-secure.tls=true"
      - "traefik.http.routers.wordpress-app-secure.tls.certresolver=lets-encr"

Anschließend den Docker neu starten.

Nun ist WordPress nur mit Eingabe des Sicherheitspasswortes aus dem Middleware-Bereich, wir erinnern uns, abrufbar.

Jetzt noch schnell die eine Fehlermeldung im Nextcloud-Sicherheitscenter beheben. Dafür öffne ich die config.php:

sudo nano /var/lib/Nextcloud/config/config.php

Die Zeilen 5 bis 8 füge ich nach dem ‚trusted_domains‘ Abschnitt hinzu. Der Rest bleibt bestehen. Die IP-Adresse ist die der VM, auf der sich Traefik befindet.

'trusted_domains' =>
  array (
    0 => 'nextcloud.sytes.net',
  ),
'trusted_proxies' =>
  array (
    '192.168.252.128',
  ),
  'datadirectory' => '/var/www/html/data',

STRG-x, y, Enter

cd /home/dockervolumes/wordpress-1 && sudo docker-compose stop
cd /home/dockervolumes/wordpress-1 && sudo docker-compose up -d

Alle Fehler wurden behoben.

.

Optional Start:

Falls Probleme auftreten (sollte zwar nicht, aber ich hab‘ schon Pferde kotzen sehen 🙂 ), kann WordPress auch mit einer implementierten Datenbank installiert werden. Das war allerdings nicht mein Ziel. Da dieser Guide aber sowieso viel zu Groß ist, kommt es auf weitere Einträge auch nicht an. Als Alternative dient folgendes. Der eben erstellte Docker muss allerdings vorher gestoppt und sollte vorsichtshalber gelöscht werden (auch der Compose-Ordner), damit es am Ende keine Probleme beim Update-Script gibt.

WordPress-Docker (inkl. Datenbank) optional:

sudo mkdir -p /home/dockervolumes/wordpress
sudo nano /home/dockervolumes/wordpress/docker-compose.yml
version: '3.1'
 
services:
 
  wordpress:
    image: wordpress
    restart: unless-stopped
 
    ports:
      - 8084:80
    depends_on:
      - db
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: vmwordpress
      WORDPRESS_DB_PASSWORD: 1254389
      WORDPRESS_DB_NAME: vmwordpress
    volumes:
      - /var/lib/Wordpress_1:/var/www/html
 
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wordpress-app.entrypoints=http"
      - "traefik.http.routers.wordpress-app.rule=Host(`wordpress.sytes.net`)"
      - "traefik.http.middlewares.wordpress-app-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.wordpress-app.middlewares=wordpress-app-https-redirect"
      - "traefik.http.routers.wordpress-app-secure.entrypoints=https"
      - "traefik.http.routers.wordpress-app-secure.rule=Host(`wordpress.sytes.net`)"
      - "traefik.http.routers.wordpress-app-secure.tls=true"
      - "traefik.http.routers.wordpress-app-secure.tls.certresolver=lets-encr"
      - "traefik.http.routers.wordpress-app-secure.service=wordpress-app"
      - "traefik.http.services.wordpress-app.loadbalancer.server.port=80"
      - "traefik.docker.network=traefik-net"
      - "traefik.http.routers.wordpress-app-secure.middlewares=secHeaders@file"
 
    networks:
      - traefik-net
      - default
 
  db:
    image: linuxserver/mariadb
    restart: always
    environment:
      - PUID=1000
      - PGID=1000
      - MYSQL_ROOT_PASSWORD=8467219
      - TZ=Europe/Berlin
      - MYSQL_DATABASE=vmwordpress
      - MYSQL_USER=vmwordpress
      - MYSQL_PASSWORD=1254389
 
    volumes:
      - /var/lib/MysqlWP_1:/var/lib/mysql
 
    ports:
      - 3306:3306
 
    networks:
      - traefik-net
      - default
 
networks:
  traefik-net:
    external: true
 
volumes:
  wordpress:
  db:

STRG-x, y, Enter

cd /home/dockervolumes/wordpress && sudo docker-compose up -d

Aufruf:

http://wordpress.sytes.net

Eine automatische Weiterleitung zu http s erfolgt.

Optional Ende

Anmerkung:

Da nun alle 3 kostenlosen Domains bei NoIp ausgeschöpft sind (Traefik-UI, Nextcloud & WordPress), ich aber weitere Domains benötige (Bitwarden, Emby etc.), greife ich parallel zu DuckDNS. Traefik ist es relativ egal, welcher DynDNS-Dienst verwendet wird. Es reicht bei DuckDNS eine erstellte Domain, da man hier mit Subdomains arbeiten kann. Dafür installiere ich zuerst in UNRAID den DuckDNS-Docker. Hier gibt es den Guide dazu. Wenn erledigt, wieder ins Terminal der VM. Ich verwende jetzt das klassische Beispiel an Whoami. Erstellt habe ich nur eine Domain bei DuckDNS Namens knilix.duckdns.org und verwende für den Whoami-Docker im Label die Subdomain whoami.knilix.duckdns.org.

sudo mkdir -p /home/dockervolumes/whoami
sudo nano /home/dockervolumes/whoami/docker-compose.yml
version: "3.3"
 
services:
   whoami:
    image: "containous/whoami"
    container_name: "whoami"
    hostname: "whoami"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.entrypoints=http"
      - "traefik.http.routers.whoami.rule=Host(`whoami.knilix.duckdns.org`)"
      - "traefik.http.middlewares.whoami-auth.basicauth.usersfile=.htpasswd"
      - "traefik.http.routers.whoami.middlewares=https-redirect@file"
      - "traefik.http.routers.whoami-secure.entrypoints=https"
      - "traefik.http.routers.whoami-secure.rule=Host(`whoami.knilix.duckdns.org`)"
      - "traefik.http.routers.whoami-secure.middlewares=whoami-auth"
      - "traefik.http.routers.whoami-secure.tls.certresolver=lets-encr"
 
    networks:
      - intern
      - traefik-net
 
networks:
  intern:
    external: true
  traefik-net:
    external: true

STRG-x, y, Enter

cd /home/dockervolumes/whoami && sudo docker-compose up -d

Wurde der Docker gestartet, empfehle ich ca. 1 Minute zu warten, bevor man das erste Mal die Website aufruft. Aufruf der Website in meinem Beispiel:

whoami.knilix.duckdns.org

Eine automatische Weiterleitung zu http s erfolgt und es erscheint eine Passwortabfrage.

Login:

Benutzername: FerdinandAdmiN

Kennwort: Das selbst eingegebene Passwort

Willkommen im Whoami.

Und jetzt noch die Erstellung und Einrichtung von Bitwardenrs:

Ich wählte hier absichtlich einen ungewöhnlichen Subdomain-Namen um die Sicherheit etwas zu erhöhen.

Vorarbeit: Zuerst erstelle ich ein eigenes Token, was später benötigt wird. Im Terminal folgendes eingeben:

openssl rand -base64 48

Die Ausgabe kopieren und zur Aufbewahrung bereit halten. So sieht das Token ungefähr aus:

yWFHlREii81yrZvDA2cuPaXckMhmH55ZN7mPf+YNSB9MnU+/tKzAwR4lZR+cx8Ds

Aus Sicherheitsgründen nicht das von mir erstellte Token verwenden! Baut Euch selbst eins 🙂

sudo mkdir /home/dockervolumes/bitwardenrs
cd /home/dockervolumes/bitwardenrs && sudo nano docker-compose.yml
version: "3.3"
 
services:
   server:
    image: bitwardenrs/server
    container_name: bitwardenrs
    hostname: bitwardenrs
    restart: unless-stopped
    ports:
      - 86:80
    environment:
      - ADMIN_TOKEN=das_erstellte_private_Token
    volumes:
      - /var/lib/BitwardenrsData/:/data/

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.bitwardenrs.entrypoints=http"
      - "traefik.http.routers.bitwardenrs.rule=Host(`bitwardenrsjsz9dsor.knilix.duckdns.org`)"
      - "traefik.http.routers.bitwardenrs.middlewares=https-redirect@file"
      - "traefik.http.routers.bitwardenrs-secure.entrypoints=https"
      - "traefik.http.routers.bitwardenrs-secure.rule=Host(`bitwardenrsjsz9dsor.knilix.duckdns.org`)"
      - "traefik.http.routers.bitwardenrs-secure.tls.certresolver=lets-encr"

    networks:
      - traefik-net
  
networks:
  traefik-net:
    external: true

STRG-x. y, Enter

cd /home/dockervolumes/bitwardenrs && docker-compose up -d

Jetztz ca. 1 Minute warten. Die Initialisierung des Dockers dauert etwas. Dann im Browser:

bitwardenrsjsz9dsor.knilix.duckdns.org/admin

Eine automatische Weiterleitung zu http s erfolgt.

Jetzt das private Token eintragen bzw. hinein kopieren, übernehmen und die Browserseite mit der Pfeil-zurück-Taste erneuern. Das Hauptmenu erscheint. Falls nicht, dann die Adresse ohne /admin eingeben.

Jetzt in der oberen Menuleiste auf „Vault“ klicken und einen neuen Benutzer erstellen. Tut Euch selbst einen gefallen und benutzt ein Mega starkes Passwort, wie z.B.

dO3djrm4js9g2l8w6(vR5G3J4Va/G5j2

Natürlich auch hier wieder die Anmerkung, dass dieses Passwort nicht 1 zu 1 übernommen werden soll 🙂

Weiter und das Passwort nochmals bestätigen. Dann auf Konto erstellen. Wenn erledigt, kann man sich mit den soeben erstellten Daten anmelden.

Wer eine Organisation erstellen möchte, um z.B. Passwörter mit anderen zu teilen, geht auf Mein Tresor und +Neue Organisation.

Wer die gespeicherten Passwörter von z.B. Firefox aufnehmen möchte, geht auf Werkzeuge und Daten importieren. Vorher natürlich die gespeicherten Passwörter aus dem Firefox exportieren.

Zum Schluss auf das Benutzerlogo oben rechts klicken und „Die Apps erhalten“ wählen. Jetzt auf z.B. „Mozilla Firefox“ und dann das Plugin installieren, welches dann oben rechts am Browser mittels Icon erscheint. Bevor wir uns jetzt anmelden, gehen wir dort auf das Zahnradsymbol und geben die komplette Domainadresse (http s://bitwardenrsjsz9dsor.knilix.duckdns.org) an und „Speichern“. Jetzt können wir uns mit den Zugangsdaten anmelden und Bitwarden läuft mit gesichertem SSL. Synchronisieren nicht vergessen!

Zur Information: Ein separater Passwortschutz (http auth) für die Website funktioniert hier nicht. Deshalb empfehle ich einen kuriosen Subdomainnamen und natürlich, wie immer, sichere Passwörter.

Wer sich jetzt doch etwas unsicher fühlt, kann, wenn Bitwardenrs eingerichtet wurde, trotzdem das Ganze lokal betreiben.

Das ist aber unbegründet. Die URL muss bekannt sein (deshalb einen kuriosen Namen), die angegebene Email-Adresse muss bekannt sein und das starke Passwort muss auch noch bekannt sein um Zugriff zu bekommen.

Für wen das alles keine Gründe sind, muss in der docker-compose-Datei einfach die Zeile 17 auf false setzen.

  - "traefik.enable=false"

Anschließend den Docker neu starten:

cd /home/dockervolumes/bitwardenrs && docker-compose up -d

oder

cd /home/dockervolumes/bitwardenrs && docker-compose restart

Dann in der Bitwarden-App im Browser auf das Zahnradsymbol und auf abmelden. Dann auf das Zahnradsymbol links oben und folgende Adresse eingeben:

htt p://VM-IP:86

Man kann zwar mit der internen IP auf das Konfigurationsmenu nicht mehr zugreifen (der Login ist aufgrund fehlendem SSL gesperrt und Traefik leitet von Aussen, wegen fehlender Zuweisung auf eine nicht vorhandene Seite, aber die Synchronisation mit Bitwardenrs funktioniert noch.

Tip: Man kann in der Browserapp einen Pin-Code erstellen, mit dem man sich einfacher einloggen kann. Und das Häckchen raus bei „Bei Neustart des Browsers mit Master-Passwort sperren“. Dieser Pin gilt aber nur für die Browser-App und nicht für das Login auf der Website.

Automatisches Update aller Docker, die mit Compose erstellt wurden:

Wie aktualisiert man jetzt die Docker? Ich verwende dafür ein kleines Script. Aber bedenkt, dass ALLE Docker, von denen sich in Dockervolumes die Scripte befinden, geupdated und gestartet werden, auch wenn diese nicht relevant sind. Soll heissen, dass die Compose-Files von Dockern, die keine Verwendung mehr haben oder momentan nicht benötigt werden, nicht im Verzeichnis /home/dockervolumes sein sollten.

cd /usr/local/bin && sudo nano mydockerupdatescript
#!/bin/bash
# Automatisches Update ALLER Docker in /home/dockervolumes/*
# Ablageverzeichnis: /usr/local/bin/mydockerupdatescript
# Angabe Hauptverzeichnis
  
# Datenbank stoppen (wird nicht benötigt, da keine interne Datenbanken vorhanden)
##cd /home/dockervolumes/mariadb
##sudo docker-compose stop
# Datenbank gestoppt (wird automatisch wieder gestartet)

# Systemupdate
sudo apt update && sudo apt upgrade -y
  
cd /home/dockervolumes
   
readarray -d '' composeConfigs < <(find . -type f -name docker-compose.y* -print0)
   
for cfg in "${composeConfigs[@]}"; do
  docker-compose -f "$cfg" pull
  docker-compose -f "$cfg" up -d
done
   
# Alte Images automatisch löschen
docker image prune -f

Strg-x, y, Enter

Zum Aufruf des Scriptes folgenden Befehl eingeben:

sudo bash mydockerupdatescript

Entfernt man bei den beiden Befehlen mit ## davor die ##, wird die Datenbank vor der Überprüfung der Docker gestoppt. Anschließend wird diese automatisch wieder gestartet. Dies dient zur Sicherheit, um einen Crash oder Datenverlust vorzubeugen, falls bei der Aktualisierung im selben Moment darauf geschrieben werden sollte. Da ich keine Datenbank in meiner VM verwende, erübrigt sich das.

Möchte man dieses Script täglich durchlaufen lassen, dann hilft folgendes:

sudo crontab -e 

Falls noch nicht geschehen, den Editor wählen. Ich verwende die 1 (nano). Folgendes am Ende der Datei einfügen (das Hashtag am Ende nicht vergessen):

0 2 * * * sudo bash mydockerupdatescript
#

STGR-x, y, Enter

Jetzt wird täglich 02:00 Uhr geschaut, ob ein Update des Dockers verfügbar ist und gegebenenfalls geupdated.

Möchte man nur einmal pro Woche updaten, z.B Montag 05:00 Uhr, dann:

0 5 * * 1 sudo bash mydockerupdatescript
#

STGR-x, y, Enter

Oder nur einmal im Monat, z.B. am 01. jeden Monats um 05:00 Uhr:

0 5 * 1 * sudo bash mydockerupdatescript
#

STGR-x, y, Enter

Ganz gut beschrieben wird das auf https://wiki.ubuntuusers.de/Cron/

.

Wenn alles erledigt, starte ich die VM einmal neu.

sudo reboot

Backup der VM in Unraid:

Dafür verwende ich das Tool VM-Backup. Hier gibt’s den Guide dazu.

Einrichtung von WordPress-Multisite

Zuerst erstelle ich ein Backup meiner schon erstellten Site. Dafür verwende ich die WordPress-Plugins „Jetpack“ und „UdraftPlus“. Doppelt hält besser. Was ich später erst checkte, dass diese Plugins für Multisite in der kostenlosen Variante nicht geeignet sind. Aber das Backup ist nur, falls etwas schiefgeht und ich meinen Docker neu aufsetzen muss. Man muss bedenken, dass es, einmal auf Multisite umgestellt, kein zurück mehr gibt. Möchte man das doch nicht, hilft nur noch eine Neuinstallation.

Ich setzte mir persönlich die Aufgabe, meine 3 Wodpress-Sites (Openmediavault, Proxmox und Unraid) in nur einer Instanz von WordPress zu packen. Mit den Menu’s, egal wie ich es gestaltete, kam ich nicht weiter. Also musste eine kleine Änderung der WordPress-Installation sein. Zuerst installierte ich WordPress, so wie man es kennt. Anschließend änderte ich die wp-config.php folgermaßen ab:

nano /var/lib/Wordpress_1/wp-config.php

Dann fügte ich die Zeile 2 nach der WP_Debug-Zeile hinzu:

define( 'WP_DEBUG', false );
define( 'WP_ALLOW_MULTISITE', true );

STRG-X, Y, Enter

Wenn erledigt, das WordPress öffnen, als Admin einloggen, das Dashboard aufrufen.

Jetzt vorübergehend alle Plugins deaktivieren. Dann auf „Werkzeuge“ und auf „Netzwerkeinrichtung“.

Nun hätte man 2 Möglichkeiten um ein Netzwerk der WordPress-Site einzurichten. Subdomains oder Unterverzeichnisse.

Bsp. Subdomain: proxmox.wordpress.sytes.net

Bsp. Unterverzeichnis: wordpress.sytes.net/proxmox

Subdomain funktioniert leider mit der Traefik-Konfiguration, wie ich sie erstellte, nicht. Zur Info: NoIP-User haben vornherein in der Kostenlosen Version das Nachsehen. Dort funktioniert es gar nicht. Ohne um den heißen Brei herum zu reden, wähle ich als Option „Unterverzeichnis“

Also wähle ich Unterverzeichnisse, vergebe einen Netzwerktitel und eine E-Mail-Adresse (ich lasse die Voreinstellung drin). Dann „Installieren“.

Jetzt wird erklärt, was man noch verändern muss. Einfach alles abarbeiten. Da WordPress nicht unterscheidet, ob es eine Dockeranwendung ist oder eine Festinstallation, muss ich noch erwähnen, dass der Pfad /var/www/html für unsere Dockeranwendung nicht funktioniert. Bei der .htaccess sei noch erwähnt, dass man die Datei vorher sichern sollte und eine neue .htaccess verwendet.

Sicherung der -htaccess-Datei:

mv /var/lib/Wordpress_1/.htaccess /var/lib/Wordpress_1/htaccess.bak

Änderung der wp-config:

nano /var/lib/Wordpress_1/wp-config.php

STRG-x, y, Enter

Erstellen der neuen .htaccess-Datei:

nano /var/lib/Wordpress_1/.htaccess

STRG-x, y, Enter

Wenn erledigt, kann man ab sofort die Multisite(s) verwenden.

Unter „Meine Websites“ (ganz oben links im Menu) erscheint nun ein neuer Reiter Namens „Netzwerkverwaltung“. Dort auf Websites, kann man nur weitere Hauptseiten erstellen. Einfach auf „Neu hinzufügen“, Seitennamen angeben, Titel der Website und E-Mail benennen. „Website erstellen“

Falls es Login-Probleme gibt oder das Dashboard der neu erstellten Seite lässt sich nicht aufrufen, dann bitte alle Browserfenster schließen und erneut öffnen.

.

.

Quelle(n):

https://projekt-rootserver.de

https://greenitsolutions.at/traefik-docker-lets-encrypt-tutorial/

https://goneuland.de/traefik-v2-reverse-proxy-fuer-docker-unter-debian-10-einrichten/

https://github.com/DoTheEvo/Traefik-v2-examples

https://docs.traefik.io

https://thibmaek.com/post/updating-all-docker-compose-container

https://www.smarthomebeginner.com/traefik-reverse-proxy-tutorial-for-docker

Erstelle eine Website wie diese mit WordPress.com
Jetzt starten