PHP-FPM (FastCGI Process Manager) ist die empfohlene Methode, PHP mit Nginx zu betreiben. Im Gegensatz zu mod_php bei Apache läuft PHP als separater Prozess, was mehr Kontrolle und bessere Performance ermöglicht.

Installation

Ubuntu/Debian

apt update
apt install php-fpm php-mysql php-curl php-gd php-mbstring php-xml php-zip

Die PHP-Version prüfen:

php -v

PHP-FPM Grundlagen

Wie es funktioniert

1. Nginx empfängt PHP-Anfrage 2. Nginx leitet an PHP-FPM weiter (via Socket oder TCP) 3. PHP-FPM verarbeitet die Anfrage 4. Ergebnis geht zurück an Nginx 5. Nginx sendet Response an Client

Wichtige Pfade

| Pfad | Inhalt | |------|--------| | /etc/php/8.1/fpm/php.ini | PHP-Konfiguration | | /etc/php/8.1/fpm/pool.d/www.conf | Pool-Konfiguration | | /run/php/php8.1-fpm.sock | Unix-Socket | | /var/log/php8.1-fpm.log | Log-Datei |

Nginx-Konfiguration

Basis-Setup

server {
    listen 80;
    server_name example.com;
    root /var/www/example.com;
    index index.php index.html;

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

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

    location ~ /\.ht {
        deny all;
    }
}

Mit TCP statt Socket

Für High-Traffic oder separate Server:

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass 127.0.0.1:9000;
}

In /etc/php/8.1/fpm/pool.d/www.conf:

listen = 127.0.0.1:9000

Pool-Konfiguration

Die Datei /etc/php/8.1/fpm/pool.d/www.conf enthält die wichtigsten Einstellungen.

Process Manager Typen

; static: Feste Anzahl Worker
pm = static
pm.max_children = 10

; dynamic: Zwischen min und max (Standard)
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35

; ondemand: Startet Worker nur bei Bedarf
pm = ondemand
pm.max_children = 50
pm.process_idle_timeout = 10s

Welchen PM wählen?

| PM | Vorteil | Nachteil | Einsatz | |----|---------|----------|---------| | static | Vorhersagbar | RAM immer belegt | Dedi-Server | | dynamic | Flexibel | Kann bei Spikes träge sein | Allzweck | | ondemand | Spart RAM | Latenz beim Start | Wenig Traffic |

Worker berechnen

Faustregel für pm.max_children:

Verfügbarer RAM / RAM pro PHP-Prozess = max_children

Beispiel:

  • Server: 4 GB RAM
  • System + Datenbank: 1 GB
  • Verfügbar für PHP: 3 GB
  • RAM pro Prozess: ~50-100 MB
  • max_children: 30-60

RAM pro Prozess ermitteln:

ps --no-headers -o "rss,cmd" -C php-fpm8.1 | awk '{ sum+=$1 } END { print sum/NR/1024 " MB" }'

PHP.ini optimieren

In /etc/php/8.1/fpm/php.ini:

Speicher und Zeit

memory_limit = 256M
max_execution_time = 300
max_input_time = 300

Upload-Größe

upload_max_filesize = 64M
post_max_size = 64M

OPcache (wichtig!)

opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.validate_timestamps = 0  ; Production
opcache.revalidate_freq = 0

Session

session.save_handler = files
session.save_path = "/var/lib/php/sessions"

Performance-Tipps

1. OPcache aktivieren

OPcache cached kompilierten PHP-Code:

php -m | grep OPcache

2. Status-Seite aktivieren

In /etc/php/8.1/fpm/pool.d/www.conf:

pm.status_path = /fpm-status

In Nginx (nur lokal!):

location /fpm-status {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    allow 127.0.0.1;
    deny all;
}

3. Slow-Log aktivieren

Findet langsame Skripte:

slowlog = /var/log/php8.1-fpm-slow.log
request_slowlog_timeout = 5s

4. Socket vs. TCP

Socket ist schneller für lokale Kommunikation:

listen = /run/php/php8.1-fpm.sock

Mehrere Pools

Für verschiedene Websites oder Benutzer:

Erstellen Sie /etc/php/8.1/fpm/pool.d/example.conf:

[example]
user = example
group = example
listen = /run/php/php8.1-fpm-example.sock
listen.owner = www-data
listen.group = www-data

pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 5

php_admin_value[error_log] = /var/log/php/example-error.log
php_admin_flag[log_errors] = on

In Nginx:

fastcgi_pass unix:/run/php/php8.1-fpm-example.sock;

Troubleshooting

"502 Bad Gateway"

PHP-FPM läuft nicht:

systemctl status php8.1-fpm

Socket existiert nicht:

ls -la /run/php/

"504 Gateway Timeout"

PHP-Skript braucht zu lange:

fastcgi_read_timeout 300;

Hohe CPU-Last

Zu viele Worker oder ineffizienter Code:

htop  # PHP-Prozesse prüfen
tail -f /var/log/php8.1-fpm-slow.log

Out of Memory

Zu viele Worker oder memory_limit zu hoch:

dmesg | grep -i oom

Dienst neustarten

Nach Konfigurationsänderungen:

systemctl restart php8.1-fpm
# oder nur reload:
systemctl reload php8.1-fpm

Fazit

PHP-FPM mit Nginx ist die performanteste Lösung für PHP-Websites. Die wichtigsten Einstellungen: pm.max_children an verfügbaren RAM anpassen, OPcache aktivieren, und für Production opcache.validate_timestamps = 0 setzen. Mit dem Slow-Log finden Sie Engpässe im Code.