Answer
The clear_env directive controls whether each PHP‑FPM worker inherits the parent environment or starts with a clean environment; it works the same for pm = static and pm = dynamic. When clear_env = yes (the default) only variables explicitly listed in env[] are passed to workers; when clear_env = no the worker receives the full Docker environment. Regarding memory overhead, a static pool keeps a fixed number of children, so total memory ≈ pm.max_children × (php_memory_limit + worker overhead) and is predictable. A dynamic pool starts with pm.start_servers children and can grow up to pm.max_children; idle spare servers still consume memory, so under low traffic the footprint can be higher than static, while traffic spikes can cause memory spikes up to the same maximum limit.
Likely explanation
The behavior of clear_env is independent of the process manager because it is applied when each child is forked; switching between static and dynamic does not change how the environment is propagated. The memory difference stems from how many children are alive at any moment: static maintains a constant count, whereas dynamic adds and removes children based on request rate, leading to variable memory usage that can approach the same upper bound but may waste RAM when idle.
Confirmed facts
- PHP‑FPM enforces
pm.max_children strictly; excess connection attempts are queued or rejected with 503.
- Each child’s resident memory is roughly the value of
php_memory_limit plus a small constant overhead (≈2‑5 MiB).
- If the sum of child memory exceeds the container’s cgroup memory limit, the OOM killer will terminate workers, causing sudden drops in available processes.
Recommended steps for this case
- Decide whether you need the Docker environment inside workers. If yes, set
clear_env = no in www.conf (or pool config); otherwise keep the default yes and list required variables with env[VAR] = $VAR.
- Estimate per‑child memory:
php_memory_limit (e.g., 128M) + ~10 MiB overhead.
- Calculate the maximum children that fit:
max_children = floor(container_memory_limit / per_child_memory).
- If traffic is steady or predictable, use
pm = static and set pm.max_children to the value from step 3.
- If traffic varies and you want to avoid over‑provisioning, use
pm = dynamic with pm.start_servers, pm.min_spare_servers, pm.max_spare_servers all ≤ the value from step 3, and keep pm.max_children at that same ceiling.
- Reload PHP‑FPM (
kill -USR2 $(cat /run/php/php-fpm.pid) or docker restart) and verify.
Missing diagnostic detail
To confirm that the chosen pm.max_children fits safely, please provide the observed average resident memory size of a single PHP‑FPM child (e.g., from ps -o rss,comm -C php-fpm or container metrics). If the measured size differs significantly from the estimate, adjust the calculation accordingly.