Automatisierung der WordPress-Installation mit NGINX Unit und Ubuntu

Automatisierung der WordPress-Installation mit NGINX Unit und Ubuntu

Es gibt viele Materialien zur Installation von WordPress, eine Google-Suche mit den Stichworten "WordPress installieren" ergibt etwa eine halbe Million Ergebnisse. Dennoch gibt es tatsächlich nur sehr wenige brauchbare Anleitungen, mit denen man WordPress und das zugrunde liegende Betriebssystem so installieren und einrichten kann, dass sie über einen langen Zeitraum funktionsfähig bleiben. Möglicherweise hängen die richtigen Einstellungen stark von den spezifischen Bedürfnissen ab, oder es liegt daran, dass eine detaillierte Erklärung den Artikel schwer lesbar macht.

In diesem Artikel werden wir versuchen, das Beste aus beiden Ansätzen zu kombinieren, indem wir ein Bash-Skript zur automatischen Installation von WordPress auf Ubuntu bereitstellen und es dabei durchgehen, um zu erklären, was jeder Teil tut, sowie welche Kompromisse wir bei der Entwicklung gemacht haben. Wenn Sie ein erfahrener Benutzer sind, können Sie den Text des Artikels überspringen und einfach das Skript zur Modifikation und Nutzung in Ihren Umgebungen übernehmen. Das Skript liefert eine anpassbare WordPress-Installation mit Unterstützung für Let's Encrypt, die auf NGINX Unit läuft und für den industriellen Einsatz geeignet ist.

Die entwickelte Architektur zur Bereitstellung von WordPress mit NGINX Unit ist in einem älteren Artikelbeschrieben, wir werden jetzt auch zusätzliche Einstellungen vornehmen, die dort nicht behandelt wurden (wie in vielen anderen Anleitungen):

  • WordPress CLI
  • Let's Encrypt und TLSSSL-Zertifikate
  • Automatische Zertifikatserneuerung
  • NGINX-Caching
  • NGINX-Kompression
  • Unterstützung für HTTPS und HTTP/2
  • Automatisierung des Prozesses

Im Artikel wird die Installation auf einem einzelnen Server beschrieben, auf dem gleichzeitig ein statischer Server, ein PHP-Server und eine Datenbank gehostet werden. Eine Installation mit Unterstützung für mehrere virtuelle Hosts und Dienste ist ein potenzielles Thema für die Zukunft. Wenn Sie möchten, dass wir über etwas schreiben, was in diesen Artikeln nicht enthalten ist, schreiben Sie uns in die Kommentare.

Anforderungen

  • Server-Container (LXC oder LXD), virtuelle Maschine oder gewöhnlicher physischer Server mit mindestens 512 MB RAM und installiertem Ubuntu 18.04 oder neuer.
  • Öffentliche Ports 80 und 443
  • Domainname, der mit der öffentlichen IP-Adresse dieses Servers verknüpft ist
  • Zugriff mit Root-Rechten (sudo).

Architekturübersicht

Die Architektur ist dieselbe wie beschrieben. zuvor, eine dreischichtige Webanwendung. Sie besteht aus PHP-Skripten, die von einem PHP-Handler ausgeführt werden, und statischen Dateien, die vom Webserver verarbeitet werden.

Automatisierung der WordPress-Installation mit NGINX Unit und Ubuntu

Allgemeine Prinzipien

  • Viele Befehle zur Konfiguration im Skript sind in Bedingungen (if) eingewickelt, um Idempotenz zu gewährleisten: Das Skript kann mehrmals ausgeführt werden, ohne dass das Risiko besteht, bereits bestätigte Einstellungen zu ändern.
  • Das Skript versucht, Software aus Repositories zu installieren, sodass Sie Systemupdates mit einem Befehl anwenden können (apt upgrade für Ubuntu).
  • Die Befehle versuchen zu erkennen, ob sie in einem Container ausgeführt werden, um ihre Einstellungen entsprechend anzupassen.
  • Um die Anzahl der gestarteten Prozesse in den Einstellungen festzulegen, versucht das Skript, automatisierte Anpassungsparameter für den Betrieb in Containern, virtuellen Maschinen und physischen Servern zu erraten.
  • Bei der Beschreibung der Einstellungen denken wir immer zuerst an die Automatisierung, die hoffentlich die Grundlage zur Erstellung Ihrer eigenen Infrastruktur als Code wird.
  • Alle Befehle werden als Benutzer rootausgeführt, da sie die grundlegenden Systemeinstellungen ändern, aber WordPress selbst läuft unter einem normalen Benutzerkonto.

Umgebungsvariablen setzen

