Wir automatisieren die Installation von WordPress mit NGINX Unit und Ubuntu.

Wir automatisieren die Installation von WordPress mit NGINX Unit und Ubuntu.

Es gibt eine Vielzahl von Ressourcen zur Installation von WordPress; eine Google-Suche mit den Stichworten "WordPress installieren" liefert etwa eine halbe Million Ergebnisse. Dennoch sind tatsächlich nur wenige davon brauchbare Anleitungen, die es ermöglichen, WordPress und das zugrunde liegende Betriebssystem so einzurichten und zu konfigurieren, dass sie über einen längeren Zeitraum hinweg stabil laufen. Möglicherweise hängen die optimalen Einstellungen stark von den spezifischen Anforderungen ab, oder es liegt daran, dass eine ausführliche 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. Außerdem werden wir das Skript durchgehen und erläutern, was jeder Teil bewirkt, sowie die Kompromisse, die wir bei der Entwicklung eingegangen sind. Wenn Sie ein erfahrener Benutzer sind, können Sie den Text des Artikels überspringen und einfach das Skript entnehmen, um es an Ihre Umgebung anzupassen und zu verwenden. Das Ergebnis des Skripts ist eine anpassbare WordPress-Installation mit Lets Encrypt-Unterstützung, die auf NGINX Unit läuft und für industrielle Anwendungen geeignet ist.

Die entwickelte Architektur für die Bereitstellung von WordPress mit NGINX Unit wird in einem älteren Artikel, jetzt werden wir auch zusätzliche Anpassungen vornehmen, die dort nicht behandelt wurden (wie in vielen anderen Anleitungen):

  • WordPress CLI
  • Let’s Encrypt und TLSSSL-Zertifikate
  • Automatische Aktualisierung von Zertifikaten
  • NGINX-Caching
  • NGINX-Komprimierung
  • Unterstützung von HTTPS und HTTP/2
  • Automatisierung des Prozesses

Der Artikel beschreibt die Installation auf einem Server, auf dem gleichzeitig ein Statik-Server, ein PHP-Server und eine Datenbank gehostet werden. Eine Installation mit Unterstützung für mehrere virtuelle Hosts und Dienste ist ein potenzielles zukünftiges Thema. Möchten Sie, dass wir über etwas schreiben, das in diesen Artikeln nicht behandelt wird – schreiben Sie uns in den Kommentaren.

Anforderungen

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

Architekturübersicht

Die Architektur ist die gleiche wie beschrieben zuvor, eine dreistufige Webanwendung. Sie besteht aus PHP-Skripten, die auf dem PHP-Handler ausgeführt werden, und statischen Dateien, die vom Webserver verarbeitet werden.

Wir automatisieren die Installation von WordPress mit NGINX Unit und Ubuntu.

Allgemeine Prinzipien

  • Viele Befehle zur Konfiguration im Skript sind in Bedingungen (if) gekapselt, um Idempotenz zu gewährleisten: Das Skript kann mehrere Male ohne Risiko gestartet werden, die bereits konfigurierten Einstellungen zu verändern.
  • Das Skript versucht, Software aus Repositories zu installieren, sodass Sie Systemupdates in einem einzigen Befehl anwenden können (apt upgrade für Ubuntu).
  • Die Befehle versuchen zu bestimmen, ob sie in einem Container ausgeführt werden, um ihre Einstellungen entsprechend anzupassen.
  • Um die Zahl der gestarteten Prozesse / Threads in den Einstellungen festzulegen, versucht das Skript, die automatischen Konfigurationsparameter für den Betrieb in Containern, virtuellen Maschinen oder auf physischen Servern zu erraten.
  • Bei der Beschreibung der Einstellungen denken wir immer zuerst an die Automation, die, so hoffen wir, die Grundlage für den Aufbau Ihrer eigenen Infrastruktur als Code sein wird.
  • Alle Befehle werden von dem Benutzer gestartet root, da sie grundlegende Systemkonfigurationen ändern, während WordPress selbst von einem normalen Benutzer ausgeführt wird.

