---
title: "WordPress auf nginx mit PHP-FPM konfigurieren: Server-Block, Grenzwerte und Sperren"
date: 2026-09-30T22:20:14+02:00
modified: 2026-11-08T22:35:25+01:00
category: wordpress
type: how_to
author: Marcel Schönfelder
canonical: https://s-edv.com/anleitungen/wordpress-nginx-php-fpm-konfigurieren-server-block
keywords:
  - WordPress
  - nginx
  - PHP-FPM
  - Debian
  - Server
reading_time: 8
---

# WordPress auf nginx mit PHP-FPM konfigurieren: Server-Block, Grenzwerte und Sperren

Viele Hoster und Administratoren betreiben WordPress mit Apache, weil WordPress seine Regeln für schöne Permalinks selbst in die `.htaccess` schreibt. Auf einem eigenen Server ist nginx mit PHP-FPM eine verbreitete Alternative: nginx liefert statische Dateien direkt aus und reicht nur PHP-Anfragen an einen separaten PHP-Prozess weiter. Der Preis dafür ist, dass nginx keine `.htaccess` kennt. Jede Regel für Permalinks, Upload-Größen und Zugriffssperren müssen Sie selbst in die Server-Konfiguration schreiben. Diese Anleitung zeigt eine vollständige, getestete Konfiguration für Debian 13 mit nginx 1.26 und PHP 8.4, erklärt jede Zeile und zeigt die typischen Fehler mit den zugehörigen Meldungen.

**Kurzfassung:** Installieren Sie `nginx` und `php8.4-fpm` mit den PHP-Erweiterungen für WordPress. Der Server-Block braucht `try_files $uri $uri/ /index.php?$args;` für Permalinks und einen PHP-Block mit `fastcgi_pass unix:/run/php/php8.4-fpm.sock;`. Sperrregeln für `wp-config.php`, versteckte Dateien und PHP im Uploads-Ordner gehören vor den PHP-Block, weil nginx die erste passende Regex-Location nimmt. Upload-Größen setzen Sie an zwei Stellen: `client_max_body_size` in nginx und `upload_max_filesize` im PHP-FPM-Pool. Prüfen Sie jede Änderung mit `nginx -t` und `curl`.

## Voraussetzungen