Setzen Sie die folgenden Umgebungsvariablen, bevor Sie das Skript ausführen:

  • WORDPRESS_DB_PASSWORD — Passwort für die WordPress-Datenbank
  • WORDPRESS_ADMIN_USER — Administratorname für WordPress
  • WORDPRESS_ADMIN_PASSWORD — Passwort für den WordPress-Administrator
  • WORDPRESS_ADMIN_EMAIL — E-Mail des WordPress-Administrators
  • WORDPRESS_URL — vollständige URL der WordPress-Website, beginnend mit https://.
  • LETS_ENCRYPT_STAGING — standardmäßig leer, aber wenn der Wert auf 1 gesetzt wird, verwenden Sie die Staging-Server von Let’s Encrypt, die für häufige Anfragen nach Zertifikaten während der Tests Ihrer Einstellungen erforderlich sind, andernfalls kann Let’s Encrypt Ihre IP-Adresse vorübergehend aufgrund der hohen Anzahl von Anfragen sperren.

Das Skript überprüft, ob diese mit WordPress verbundenen Variablen gesetzt sind, und beendet die Ausführung, wenn dies nicht der Fall ist.
Die Zeilen 572-576 des Skripts überprüfen den Wert LETS_ENCRYPT_STAGING.

Setzen von abgeleiteten Umgebungsvariablen

Das Skript setzt in den Zeilen 55-61 die folgenden Umgebungsvariablen, entweder auf einen festen Wert oder mithilfe eines Werts, der aus den im vorherigen Abschnitt gesetzten Variablen stammt:

  • DEBIAN_FRONTEND="noninteractive" — informiert die Anwendungen, dass sie in einem Skript ausgeführt werden und keine Möglichkeit zur Interaktion mit dem Benutzer besteht.
  • WORDPRESS_CLI_VERSION="2.4.0" — Version der WordPress CLI-Anwendung.
  • WORDPRESS_CLI_MD5= "dedd5a662b80cda66e9e25d44c23b25c" — Prüfziffer der ausführbaren Datei WordPress CLI 2.4.0 (die Version wird in der Variable angegeben, WORDPRESS_CLI_VERSION). Das Skript in Zeile 162 verwendet diesen Wert zur Überprüfung, dass die korrekte Datei der WordPress CLI heruntergeladen wurde.
  • UPLOAD_MAX_FILESIZE="16M" — maximale Dateigröße, die in WordPress hochgeladen werden kann. Diese Einstellung wird an mehreren Stellen verwendet, sodass es einfacher ist, sie an einem Ort festzulegen.
  • TLS_HOSTNAME= "$(echo ${WORDPRESS_URL} | cut -d'\/ -f3)" — Hostname des Systems, der aus der Variablen WORDPRESS_URL extrahiert wird. Wird verwendet, um die entsprechenden TLS/SSL-Zertifikate von Let’s Encrypt zu erhalten, sowie für interne Überprüfungen von WordPress.
  • NGINX_CONF_DIR="\/etc\/nginx" — Pfad zum Verzeichnis mit den NGINX-Einstellungen, einschließlich der Hauptdatei nginx.conf.
  • CERT_DIR="\/etc\/letsencrypt\/live\/${TLS_HOSTNAME}" — Pfad zu den Let’s Encrypt-Zertifikaten für die WordPress-Website, abgeleitet aus der Variablen TLS_HOSTNAME.

Zuweisung des Hostnamens zum WordPress-Server

Das Skript weist dem Server einen Hostnamen zu, sodass der Wert dem Domainnamen der Website entspricht. Dies ist nicht zwingend erforderlich, erleichtert jedoch den Versand von ausgehenden E-Mails über SMTP, wenn ein einzelner Server eingerichtet wird, wie es im Skript konfiguriert ist.

Skriptcode

# Change the hostname to be the same as the WordPress hostname
if [ ! "$(hostname)" == "${TLS_HOSTNAME}" ]; then
  echo " Changing hostname to ${TLS_HOSTNAME}"
  hostnamectl set-hostname "${TLS_HOSTNAME}"
fi

Hinzufügen des Hostnamens zu /etc/hosts

Ergänzung WP‑Cron wird verwendet, um periodische Aufgaben auszuführen und erfordert, dass WordPress über HTTP auf sich selbst zugreifen kann. Um sicherzustellen, dass WP-Cron in allen Umgebungen korrekt funktioniert, fügt das Skript eine Zeile in die Datei ein, /etc/hosts, sodass WordPress über das Loopback-Interface auf sich selbst zugreifen kann:

Skriptcode

# Add the hostname to /etc/hosts
if [ "$(grep -m1 "${TLS_HOSTNAME}" /etc/hosts)" = "" ]; then
  echo " Adding hostname ${TLS_HOSTNAME} to /etc/hosts so that WordPress can ping itself"
  printf "::1 %sn127.0.0.1 %sn" "${TLS_HOSTNAME}" "${TLS_HOSTNAME}" >> /etc/hosts
fi

Installation der für die nächsten Schritte erforderlichen Werkzeuge

