# PHP-FPM vysvětleno: správce procesů, pooly a workery

> PHP-FPM vysvětleno: jak pracují master, pooly a workery, co znamenají pm static, dynamic a ondemand a která nastavení poolu zvyšují bezpečnost.

Zdroj: https://phpsos.de/cs/php/php-fpm-erklaert/  
Stav: 25.10.2026  
Poskytovatel: PHP SOS, Nouzová pomoc pro PHP a bezpečnost serverů. Okamžitá pomoc přes WhatsApp: https://wa.me/491736494914?text=Dobr%C3%BD%20den%2C%20PHP%20SOS%2C%20pot%C5%99ebujeme%20pomoc%20s%20na%C5%A1%C3%ADm%20PHP%20serverem.%20Firma%3A%20%E2%80%A6%20Web%3A%20%E2%80%A6

**Stručně:** PHP-FPM (FastCGI Process Manager) provozuje PHP jako samostatnou službu vedle webového serveru. Hlavní proces (master) spravuje pooly a každý pool spouští workery, které zpracovávají požadavky přes FastCGI. Pooly lze provozovat pro každý web s vlastním uživatelem, vlastními limity a uzamčenými nastaveními PHP. Protože workery zpracovávají postupně mnoho požadavků, je nutné je po aktualizaci PHP všechny restartovat.

## Co je PHP-FPM?

Příručka PHP popisuje FPM jako primární implementaci FastCGI v PHP s funkcemi, které jsou užitečné hlavně pro silně zatížené weby. FPM bylo převzato s PHP 5.3.3 jako samostatné SAPI, tedy samostatný provozní režim. Jeho název SAPI je `fpm-fcgi`.