- [ ] **Server:** ein Linux-Server oder VPS mit Debian 13 („trixie“). Auf Ubuntu heißen Pakete und Pfade ähnlich, die PHP-Version kann abweichen. Für eine kleine Unternehmenswebsite genügen 2 CPU-Kerne und 2 bis 4 GB RAM.
- [ ] **WordPress:** eine vorhandene Installation mit Datenbank, hier WordPress 7.1.2 in deutscher Sprache.
- [ ] **PHP:** PHP 8.4 aus den Debian-Paketquellen, hier 8.4.26. WordPress empfiehlt PHP 8.3 oder neuer.
- [ ] **Zugriff:** SSH mit Root- oder sudo-Rechten sowie Administrator-Zugang zu WordPress.
- [ ] **Backup:** eine aktuelle Sicherung von Dateien, Datenbank und bisheriger Webserver-Konfiguration, bevor Sie von Apache auf nginx wechseln.
- [ ] **TLS:** Die Anleitung zeigt den HTTP-Teil. Das Zertifikat richten Sie danach ein, siehe [Nginx mit TLS einrichten](https://s-edv.com/anleitungen/nginx-reverse-proxy-tls-einrichten).

## Schritt 1: nginx und PHP-FPM installieren

PHP-FPM (FastCGI Process Manager) hält einen Pool von PHP-Prozessen bereit, an die nginx Anfragen weiterreicht. Installieren Sie beide Komponenten und die PHP-Erweiterungen, die WordPress für Datenbank, HTTP-Anfragen, Bildbearbeitung und Sprachdateien braucht:

```bash
sudo apt update
sudo apt install --no-install-recommends nginx php8.4-fpm php8.4-mysql \
  php8.4-curl php8.4-xml php8.4-mbstring php8.4-zip php8.4-intl php8.4-gd php8.4-imagick
```

`--no-install-recommends` verhindert, dass Debian zusätzlich Apache als Abhängigkeit mitbringt. Debian installiert dabei nginx 1.26.3 und PHP-FPM 8.4.26. Prüfen Sie die Versionen und den Standard-Pool:

```bash
nginx -v
php-fpm8.4 -v
grep -E '^(user|group|listen|pm)' /etc/php/8.4/fpm/pool.d/www.conf
```

Der Pool `www` läuft als Benutzer `www-data` und lauscht auf dem Unix-Socket `/run/php/php8.4-fpm.sock`. Diesen Pfad brauchen Sie im Server-Block. Die WordPress-Dateien müssen für `www-data` lesbar sein, schreibbar nur dort, wo WordPress schreiben soll. Details dazu stehen in [Dateirechte in WordPress richtig setzen](https://s-edv.com/anleitungen/wordpress-dateirechte-richtig-setzen-wp-config-chmod-chown).

> **Prüfen:** `php-fpm8.4 -t` meldet „configuration file /etc/php/8.4/fpm/php-fpm.conf test is successful“, und der Socket `/run/php/php8.4-fpm.sock` existiert nach dem Start des Dienstes.

## Schritt 2: Server-Block für WordPress anlegen

Legen Sie die Datei `/etc/nginx/sites-available/wordpress` an. Die folgende Konfiguration läuft unverändert, ersetzen Sie nur `server_name` und `root`:

```nginx
server {
    listen 80;
    server_name www.ihre-domain.de;

    root /var/www/html;
    index index.php;

    client_max_body_size 80m;

    # Sperren zuerst: nginx nimmt die erste passende Regex-Location
    location = /wp-config.php { deny all; }
    location = /xmlrpc.php { deny all; }
    location ~ /\.(?!well-known) { deny all; }
    location ~* /(?:uploads|files)/.*\.php$ { deny all; }

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.4-fpm.sock;
    }

    location ~* \.(?:css|js|jpe?g|png|gif|webp|avif|svg|ico|woff2?)$ {
        expires 30d;
        access_log off;
        try_files $uri =404;
    }
}
```

Die wichtigsten Zeilen im Einzelnen:

- **`try_files $uri $uri/ /index.php?$args;`** ersetzt die Permalink-Regeln der `.htaccess`. Existiert keine Datei und kein Verzeichnis mit diesem Namen, übernimmt WordPress die Anfrage. Die Beispielkonfiguration im Advanced Administration Handbook verwendet dieselbe Zeile.
- **`snippets/fastcgi-php.conf`** ist ein Debian-Baustein. Er prüft mit `try_files $fastcgi_script_name =404;`, ob die PHP-Datei existiert, und bindet `fastcgi.conf` mit dem Parameter `SCRIPT_FILENAME` ein.
- **`client_max_body_size`** begrenzt die Größe einer Anfrage. Der Standard von nginx liegt laut Dokumentation bei 1 MB, zu wenig für Medien-Uploads.
- **`location ~ /\.(?!well-known)`** sperrt versteckte Dateien wie `.htaccess` oder `.git`, lässt aber `.well-known` für Zertifikatsprüfungen offen.
- **`xmlrpc.php`** sperren Sie nur, wenn Sie keine Apps oder Dienste nutzen, die XML-RPC brauchen. Hintergründe stehen in [XML-RPC in WordPress deaktivieren oder einschränken](https://s-edv.com/anleitungen/wordpress-xml-rpc-deaktivieren-einschraenken).

Die Reihenfolge ist kein Detail. nginx prüft Regex-Locations in der Reihenfolge, in der sie in der Datei stehen, und nimmt die erste passende. Stehen die Sperren hinter dem PHP-Block, wird eine Datei `wp-content/uploads/test.php` mit Status `200` ausgeführt, weil `location ~ \.php$` zuerst passt. Erst nach dem Verschieben der Sperren nach oben antwortet nginx mit `403`.

Aktivieren Sie die Konfiguration und prüfen Sie die Syntax:

```bash
$ sudo ln -s /etc/nginx/sites-available/wordpress /etc/nginx/sites-enabled/wordpress
$ sudo rm /etc/nginx/sites-enabled/default
$ sudo nginx -t && sudo systemctl reload nginx
```

> **Prüfen:** `nginx -t` meldet „syntax is ok“ und „test is successful“. `curl -s -o /dev/null -w '%{http_code}\n' http://www.ihre-domain.de/` liefert `200`.

## Schritt 3: Umgebung und Grenzwerte im PHP-FPM-Pool

PHP-FPM startet seine Prozesse mit leerer Umgebung. Laut PHP-Handbuch steht `clear_env` standardmäßig auf „Yes“, damit keine beliebigen Umgebungsvariablen in die PHP-Prozesse gelangen. Das ist sicher, hat aber eine Folge: Liest Ihre `wp-config.php` Zugangsdaten per `getenv()`, etwa weil sie aus einem Container-Image oder einem Deployment-Werkzeug stammt, findet sie nichts. Dann zeigt WordPress die Seite „Database Error“, und nginx liefert den Status `500`. Die Lösung ist entweder, die Werte direkt in die `wp-config.php` zu schreiben, oder sie gezielt im Pool freizugeben:

Datei: `wp-config.php`

```php
; /etc/php/8.4/fpm/pool.d/www.conf (am Ende ergänzen)
env[WORDPRESS_DB_HOST] = $WORDPRESS_DB_HOST
```

In derselben Datei legen Sie die PHP-Grenzwerte für diesen Pool fest. Ohne Anpassung gelten `upload_max_filesize` 2M, `post_max_size` 8M und `memory_limit` 128M:

```plaintext
php_admin_value[upload_max_filesize] = 64M
php_admin_value[post_max_size] = 80M
php_admin_value[memory_limit] = 256M
```

`php_admin_value` kann von PHP-Code nicht überschrieben werden. Für Dateien bis 64 MB lassen `post_max_size` und `client_max_body_size` mit 80 MB Reserve für die übrigen Formulardaten. Laden Sie den Dienst neu:

```bash
$ sudo php-fpm8.4 -t && sudo systemctl reload php8.4-fpm
```

Die Anzahl der PHP-Prozesse steuert `pm.max_children`, im Debian-Standard 5. Jeder Prozess kann bis zum `memory_limit` belegen. Rechnen Sie grob: freier Arbeitsspeicher geteilt durch den typischen Speicherbedarf eines Prozesses. Messen Sie diesen Bedarf auf Ihrem Server, statt Werte aus Foren zu übernehmen.

> **Prüfen:** Eine vorübergehend angelegte Datei mit `<?php echo ini_get('upload_max_filesize');` gibt über den Browser den neuen Wert aus, für die gezeigte Konfiguration 64M; prüfen Sie `post_max_size` und `memory_limit` entsprechend auf 80M und 256M. Löschen Sie die Datei danach sofort.

## Schritt 4: Permalinks, Sperren und Caching prüfen

Prüfen Sie die Konfiguration nicht nur mit der Startseite, sondern systematisch. Die folgende Schleife ruft typische Adressen auf und zeigt den Statuscode:

```bash
for p in / /hello-world/ /wp-login.php /wp-json/ /xmlrpc.php /wp-config.php /.htaccess /nicht-vorhanden/; do
  echo "$(curl -s -o /dev/null -w '%{http_code}' https://www.ihre-domain.de$p) $p"
done
```

Mit der Permalink-Struktur `/%postname%/` lautet das Ergebnis:

| Adresse | Status | Bedeutung |
| --- | --- | --- |
| `/`, `/hello-world/`, `/wp-login.php`, `/wp-json/` | 200 | Permalinks und REST-API funktionieren |
| `/xmlrpc.php`, `/wp-config.php`, `/.htaccess` | 403 | Sperren greifen |
| `/wp-content/uploads/test.php` | 403 | kein PHP im Uploads-Ordner |
| `/nicht-vorhanden/` | 404 | WordPress liefert seine Fehlerseite |

Für statische Dateien setzt die Konfiguration `Cache-Control: max-age=2592000`, also 30 Tage. Das entlastet den Server bei wiederkehrenden Besuchern. Mehr zu Caching-Headern und Komprimierung steht in [Browser-Caching und Komprimierung für WordPress](https://s-edv.com/anleitungen/wordpress-browser-caching-komprimierung-gzip-brotli-apache-nginx).

Unter *Einstellungen > Permalinks* können Sie die Struktur wie gewohnt ändern. Die `try_files`-Zeile leitet jede nicht vorhandene Adresse an WordPress weiter und deckt damit alle Strukturen ab.

> **Prüfen:** Alle Adressen liefern die Statuscodes aus der Tabelle, und `/?p=1` leitet mit `301` auf die schöne Adresse des Beitrags weiter.

## Schritt 5: Protokolle lesen und dauerhaft betreiben

nginx schreibt Fehler nach `/var/log/nginx/error.log`, PHP-FPM nach `/var/log/php8.4-fpm.log`. Beide Dateien sind die erste Anlaufstelle bei Problemen. Gesperrte Zugriffe erscheinen dort mit „access forbidden by rule“, was zeigt, dass Ihre Sperren arbeiten.

Richten Sie außerdem ein, dass beide Dienste nach einem Neustart des Servers starten:

```bash
$ sudo systemctl enable --now nginx php8.4-fpm
```

Ein eigener Server bedeutet eigene Verantwortung. Sicherheitsupdates für nginx und PHP kommen über `apt`, WordPress, Plugins und Themes brauchen ihre eigenen Updates, und nach jeder Änderung an der Konfiguration sollten Sie die Prüfung aus Schritt 4 wiederholen. Wer die WordPress-seitigen Aufgaben nicht selbst im Kalender halten möchte, kann sie abgeben: Die [WordPress-Wartung von wordpressupdate.de](https://wordpressupdate.de/?utm_source=s-edv.com&utm_medium=artikel&utm_campaign=105) übernimmt Updates von WordPress, Plugins und Themes mit Kompatibilitätsprüfung, wöchentliche Backups auf externen Speicher und die Firewall.

> **Prüfen:** `systemctl is-enabled nginx php8.4-fpm` meldet zweimal „enabled“, und nach einem Neustart des Servers liefert die Website wieder `200`.

## Typische Fehler

**502 Bad Gateway**

nginx erreicht PHP-FPM nicht. Bei falschem Socket-Pfad steht im Fehlerprotokoll: `connect() to unix:/run/php/php-fpm.sock failed (2: No such file or directory) while connecting to upstream`. Pfad aus `listen` im Pool übernehmen und prüfen, ob PHP-FPM läuft.

**413 Request Entity Too Large beim Upload**

`client_max_body_size` ist zu klein. nginx protokolliert dazu „client intended to send too large body“.

**Upload scheitert trotz passender nginx-Grenze**

`upload_max_filesize` oder `post_max_size` im PHP-FPM-Pool ist kleiner. WordPress zeigt dann die Meldung, die Datei überschreite das Upload-Limit.

**„Database Error“ und Status 500 nach dem Wechsel**

Die `wp-config.php` liest Umgebungsvariablen, die PHP-FPM wegen `clear_env` nicht weitergibt.

**Beiträge liefern 404, die Startseite funktioniert**

Die Zeile `try_files … /index.php?$args;` fehlt oder steht im falschen `location`-Block.

**PHP-Dateien im Uploads-Ordner werden ausgeführt**

Die Sperre steht hinter `location ~ \.php$`. Sperren nach oben verschieben.

## Häufige Fragen

### Ist nginx schneller als Apache?

Das hängt von Konfiguration und Last ab. nginx liefert statische Dateien effizient aus, die Laufzeit von WordPress selbst bestimmt aber PHP. Für die meisten kleinen Websites wirken Seiten-Cache und OPcache stärker als die Wahl des Webservers.

### Funktionieren Sicherheits- und Cache-Plugins, die in die .htaccess schreiben?

Deren Regeln wirken auf nginx nicht. Viele Plugins zeigen deshalb eigene nginx-Beispiele an, die Sie in den Server-Block übernehmen und mit `nginx -t` prüfen.

### Brauche ich einen eigenen PHP-FPM-Pool pro Website?

Bei mehreren Websites auf einem Server ja. Ein eigener Pool mit eigenem Benutzer trennt die Websites, sodass eine kompromittierte Installation nicht die Dateien der anderen lesen kann.

## Fazit

WordPress läuft auf nginx mit PHP-FPM stabil, wenn Sie drei Dinge beachten: `try_files` für Permalinks, Sperren vor dem PHP-Block und abgestimmte Grenzwerte in nginx und PHP-FPM. Mit der Prüfschleife aus Schritt 4 erkennen Sie nach jeder Änderung, ob alles noch greift. Wenn Sie die Pflege von WordPress, Plugins und Backups auf diesem Server lieber abgeben, übernimmt das die [WordPress-Wartung von Marcel Schönfelder](https://wordpressupdate.de/?utm_source=s-edv.com&utm_medium=fazit&utm_campaign=105).

## Weiterführende Anleitungen und Quellen

- [Nginx als Reverse Proxy mit TLS manuell einrichten](https://s-edv.com/anleitungen/nginx-reverse-proxy-tls-einrichten)
- [Dateirechte in WordPress richtig setzen](https://s-edv.com/anleitungen/wordpress-dateirechte-richtig-setzen-wp-config-chmod-chown)
- [Browser-Caching und Komprimierung für WordPress auf Apache und Nginx](https://s-edv.com/anleitungen/wordpress-browser-caching-komprimierung-gzip-brotli-apache-nginx)
- [XML-RPC in WordPress deaktivieren oder einschränken](https://s-edv.com/anleitungen/wordpress-xml-rpc-deaktivieren-einschraenken)
- [Advanced Administration Handbook: Nginx](https://developer.wordpress.org/advanced-administration/server/web-server/nginx/)
- [nginx-Dokumentation: Core-Modul (location, try_files, client_max_body_size)](https://nginx.org/en/docs/http/ngx_http_core_module.html)
- [PHP-Handbuch: FPM-Konfiguration](https://www.php.net/manual/en/install.fpm.configuration.php)