Der verbleibende Teil des Skripts benötigt einige Programme und setzt voraus, dass die Repositories aktuell sind. Wir aktualisieren die Liste der Repositories, bevor wir die benötigten Werkzeuge installieren:

Skriptcode

# Make sure tools needed for install are present
echo " Installing prerequisite tools"
apt-get -qq update
apt-get -qq install -y 
  bc 
  ca-certificates 
  coreutils 
  curl 
  gnupg2 
  lsb-release

Hinzufügen der NGINX Unit- und NGINX-Repositories

Das Skript installiert die Open-Source-Versionen von NGINX Unit und NGINX aus den offiziellen NGINX-Repositories, um sicherzustellen, dass die Versionen mit den neuesten Sicherheitsupdates und Fehlerbehebungen verwendet werden.

Das Skript fügt das Repository von NGINX Unit hinzu und anschließend das Repository von NGINX, indem es die Repository-Schlüssel und die Konfigurationsdateien hinzufügt, apt, die den Zugriff auf die Repositories über das Internet festlegen.

Die Installation von NGINX Unit und NGINX erfolgt im folgenden Abschnitt. Wir fügen zunächst die Repositories hinzu, um die Metadaten nicht mehrfach aktualisieren zu müssen, was die Installation beschleunigt.

Skriptcode

# Install the NGINX Unit repository
if [ ! -f /etc/apt/sources.list.d/unit.list ]; then
  echo " Installing NGINX Unit repository"
  curl -fsSL https://nginx.org/keys/nginx_signing.key | apt-key add -
  echo "deb https://packages.nginx.org/unit/ubuntu/ $(lsb_release -cs) unit" > /etc/apt/sources.list.d/unit.list
fi

# Install the NGINX repository
if [ ! -f /etc/apt/sources.list.d/nginx.list ]; then
  echo " Installing NGINX repository"
  curl -fsSL https://nginx.org/keys/nginx_signing.key | apt-key add -
  echo "deb https://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" > /etc/apt/sources.list.d/nginx.list
fi

Installation von NGINX, NGINX Unit, PHP MariaDB, Certbot (Let’s Encrypt) und deren Abhängigkeiten

Sobald alle Repositories hinzugefügt sind, aktualisieren wir die Metadaten und installieren die Anwendungen. Die durch das Skript installierten Pakete umfassen ebenfalls die PHP-Erweiterungen, die beim Start von WordPress.org empfohlen werden.

Skriptcode

echo "Aktualisiere die Repository-Metadaten"
apt-get -qq update

# Installiere PHP mit Abhängigkeiten und NGINX Unit
echo "Installiere PHP, NGINX Unit, NGINX, Certbot und MariaDB"
apt-get -qq install -y --no-install-recommends 
  certbot 
  python3-certbot-nginx 
  php-cli 
  php-common 
  php-bcmath 
  php-curl 
  php-gd 
  php-imagick 
  php-mbstring 
  php-mysql 
  php-opcache 
  php-xml 
  php-zip 
  ghostscript 
  nginx 
  unit 
  unit-php 
  mariadb-server

PHP für die Verwendung mit NGINX Unit und WordPress konfigurieren

Das Skript erstellt eine Konfigurationsdatei im Verzeichnis conf.d. Hier wird die maximale Größe der hochgeladenen Dateien für PHP festgelegt, die PHP-Fehlerausgabe auf STDERR aktiviert, so dass sie in das NGINX Unit-Log geschrieben wird, und NGINX Unit wird neu gestartet.

Skriptcode

# Find the major and minor PHP version so that we can write to its conf.d directory
PHP_MAJOR_MINOR_VERSION="$(php -v | head -n1 | cut -d' ' -f2 | cut -d'.' -f1,2)"

if [ ! -f "/etc/php/${PHP_MAJOR_MINOR_VERSION}/embed/conf.d/30-wordpress-overrides.ini" ]; then
  echo " Configuring PHP for use with NGINX Unit and WordPress"
  # Add PHP configuration overrides
  cat > "/etc/php/${PHP_MAJOR_MINOR_VERSION}/embed/conf.d/30-wordpress-overrides.ini" << EOM
; Set a larger maximum upload size so that WordPress can handle
; bigger media files.
upload_max_filesize=${UPLOAD_MAX_FILESIZE}
post_max_size=${UPLOAD_MAX_FILESIZE}
; Write error log to STDERR so that error messages show up in the NGINX Unit log
error_log=/dev/stderr
EOM
fi

# Restart NGINX Unit because we have reconfigured PHP
echo " Restarting NGINX Unit"
service unit restart

Datenbankeinstellungen von MariaDB für WordPress festlegen

Wir haben MariaDB anstelle von MySQL gewählt, da sie eine aktivere Community hat und möglicherweise eine höhere Leistung standardmäßig bietet (wahrscheinlich ist es hier einfacher: Um MySQL zu installieren, muss man ein weiteres Repository hinzufügen, Anm. des Übersetzers).