Einrichtung der Umgebungsvariablen

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

  • WORDPRESS_DB_PASSWORD — Passwort für die WordPress-Datenbank
  • WORDPRESS_ADMIN_USER — Benutzername des WordPress-Administrators
  • WORDPRESS_ADMIN_PASSWORD — Passwort des WordPress-Administrators
  • WORDPRESS_ADMIN_EMAIL — E-Mail des WordPress-Administrators
  • WORDPRESS_URL — Vollständige URL der WordPress-Seite, beginnend mit https://.
  • LETS_ENCRYPT_STAGING — Standardmäßig leer, aber wenn Sie den Wert auf 1 setzen, verwenden Sie die Staging-Server von Let’s Encrypt, die für häufige Anfragen nach Zertifikaten während des Tests Ihrer Einstellungen erforderlich sind. Andernfalls könnte Let’s Encrypt Ihre IP-Adresse temporär sperren, wenn zu viele Anfragen gestellt werden.

Das Skript überprüft, ob diese mit WordPress verbundenen Variablen gesetzt sind, und wird beendet, 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 in den Zeilen 55-61 setzt die folgenden Umgebungsvariablen entweder auf einen bestimmten Wert oder verwendet Werte, die aus den im vorherigen Abschnitt gesetzten Variablen abgeleitet sind:

  • DEBIAN_FRONTEND="noninteractive" — informiert Anwendungen, dass sie in einem Skript ausgeführt werden und es keine Möglichkeit zur Benutzerinteraktion gibt.
  • WORDPRESS_CLI_VERSION="2.4.0" — Version der WordPress CLI-Anwendung.
  • WORDPRESS_CLI_MD5= "dedd5a662b80cda66e9e25d44c23b25c" — Prüfziffer der Executable-Datei WordPress CLI 2.4.0 (die Version wird in der Variablen WORDPRESS_CLI_VERSION). Das Skript in Zeile 162 verwendet diesen Wert zur Überprüfung, ob die korrekte WordPress CLI-Datei heruntergeladen wurde.
  • UPLOAD_MAX_FILESIZE="16M" — größtmögliche Dateigröße, die in WordPress hochgeladen werden kann. Diese Einstellung wird an mehreren Stellen verwendet, daher ist es einfacher, 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 und zur internen Überprüfung von WordPress.
  • NGINX_CONF_DIR="/etc/nginx" — Pfad zum Verzeichnis mit den NGINX-Konfigurationen, 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 von der Variablen TLS_HOSTNAME.

Festlegung des Hostnamens für den WordPress-Server

Das Skript legt den Hostnamen des Servers fest, sodass der Wert mit dem Domänennamen der Website übereinstimmt. Dies ist nicht zwingend erforderlich, erleichtert jedoch den Versand von ausgehenden E-Mails über SMTP, wenn ein einzelner Server konfiguriert wird, wie es im Skript vorgesehen 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 in /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 die Loopback-Schnittstelle 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 erforderlichen Tools für die nachfolgenden Schritte

Der verbleibende Teil des Skripts benötigt einige Programme und geht davon aus, dass die Repositories aktuell sind. Wir aktualisieren die Liste der Repositories und installieren dann die benötigten Werkzeuge:

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 Repositories für NGINX Unit und NGINX

Das Skript installiert NGINX Unit und NGINX als Open-Source-Software aus den offiziellen NGINX-Repositories, um sicherzustellen, dass die neuesten Sicherheitsupdates und Fehlerkorrekturen verwendet werden.

Das Skript fügt das Repository für NGINX Unit hinzu und dann das Repository für NGINX, indem es den Repository-Schlüssel und die Konfigurationsdateien hinzufügt apt, die den Zugriff auf die Repositories über das Internet regeln.

Die tatsächliche Installation von NGINX Unit und NGINX erfolgt im folgenden Abschnitt. Wir fügen die Repositories vorab 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 auch die empfohlenen PHP-Erweiterungen für die Nutzung von WordPress.org.