Rozdíl oproti mod_php: PHP neběží ve webovém serveru, ale jako samostatná služba. Nginx, Apache nebo jiný webový server předává požadavky PHP protokolem FastCGI a dostává zpět hotovou odpověď. Webový server a PHP lze tak nezávisle na sobě restartovat, konfigurovat a zabezpečovat. Jak FastCGI v zásadě funguje, popisuje článek [CGI a FastCGI](https://phpsos.de/cs/php/cgi-und-fastcgi/).

## Master, pooly a workery: procesní model

PHP-FPM se skládá ze tří úrovní:

1. **Hlavní proces (master):** čte konfiguraci, otevírá sockety a spouští nebo ukončuje workery. Sám nespouští žádný kód aplikace.
2. **Pooly:** Každý pool má název, vlastní socket nebo port, vlastního uživatele Unix a vlastní nastavení PHP. Příručka výslovně uvádí odlišné uid, gid, chroot, prostředí a php.ini pro každý pool.
3. **Workery:** procesy poolu, které přijímají a provádějí požadavky. Worker zpracuje postupně mnoho požadavků, než je nahrazen.

Kolik workerů běží, určuje správce procesů direktivou `pm`:

| Režim | Chování | Důležité direktivy |
|---|---|---|
| `static` | pevný počet workerů | `pm.max_children` |
| `dynamic` | workery mezi dolní a horní mezí | `pm.start_servers`, `pm.min_spare_servers`, `pm.max_spare_servers` |
| `ondemand` | workery jen podle potřeby, po nečinnosti se ruší | `pm.process_idle_timeout` (výchozí 10s) |

`pm.max_children` omezuje ve všech režimech počet souběžných požadavků. `pm.max_requests` nahradí worker po pevném počtu požadavků; výchozí hodnota 0 znamená neomezeně.

Který režim se hodí, závisí na zátěži. `static` drží vždy stejný počet workerů připravených a hodí se pro rovnoměrně silně využívané aplikace s dostatkem paměti. `dynamic` je kompromis pro většinu webů. `ondemand` šetří paměť na serverech s mnoha malými weby, protože pooly bez návštěvníků nezabírají žádné workery; první požadavek po pauze ale trvá o něco déle. Příliš vysoké `pm.max_children` může server při špičkách přivést k nedostatku paměti, příliš nízké vede k čekacím dobám a chybovým hlášením webového serveru.

## Pool s bezpečnými základními nastaveními

Příklad samostatného poolu pro každý web s direktivami z příručky PHP. Cesty a hodnoty jsou příklady:

```ini
; /etc/php/8.3/fpm/pool.d/kunde-a.conf
[kunde-a]
user = kunde-a
group = kunde-a

listen = /run/php/kunde-a.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 10s

request_terminate_timeout = 60s
security.limit_extensions = .php
clear_env = yes

php_admin_value[open_basedir] = /var/www/kunde-a:/tmp
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[error_log] = /var/log/php/kunde-a.error.log
```

Podle příručky lze hodnoty nastavené přes `php_value` a `php_flag` za běhu měnit pomocí `ini_set()`, hodnoty přes `php_admin_value` a `php_admin_flag` naopak ne. `security.limit_extensions` je standardně `.php .phar` a určuje, které přípony souborů FPM provede jako hlavní skript. `clear_env = yes` je výchozí hodnota a vyprázdní prostředí workerů.

Pro monitorování existuje stavová stránka přes `pm.status_path` a stránka ping přes `ping.path`. Obě by měly být dostupné jen interně. Pomalé požadavky FPM zaznamenává s backtrace, pokud jsou nastaveny `request_slowlog_timeout` a `slowlog`.

> **Důležité:**
> Příručka PHP varuje: Kdo může otevřít spojení FastCGI k PHP-FPM, ovládá konfiguraci požadavku a může tak provést libovolný kód. PHP-FPM nesmí být nikdy dostupné z nedůvěryhodné sítě. Použijte socket Unix nebo `listen.allowed_clients`.

## Jakou roli hraje PHP-FPM u PHP2Shell?

PHP-FPM patří mezi postižené provozní režimy. Procesní model je obzvlášť zřetelný u CVE-2026-109619: vnitřní stav patřící k požadavku může po uvolnění paměti přetrvat a pozdější požadavek ve stejném workeru ho může využít dříve, než se vynuluje. To je možné jen proto, že workery zpracovávají mnoho požadavků za sebou.

Z toho plynou tři povinnosti:

1. **Nasadit aktualizaci:** PHP 8.5.12, 8.4.27, 8.3.36 nebo 8.2.35, případně potvrzený backport distribuce.
2. **Restartovat všechny workery:** Nové soubory na disku nic nemění, dokud běží staré workery. Platí to pro každou nainstalovanou verzi FPM a každý pool. Příkazy najdete v článku [Restart PHP-FPM a všech workerů](https://phpsos.de/cs/php2shell/php-fpm-neustart/).
3. **Přechodné hodnoty nastavit jako uzamčené:** Opatření z php.net, například `session.upload_progress.enabled=0`, patří přes `php_admin_value` nebo `php_admin_flag` do poolu, nikoli do `.user.ini`.

Oddělení do poolů aktualizaci nenahrazuje, ale omezuje škody: pokud každý web běží pod vlastním uživatelem, útočník po průniku automaticky nezíská soubory ostatních. Jak to konkrétně vypadá, popisuje článek [Izolace poolů PHP-FPM pro každý web](https://phpsos.de/cs/blog/php-fpm-pools-isolieren/); začlenění do Nginx najdete v článku [Zabezpečení Nginx s PHP-FPM](https://phpsos.de/cs/server/nginx-php-fpm/).

## Jak konkrétně pomáhá PHP SOS?

- **Zmapovat pooly:** Vypíšeme všechny verze FPM, pooly, uživatele a sockety vašeho serveru.
- **Záplatovat a restartovat:** Aktualizujeme PHP a podle časů spuštění doložíme, že už neběží žádný starý worker.
- **Oddělit pooly:** V rámci [zpevnění serveru](https://phpsos.de/cs/leistungen/server-haertung/) nastavíme pro každý web pool s vlastním uživatelem a uzamčenými nastaveními.
- **Zkontrolovat dostupnost:** Ověříme, že sockety FastCGI a stavové stránky nejsou dostupné zvenčí.


## Časté dotazy

**Co znamená FPM?**  
FPM znamená FastCGI Process Manager. Příručka PHP jej popisuje jako primární implementaci FastCGI v PHP s funkcemi, které jsou užitečné hlavně pro silně zatížené weby. Převzat byl s PHP 5.3.3.

**Jaký je rozdíl mezi poolem a workerem?**  
Pool je skupina procesů workerů se společnou konfigurací: uživatel, socket, limity a nastavení PHP. Worker je jednotlivý proces, který postupně zpracovává požadavky. Server může mít mnoho poolů, například jeden pro každý web.

**Má být PHP-FPM dostupné přes TCP, nebo přes socket Unix?**  
Pokud webový server běží na stejném hostiteli, příručka PHP doporučuje socket Unix. U TCP je nutné nastavit listen.allowed_clients, protože jinak se smí připojit kterákoli adresa. Volně dostupný port FastCGI umožňuje podle příručky libovolné provedení kódu.

**Chrání pm.max_requests před zranitelnostmi jako PHP2Shell?**  
Ne. pm.max_requests nahradí worker po pevném počtu požadavků a pomáhá hlavně proti únikům paměti v rozšířeních. Proti zranitelnosti v interpretu pomůže jen aktualizace s následným restartem všech workerů.

## Zdroje

- [Příručka PHP: FastCGI Process Manager](https://www.php.net/manual/en/install.fpm.php)
- [Příručka PHP: Konfigurace FPM](https://www.php.net/manual/en/install.fpm.configuration.php)
- [php.net: Vydání PHP 5.3.3](https://www.php.net/releases/5_3_3.php)
- [php.net: Bezpečnostní oznámení](https://www.php.net/)