Das Skript erstellt eine neue Datenbank und legt Anmeldedaten für den Zugriff auf WordPress über die Loopback-Schnittstelle fest:

Skriptcode

# Set up the WordPress database
echo " Configuring MariaDB for WordPress"
mysqladmin create wordpress || echo "Ignoring above error because database may already exist"
mysql -e "GRANT ALL PRIVILEGES ON wordpress.* TO "wordpress"@"localhost" IDENTIFIED BY "$WORDPRESS_DB_PASSWORD"; FLUSH PRIVILEGES;"

WordPress CLI installieren

In diesem Schritt installiert das Skript das Programm WP-CLI. Mit diesem Tool kann man WordPress konfigurieren und verwalten, ohne Dateien manuell bearbeiten, die Datenbank aktualisieren oder sich im Admin-Bereich anmelden zu müssen. Es ermöglicht auch die Installation von Themes und Plugins sowie die Durchführung von Updates für WordPress.

Skriptcode

if [ ! -f /usr/local/bin/wp ]; then
  # Installiere das WordPress CLI
  echo "Installiere das WordPress CLI-Tool"
  curl --retry 6 -Ls "https://github.com/wp-cli/wp-cli/releases/download/v${WORDPRESS_CLI_VERSION}/wp-cli-${WORDPRESS_CLI_VERSION}.phar" > /usr/local/bin/wp
  echo "$WORDPRESS_CLI_MD5 /usr/local/bin/wp" | md5sum -c -
  chmod +x /usr/local/bin/wp
fi

Installation und Konfiguration von WordPress

Das Skript installiert die neueste Version von WordPress im Verzeichnis /var/www/wordpress, und ändert die Einstellungen:

  • Die Verbindung zur Datenbank erfolgt über einen Unix-Domain-Socket anstelle von TCP über Loopback, um den TCP-Datenverkehr zu reduzieren.
  • WordPress fügt ein Präfix hinzu https:// zur URL, wenn Kunden sich über das HTTPS-Protokoll mit NGINX verbinden, und sendet auch den entfernten Hostnamen (wie von NGINX bereitgestellt) an PHP. Wir verwenden einen Code-Schnipsel, um dies einzurichten.
  • WordPress benötigt HTTPS für den Login
  • Die URL-Struktur basiert standardmäßig auf Ressourcen
  • Die richtigen Berechtigungen werden im Dateisystem für das WordPress-Verzeichnis festgelegt.

Skriptcode

if [ ! -d /var/www/wordpress ]; then
  # Erstelle WordPress-Verzeichnisse
  mkdir -p /var/www/wordpress
  chown -R www-data:www-data /var/www

  # Lade WordPress über das WordPress CLI herunter
  echo " WordPress wird installiert"
  su -s /bin/sh -c 'wp --path=/var/www/wordpress core download' www-data

  WP_CONFIG_CREATE_CMD="wp --path=/var/www/wordpress config create --extra-php --dbname=wordpress --dbuser=wordpress --dbhost="localhost:/var/run/mysqld/mysqld.sock" --dbpass="${WORDPRESS_DB_PASSWORD}""

  # Dieser Schnipsel wird in die wp-config.php-Datei eingefügt, wenn sie erstellt wird;
  # er informiert WordPress, dass wir hinter einem Reverse-Proxy stehen, und ermöglicht es somit
  # Links über HTTPS zu generieren
  cat > /tmp/wp_forwarded_for.php << 'EOM'
/* Aktiviere HTTPS 'ein', wenn HTTP_X_FORWARDED_PROTO 'https' entspricht */
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
    $_SERVER['HTTPS'] = 'on';
}
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}
EOM

  # Erstelle die WordPress-Konfiguration
  su -s /bin/sh -p -c "cat /tmp/wp_forwarded_for.php | ${WP_CONFIG_CREATE_CMD}" www-data
  rm /tmp/wp_forwarded_for.php
  su -s /bin/sh -p -c "wp --path=/var/www/wordpress config set 'FORCE_SSL_ADMIN' 'true'" www-data

  # Installiere WordPress
  WP_SITE_INSTALL_CMD="wp --path=/var/www/wordpress core install --url="${WORDPRESS_URL}" --title="${WORDPRESS_SITE_TITLE}" --admin_user="${WORDPRESS_ADMIN_USER}" --admin_password="${WORDPRESS_ADMIN_PASSWORD}" --admin_email="${WORDPRESS_ADMIN_EMAIL}" --skip-email"
  su -s /bin/sh -p -c "${WP_SITE_INSTALL_CMD}" www-data

  # Setze die Permalink-Struktur auf eine sinnvolle Voreinstellung, die nicht in der Benutzeroberfläche ist
  su -s /bin/sh -p -c "wp --path=/var/www/wordpress option update permalink_structure '/%year%/%monthnum%/%postname%/'" www-data

  # Entferne die Beispieldatei, da sie überflüssig ist und ein Sicherheitsproblem darstellen könnte
  rm /var/www/wordpress/wp-config-sample.php

  # Stelle sicher, dass die WordPress-Berechtigungen korrekt sind
  find /var/www/wordpress -type d -exec chmod g+s {} ;
  chmod g+w /var/www/wordpress/wp-content
  chmod -R g+w /var/www/wordpress/wp-content/themes
  chmod -R g+w /var/www/wordpress/wp-content/plugins