Skriptcode

echo "Aktualisierung der Repository-Metadaten"
apt-get -qq update

# Installiere PHP mit Abhängigkeiten und NGINX Unit
echo "Installation von 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

Konfiguration von PHP zur Verwendung mit NGINX Unit und WordPress.

Das Skript erstellt eine Konfigurationsdatei im Verzeichnis conf.d. Hier wird die maximale Größe der hochladbaren Dateien für PHP festgelegt, die Fehlermeldungen von PHP in STDERR aktiviert, sodass diese im NGINX Unit-Log aufgezeichnet werden, 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

Festlegen der Datenbankeinstellungen für MariaDB in WordPress.

Wir haben uns für MariaDB anstelle von MySQL entschieden, da sie eine aktivere Community hat und möglicherweise, bietet standardmäßig eine höhere Leistung (Es ist wahrscheinlich einfacher: Um MySQL zu installieren, muss ein weiteres Repository hinzugefügt werden, Anm. des Übersetzers).

Das Skript erstellt eine neue Datenbank und generiert Zugangsdaten für WordPress über die Loopback-Schnittstelle:

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;"

Installation des WordPress CLI

In diesem Schritt installiert das Skript das Programm WP-CLI. Damit können Sie WordPress ohne manuelle Dateiänderungen, Datenbankaktualisierungen oder Anmeldungen im Verwaltungspanel installieren und verwalten. Außerdem können Sie damit Themes und Plugins installieren und WordPress aktualisieren.

Skriptcode

if [ ! -f /usr/local/bin/wp ]; then
  # Installieren Sie 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-Verkehr zu reduzieren.
  • WordPress fügt ein Präfix hinzu https:// an die URL, wenn Kunden über das HTTPS-Protokoll mit NGINX verbunden sind, und sendet auch den entfernten Hostnamen (wie es NGINX bereitstellt) an PHP. Wir verwenden einen Code-Schnipsel, um dies zu konfigurieren.
  • WordPress benötigt HTTPS für die Anmeldung
  • Die Standard-URL-Struktur basiert auf Ressourcen
  • Die richtigen Berechtigungen werden im Dateisystem für das WordPress-Verzeichnis gesetzt.

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 die 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}'"

  # Dieses Snippet wird in die wp-config.php-Datei eingefügt, wenn sie erstellt wird;
  # es informiert WordPress, dass wir hinter einem Reverse-Proxy stehen und somit
  # ermöglicht es, Links unter Verwendung von HTTPS zu generieren
  cat > /tmp/wp_forwarded_for.php << 'EOM'