fi

NGINX Unit konfigurieren

Das Skript konfiguriert NGINX Unit, um PHP auszuführen und WordPress-Pfade zu verarbeiten, indem es den Namensraum der PHP-Prozesse isoliert und die Leistungseinstellungen optimiert. Hier gibt es drei Funktionen, auf die man achten sollte:

  • Die Unterstützung von Namensräumen wird bedingt durch die Überprüfung, ob das Skript im Container ausgeführt wird. Dies ist notwendig, da die meisten Container-Konfigurationen keinen verschachtelten Containerbetrieb unterstützen.
  • Wenn Namensraumunterstützung vorhanden ist, wird der Namensraum deaktiviert Netzwerk. Dies ist notwendig, um WordPress zu ermöglichen, gleichzeitig eine Verbindung zu Endpunkten herzustellen und im Internet verfügbar zu sein.
  • Die maximale Anzahl an Prozessen wird wie folgt bestimmt: (Verfügbare Speicherkapazität für laufende MariaDB und NGINX Uniy)/(RAM-Grenze in PHP + 5)
    Dieser Wert wird in den NGINX Unit-Einstellungen festgelegt.

Dieser Wert impliziert auch, dass immer mindestens zwei PHP-Prozesse ausgeführt werden, was wichtig ist, da WordPress viele asynchrone Anfragen an sich selbst stellt, und ohne zusätzliche Prozesse würde beispielsweise WP-Cron nicht funktionieren. Möglicherweise möchten Sie diese Grenzen erhöhen oder verringern, basierend auf Ihren lokalen Einstellungen, da die hier festgelegten Werte konservativ sind. Bei den meisten Produktionssystemen liegen die Einstellungen zwischen 10 und 100.

Skriptcode

if [ "${container:-unknown}" != "lxc" ] && [ "$(grep -m1 -a container=lxc /proc/1/environ | tr -d ' ')" == "" ]; then
  NAMESPACES='"namespaces": {
        "cgroup": true,
        "credential": true,
        "mount": true,
        "network": false,
        "pid": true,
        "uname": true
    }'
else
  NAMESPACES='"namespaces": {}'
fi

PHP_MEM_LIMIT="$(grep 'memory_limit' /etc/php/7.4/embed/php.ini | tr -d ' ' | cut -f2 -d= | numfmt --from=iec)"
AVAIL_MEM="$(grep MemAvailable /proc/meminfo | tr -d ' kB' | cut -f2 -d: | numfmt --from-unit=K)"
MAX_PHP_PROCESSES="$(echo "${AVAIL_MEM}/${PHP_MEM_LIMIT}+5" | bc)"
echo " Die maximale Anzahl an PHP-Prozessen wurde auf ${MAX_PHP_PROCESSES} berechnet. Sie möchten diesen Wert möglicherweise anpassen, da er von Ihrer Konfiguration abhängt. Werte zwischen 10 und 100 sind in Produktionskonfigurationen nicht ungewöhnlich."

echo " NGINX Unit zur Verwendung von PHP und WordPress konfigurieren"
cat > /tmp/wordpress.json << EOM
{
  "settings": {
    "http": {
      "header_read_timeout": 30,
      "body_read_timeout": 30,
      "send_timeout": 30,
      "idle_timeout": 180,
      "max_body_size": $(numfmt --from=iec ${UPLOAD_MAX_FILESIZE})
    }
  },
  "listeners": {
    "127.0.0.1:8080": {
      "pass": "routes/wordpress"
    }
  },
  "routes": {
    "wordpress": [
      {
        "match": {
          "uri": [
            "*.php",
            "*.php/*",
            "/wp-admin/"
          ]
        },
        "action": {
          "pass": "applications/wordpress/direct"
        }
      },
      {
        "action": {
          "share": "/var/www/wordpress",
          "fallback": {
            "pass": "applications/wordpress/index"
          }
        }
      }
    ]
  },
  "applications": {
    "wordpress": {
      "type": "php",
      "user": "www-data",
      "group": "www-data",
      "processes": {
        "max": ${MAX_PHP_PROCESSES},
        "spare": 1
      },
      "isolation": {
        ${NAMESPACES}
      },
      "targets": {
        "direct": {
          "root": "/var/www/wordpress/"
        },
        "index": {
          "root": "/var/www/wordpress/",
          "script": "index.php"
        }
      }
    }
  }
}
EOM

curl -X PUT --data-binary @/tmp/wordpress.json --unix-socket /run/control.unit.sock http://localhost/config

NGINX-Konfiguration

Konfiguration der grundlegenden NGINX-Einstellungen

Das Skript erstellt ein Verzeichnis für den NGINX-Cache und dann die Hauptkonfigurationsdatei. nginx.conf. Achten Sie auf die Anzahl der Verarbeitungsprozesse und geben Sie die maximale Dateigröße für den Upload an. Es gibt auch eine Zeile, in der die Konfigurationsdatei für die Kompression verbunden wird, die im nächsten Abschnitt definiert wird, danach folgen die Cache-Einstellungen.

Skriptcode

# Make directory for NGINX cache
mkdir -p /var/cache/nginx/proxy

echo " Configuring NGINX"
cat > ${NGINX_CONF_DIR}/nginx.conf << EOM
user nginx;
worker_processes auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       ${NGINX_CONF_DIR}/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    client_max_body_size ${UPLOAD_MAX_FILESIZE};
    keepalive_timeout  65;
    # gzip settings
    include ${NGINX_CONF_DIR}/gzip_compression.conf;
    # Cache settings
    proxy_cache_path /var/cache/nginx/proxy
        levels=1:2
        keys_zone=wp_cache:10m
        max_size=10g
        inactive=60m
        use_temp_path=off;
    include ${NGINX_CONF_DIR}/conf.d/*.conf;
}
EOM

NGINX Komprimierungseinstellungen

Die Kompression von Inhalten in Echtzeit, bevor sie an die Kunden gesendet werden, ist eine ausgezeichnete Möglichkeit, die Leistung der Website zu verbessern, aber nur, wenn die Kompression richtig konfiguriert ist. Dieser Abschnitt des Scripts basiert auf den Einstellungen von hier.

Skriptcode

cat > ${NGINX_CONF_DIR}\/gzip_compression.conf << 'EOM'
# Credit: https://github.com/h5bp/server-configs-nginx/
# ----------------------------------------------------------------------
# | Kompression                                                      |
# ----------------------------------------------------------------------
# https://nginx.org/en/docs/http/ngx_http_gzip_module.html
# Aktivieren Sie die Gzip-Kompression.
# Standard: aus
gzip on;
# Kompressionsstufe (1-9).
# 5 ist ein perfekter Kompromiss zwischen Größe und CPU-Nutzung und bietet bei den meisten ASCII-Dateien eine Reduktion von etwa 75%
# (fast identisch mit Stufe 9).
# Standard: 1
gzip_comp_level 6;
# Nichts komprimieren, was bereits klein ist und kaum schrumpft
# (der Standardwert beträgt 20 Bytes, was schlecht ist, da dies normalerweise zu größeren
# Dateien nach dem Gzippen führt).
# Standard: 20
gzip_min_length 256;
# Daten auch für Clients komprimieren, die über Proxys zu uns verbinden,
# identifiziert durch den "Via"-Header (erforderlich für CloudFront).
# Standard: aus
gzip_proxied any;
# Proxys mitteilen, sowohl die gzippte als auch die normale Version einer Ressource zwischenzuspeichern,
# wann immer der Accept-Encoding-Kapazitätenheader des Clients variiert;
# Vermeidet das Problem, bei dem ein nicht gzip-fähiger Client (was heutzutage sehr selten ist)
# Kauderwelsch anzeigen würde, wenn ihr Proxy ihnen die gzippte Version lieferte.
# Standard: aus
gzip_vary on;
# Alle Ausgaben komprimieren, die mit einem der folgenden MIME-Typen gekennzeichnet sind.
# `text\/html` wird immer vom Gzip-Modul komprimiert.
# Standard: text\/html
gzip_types
  application\/atom+xml
  application\/geo+json
  application\/javascript
  application\/x-javascript
  application\/json
  application\/ld+json
  application\/manifest+json
  application\/rdf+xml
  application\/rss+xml
  application\/vnd.ms-fontobject
  application\/wasm
  application\/x-web-app-manifest+json
  application\/xhtml+xml
  application\/xml
  font\/eot
  font\/otf
  font\/ttf
  image\/bmp
  image\/svg+xml
  text\/cache-manifest
  text\/calendar
  text\/css
  text\/javascript
  text\/markdown
  text\/plain
  text\/xml
  text\/vcard
  text\/vnd.rim.location.xloc
  text\/vtt
  text\/x-component
  text\/x-cross-domain-policy;
EOM

NGINX Einstellungen für WordPress

Im Folgenden erstellt das Skript eine Konfigurationsdatei für WordPress default.conf im Verzeichnis conf.d. Hier wird konfiguriert:

  • Aktivierung von TLS-Zertifikaten, die von Let's Encrypt über Certbot erhalten wurden (dessen Einstellungen im nächsten Abschnitt folgen werden)
  • Einstellung der TLS-Sicherheitsparameter basierend auf den Empfehlungen von Let's Encrypt
  • Standardmäßige Konfiguration der Caching für übersprungene Anfragen für 1 Stunde
  • Deaktivierung des Zugriffsprotokolls sowie der Fehlerprotokollierung, wenn die Datei nicht gefunden wird, für zwei häufig angeforderte Dateien: favicon.ico und robots.txt
  • Zugriff auf versteckte Dateien und einige Dateien verbieten .php, um unbefugten Zugriff oder unbeabsichtigtes Auslösen zu verhindern
  • Deaktivierung des Zugriffsprotokolls für statische Inhalte und Schriftdateien
  • Festlegung des Headers Access-Control-Allow-Origin für Schriftdateien
  • Hinzufügen von Routen für index.php und andere statische Inhalte.

Skriptcode

cat > ${NGINX_CONF_DIR}\/conf.d\/default.conf << EOM
upstream unit_php_upstream {
    server 127.0.0.1:8080;
    keepalive 32;
}
server {
    listen 80;
    listen [::]:80;
    # ACME-Challenge, die von Certbot für Let's Encrypt verwendet wird
    location ^~ \/.well-known\/acme-challenge\/ {
      root \/var\/www\/certbot;
    }
    location \/ {
      return 301 https:\/${TLS_HOSTNAME}$request_uri;
    }
}
server {
    listen      443 ssl http2;
    listen [::]:443 ssl http2;
    server_name ${TLS_HOSTNAME};
    root        \/var\/www\/wordpress\/;
    # Let's Encrypt-Konfiguration
    ssl_certificate         ${CERT_DIR}\/fullchain.pem;
    ssl_certificate_key     ${CERT_DIR}\/privkey.pem;
    ssl_trusted_certificate ${CERT_DIR}\/chain.pem;
    include ${NGINX_CONF_DIR}\/options-ssl-nginx.conf;
    ssl_dhparam ${NGINX_CONF_DIR}\/ssl-dhparams.pem;
    # OCSP-Stapeln
    ssl_stapling on;
    ssl_stapling_verify on;
    # Proxy-Cache
    proxy_cache wp_cache;
    proxy_cache_valid 200 302 1h;
    proxy_cache_valid 404 1m;
    proxy_cache_revalidate on;
    proxy_cache_background_update on;
    proxy_cache_lock on;
    proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
    location = \/favicon.ico {
        log_not_found off;
        access_log off;
    }
    location = \/robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    # Alle Versuche, auf versteckte Dateien wie .htaccess, .htpasswd,
    # .DS_Store (Mac) zuzugreifen, verweigern
    # Protokollieren Sie die Anforderungen, um sie später zu analysieren (oder an Firewall-Tools
    # wie fail2ban weiterzugeben)
    location ~ \/. {
        deny all;
    }
    # Verweigern Sie den Zugriff auf Dateien mit der Erweiterung .php im Uploads-Verzeichnis;
    # funktioniert in Unterverzeichnisinstallationen und auch in Multi-Site-Netzwerken.
    location ~* \/(?:uploads|files)\/.php$ {
        deny all;
    }
    # WordPress: Zugriff auf wp-content, wp-includes PHP-Dateien verweigern
    location ~* ^\/(?:wp-content|wp-includes)\/.php$ {
        deny all;
    }
    # Verweigern Sie den öffentlichen Zugriff auf wp-config.php
    location ~* wp-config.php {
        deny all;
    }
    # Protokollieren Sie keinen Zugriff auf statische Assets, Medien
    location ~* .(?:css(.map)?|js(.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
        access_log off;
    }
    location ~* .(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
        add_header Access-Control-Allow-Origin "*";
        access_log off;
    }
    location \/ {
        try_files $uri @index_php;
    }
    location @index_php {
        proxy_socket_keepalive on;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
        proxy_pass       http:\/\/unit_php_upstream;
    }
    location ~* .php$ {
        proxy_socket_keepalive on;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
        try_files        $uri =404;
        proxy_pass       http:\/\/unit_php_upstream;
    }
}
EOM

Einrichtung von Certbot für Zertifikate von Let’s Encrypt und deren automatische Verlängerung

Certbot — ein kostenloses Werkzeug der Electronic Frontier Foundation (EFF), mit dem man TLS-Zertifikate von Let’s Encrypt erhalten und automatisch aktualisieren kann. Das Skript führt die folgenden Schritte aus, um Certbot für die Verarbeitung von Zertifikaten von Let’s Encrypt in NGINX einzurichten:

  • Stoppt NGINX
  • Lädt empfohlene TLS-Einstellungen herunter
  • Startet Certbot, um Zertifikate für die Website zu erhalten
  • Startet NGINX neu, um die Zertifikate zu verwenden
  • Richtet die tägliche Ausführung von Certbot um 3:24 Uhr ein, um die Notwendigkeit zur Aktualisierung von Zertifikaten zu überprüfen und, falls nötig, neue Zertifikate herunterzuladen und NGINX neu zu starten.

Skriptcode

echo " Stoppen von NGINX, um Let's Encrypt einzurichten"
service nginx stop

mkdir -p /var/www/certbot
chown www-data:www-data /var/www/certbot
chmod g+s /var/www/certbot

if [ ! -f ${NGINX_CONF_DIR}/options-ssl-nginx.conf ]; then
  echo " Herunterladen der empfohlenen TLS-Einstellungen"
  curl --retry 6 -Ls -z "Tue, 14 Apr 2020 16:36:07 GMT" 
    -o "${NGINX_CONF_DIR}/options-ssl-nginx.conf" 
    "https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf" 
    || echo "Konnte die neueste options-ssl-nginx.conf nicht herunterladen"
fi

if [ ! -f ${NGINX_CONF_DIR}/ssl-dhparams.pem ]; then
  echo " Herunterladen der empfohlenen TLS-DH-Einstellungen"
  curl --retry 6 -Ls -z "Tue, 14 Apr 2020 16:49:18 GMT" 
    -o "${NGINX_CONF_DIR}/ssl-dhparams.pem" 
    "https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem" 
    || echo "Konnte die neueste ssl-dhparams.pem nicht herunterladen"
fi

# Wenn tls_certs_init.sh zuvor nicht ausgeführt wurde, entfernen Sie die selbstsignierten Zertifikate
if [ ! -d "/etc/letsencrypt/accounts" ]; then
  echo " Entfernen der selbstsignierten Zertifikate"
  rm -rf "${CERT_DIR}"
fi

if [ "" = "${LETS_ENCRYPT_STAGING:-}" ] || [ "0" = "${LETS_ENCRYPT_STAGING}" ]; then
  CERTBOT_STAGING_FLAG=""
else
  CERTBOT_STAGING_FLAG="--staging"
fi

if [ ! -f "${CERT_DIR}/fullchain.pem" ]; then
  echo " Generieren von Zertifikaten mit Let's Encrypt"
  certbot certonly --standalone 
         -m "${WORDPRESS_ADMIN_EMAIL}" 
         ${CERTBOT_STAGING_FLAG} 
         --agree-tos --force-renewal --non-interactive 
         -d "${TLS_HOSTNAME}"
fi

echo " Starte NGINX, um die neue Konfiguration zu verwenden"
service nginx start

# Schreibe crontab für die regelmäßige Erneuerung von Let's Encrypt-Zertifikaten
if [ "$(crontab -l | grep -m1 'certbot renew')" == "" ]; then
  echo " Füge certbot zu crontab für automatische Let's Encrypt-Erneuerung hinzu"
  (crontab -l 2>/dev/null; echo "24 3 * * * certbot renew --nginx --post-hook 'service nginx reload'") | crontab -
fi

Zusätzliche Konfiguration Ihrer Website

Wir haben oben beschrieben, wie unser Skript NGINX und NGINX Unit für den Betrieb einer betriebsbereiten Website mit aktiviertem TLS SSL konfiguriert. Je nach Ihren Bedürfnissen können Sie darüber hinaus in Zukunft hinzufügen:

  • Unterstützung Brotli, verbesserte Kompression in Echtzeit über HTTPS
  • ModSecurity c Regeln für WordPress, um automatisierte Angriffe auf Ihre Website zu verhindern
  • Backup für WordPress, die Ihnen passend ist
  • Schutz mit AppArmor (unter Ubuntu)
  • Postfix oder msmtp, damit WordPress E-Mails senden kann
  • Prüfungen Ihrer Website, damit Sie verstehen, wie viel Traffic sie verkraften kann

Für noch bessere Website-Leistung empfehlen wir ein Upgrade auf NGINX Plus, unser kommerzielles Produkt auf Unternehmensniveau, basierend auf dem Open-Source-NGINX. Abonnenten erhalten ein dynamisch ladbares Brotli-Modul sowie (gegen Aufpreis) NGINX ModSecurity WAF. Wir bieten auch NGINX App Protect, ein WAF-Modul für NGINX Plus, das auf branchenführender Sicherheitstechnologie von F5 basiert.

N.B. Für die Unterstützung hochbelasteter Websites können Sie sich an Experten wenden Southbridge. Wir sorgen für einen schnellen und zuverlässigen Betrieb Ihrer Website oder Ihres Dienstes unter jeglicher Last.

Quelle: habr.com

Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server 🔥 Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server - ProHoster