/* Aktiviert HTTPS, 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 einen sinnvollen Standard, der nicht in der UI angezeigt wird
  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

Dieses Skript konfiguriert NGINX Unit für den Start von PHP und die Verarbeitung von WordPress-Pfaden, indem es den Namensraum der PHP-Prozesse isoliert und die Leistungseinstellungen optimiert. Es gibt drei Funktionen, die besonders hervorzuheben sind:

  • Die Unterstützung von Namensräumen wird bedingt durch die Überprüfung, ob das Skript in einem Container läuft. Dies ist wichtig, da die meisten Container-Einstellungen keine verschachtelte Container-Ausführung unterstützen.
  • Wenn die Unterstützung von Namensräumen gegeben ist, wird der Namensraum deaktiviert Netzwerk. Dies ermöglicht es WordPress, gleichzeitig mit Endpunkten zu verbinden und im Internet verfügbar zu sein.
  • Die maximale Anzahl von Prozessen wird wie folgt bestimmt: (Verfügbare Speicher für laufende MariaDB und NGINX Unit)/(Speichergrenze in PHP + 5)
    Dieser Wert wird in den Einstellungen von NGINX Unit festgelegt.

Dieser Wert bedeutet auch, dass immer mindestens zwei PHP-Prozesse aktiv sind, was wichtig ist, da WordPress viele asynchrone Anfragen an sich selbst stellt. Ohne zusätzliche Prozesse könnte die Ausführung von WP-Cron beispielsweise fehlschlagen. Möglicherweise möchten Sie diese Einschränkungen basierend auf Ihren lokalen Einstellungen anpassen, da die hier angegebenen Werte konservativ sind. In 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 von PHP-Prozessen wurde auf ${MAX_PHP_PROCESSES} berechnet. Sie sollten diesen Wert aufgrund von Variationen in Ihrer Konfiguration anpassen. Es ist nicht ungewöhnlich, Werte zwischen 10 und 100 in Produktionskonfigurationen zu sehen."

echo " Konfiguriere NGINX Unit zur Verwendung von PHP und WordPress"
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

Hauptparameter von NGINX einrichten

Das Skript erstellt ein Verzeichnis für den NGINX-Cache und dann die Hauptkonfigurationsdatei nginx.conf. Achten Sie auf die Anzahl der Worker-Prozesse und das Festlegen der maximalen Dateigröße für Uploads. Außerdem gibt es eine Zeile, in der die Konfigurationsdatei für die Kompression eingebunden wird, die im nächsten Abschnitt definiert wird, gefolgt von den 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

Kompression von NGINX einrichten

Die Inhalte im Handumdrehen zu komprimieren, bevor sie an die Kunden gesendet werden, ist eine hervorragende Möglichkeit, die Leistung der Website zu verbessern, aber nur, wenn die Kompression korrekt konfiguriert ist. Dieser Abschnitt des Skripts basiert auf den Einstellungen hier herunter.

Skriptcode

cat > ${NGINX_CONF_DIR}/gzip_compression.conf << 'EOM'
# Quelle: 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;
# Kompressionsniveau (1-9).
# 5 bietet einen perfekten Kompromiss zwischen Größe und CPU-Nutzung, was eine Reduzierung von etwa 75%
# für die meisten ASCII-Dateien bewirkt (fast identisch mit Niveau 9).
# Standard: 1
gzip_comp_level 6;
# Nichts komprimieren, was bereits klein ist und wahrscheinlich nicht viel schrumpfen wird, falls überhaupt
# (der Standardwert sind 20 Bytes, was schlecht ist, da dies in der Regel zu größeren
# Dateien nach dem Gzip führt).
# Standard: 20
gzip_min_length 256;
# Komprimieren Sie Daten auch für Clients, die über Proxys zu uns verbinden,
# erkennbar durch den "Via"-Header (benötigt für CloudFront).
# Standard: aus
gzip_proxied any;
# Proxies anweisen, sowohl die gzipped- als auch die reguläre Version eines Ressourcen zu cachen,
# wann immer die Accept-Encoding-Fähigkeiten des Clients variieren;
# Vermeidet das Problem, dass ein nicht gzip-fähiger Client (was heute äußerst selten ist)
# unsinnige Ausgaben anzeigen würde, wenn ihr Proxy ihnen die gzipped Version gibt.
# Standard: aus
gzip_vary on;
# Komprimieren Sie alle Ausgaben, 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-Konfiguration für WordPress

Anschließend erstellt das Skript eine Konfigurationsdatei für WordPress default.conf im Verzeichnis conf.d. Hier werden folgende Einstellungen vorgenommen:

  • Aktivierung von TLS-Zertifikaten, die von Let’s Encrypt über Certbot erhalten wurden (die Konfiguration folgt im nächsten Abschnitt)
  • Einrichtung von TLS-Sicherheitsparametern basierend auf den Empfehlungen von Let’s Encrypt
  • Standardmäßige Aktivierung der Cache-Mechanismen für übergangene Anfragen für eine Stunde
  • Deaktivierung der Zugriffsprotokollierung sowie der Fehlerprotokollierung, falls die Datei nicht gefunden wird, für zwei häufig angeforderte Dateien: favicon.ico und robots.txt
  • Zugriffsbeschränkungen auf versteckte Dateien und bestimmte Dateien .php, um unbefugten Zugriff oder unbeabsichtigtes Starten zu verhindern
  • Deaktivierung der Zugriffsprotokollierung für statische Dateien und Schriftartdateien
  • Festlegung des Headers Access-Control-Allow-Origin für Schriftartdateien
  • Hinzufügen von Routing 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, verwendet von Certbot für Let's Encrypt
    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-Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    # Proxy-Caching
    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, verbieten
    # Logging der Anfragen fortsetzen, um später zu analysieren (oder an Firewall-Dienste
    # wie fail2ban weiterzugeben)
    location ~ /.{
        deny all;
    }
    # Zugriff auf Dateien mit der Endung .php im Upload-Verzeichnis verweigern;
    # funktioniert in Unterverzeichnis-Installationen und auch in Multi-Site-Netzwerken.
    # Logging der Anfragen fortsetzen, um später zu analysieren (oder an Firewall-Dienste
    # wie fail2ban weiterzugeben).
    location ~* /(?:uploads|files)/.*.php$ {
        deny all;
    }
    # WordPress: Zugriff auf wp-content, wp-includes PHP-Dateien verweigern
    location ~* ^/(?:wp-content|wp-includes)/.*.php$ {
        deny all;
    }
    # Öffentlichem Zugriff auf wp-config.php verweigern
    location ~* wp-config.php {
        deny all;
    }
    # Zugriff für statische Assets, Medien nicht protokollieren
    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

Konfiguration von Certbot für Let's Encrypt-Zertifikate und deren automatische Verlängerung

Certbot ist ein kostenloses Tool der Electronic Frontier Foundation (EFF), mit dem Sie TLS-Zertifikate von Let's Encrypt erhalten und automatisch aktualisieren können. Das Skript führt folgende Schritte durch, um Certbot für die Verwaltung von Let's Encrypt-Zertifikaten 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 eine tägliche Ausführung von Certbot um 3:24 Uhr ein, um zu prüfen, ob eine Zertifikatsverlängerung erforderlich ist, und falls nötig, neue Zertifikate herunterzuladen und NGINX neu zu starten.

Skriptcode

echo " NGINX wird gestoppt, 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 " Lade empfohlene TLS-Parameter herunter"
  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 " Lade empfohlene TLS-DH-Parameter herunter"
  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

# Falls tls_certs_init.sh zuvor nicht ausgeführt wurde, entferne die selbstsignierten Zertifikate
if [ ! -d "/etc/letsencrypt/accounts" ]; then
  echo " Entferne selbstsignierte 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 " Generiere Zertifikate 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 Verlängerung von Let's Encrypt Zertifikaten
if [ "$(crontab -l | grep -m1 'certbot renew')" == "" ]; then
  echo "Füge certbot zur crontab für die automatische Verlängerung von Let's Encrypt hinzu"
  (crontab -l 2>/dev/null; echo "24 3 * * * certbot renew --nginx --post-hook 'service nginx reload'") | crontab -
fi

Zusätzliche Anpassung Ihrer Website

Wir haben zuvor erläutert, wie unser Skript NGINX und NGINX Unit einrichtet, um eine produktionsbereite Website mit aktivem TLS/SSL zu betreiben. Je nach Ihren Bedürfnissen können Sie in Zukunft auch hinzufügen:

  • Unterstützung Brotli, verbesserte On-the-Fly-Kompression über HTTPS
  • ModSecurity mit Regeln für WordPress, um automatische Angriffe auf Ihre Website zu verhindern
  • Sicherungskopie für WordPress, die Ihnen entspricht
  • Schutz mit Hilfe von AppArmor (unter Ubuntu)
  • Postfix oder msmtp, damit WordPress E-Mails versenden kann
  • Überprüfungen Ihrer Website, damit Sie wissen, wie viel Traffic sie bewältigen kann

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

N.B. Für die Unterstützung einer hochbelasteten Website können Sie sich an Experten wenden Southbridge. Wir gewährleisten eine schnelle und zuverlässige Leistung Ihrer Website oder Dienstleistung unter jeglicher Last.

Quelle: habr.com

Zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Servern kaufen 🔥 Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Servern | ProHoster