Configuring PHP Settings in php-fpm Pool Configs vs php.ini: Best Practices for Nginx Environments


21 views

When working with PHP-FPM and Nginx, you have multiple layers for PHP configuration:

1. php.ini (global PHP configuration)
2. php-fpm.conf (master process configuration)
3. www.conf (or other pool-specific configurations)
4. .user.ini or .htaccess (per-directory overrides)

The syntax you've used is correct for PHP-FPM pool configuration files (typically found in /etc/php-fpm.d/). Here's the proper way to set these values:

php_admin_value[memory_limit] = 96M
php_admin_value[max_execution_time] = 120
php_admin_value[max_input_time] = 300
php_admin_value[post_max_size] = 25M
php_admin_value[upload_max_filesize] = 25M

Note the correction from php_post_max_size to just post_max_size and the recommendation to use php_admin_value instead of php_value for production environments as it prevents runtime overrides.

The configuration hierarchy works like this:

1. php.ini sets the baseline values
2. php-fpm.conf can override these
3. Pool-specific configs (www.conf) take highest precedence
4. Runtime ini_set() calls can override if allowed

Key point: When the same setting exists in both php.ini and php-fpm pool config, the pool configuration will take precedence.

Yes, you absolutely can (and often should) configure different PHP settings per virtual host. This is one of the powerful features of PHP-FPM. Example scenario:

# /etc/php-fpm.d/blog.conf
[blog]
user = blog-user
group = blog-group
listen = /var/run/php-fpm-blog.sock

php_admin_value[memory_limit] = 128M
php_admin_value[max_execution_time] = 60

# /etc/php-fpm.d/ecommerce.conf
[ecommerce]
user = ecom-user
group = ecom-group
listen = /var/run/php-fpm-ecom.sock

php_admin_value[memory_limit] = 256M
php_admin_value[max_execution_time] = 120

Then in your Nginx configs, you'd point each virtual host to its specific PHP-FPM socket.

Here's a complete example of setting up different configurations:

# Create new pool config
sudo nano /etc/php/8.2/fpm/pool.d/custom_app.conf

[custom_app]
user = custom-user
group = www-data
listen = /run/php/custom_app.sock

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6

php_admin_value[memory_limit] = 256M
php_admin_value[post_max_size] = 50M
php_admin_value[upload_max_filesize] = 48M
php_admin_value[max_execution_time] = 180

# Then in Nginx config
location ~ \.php$ {
    fastcgi_pass unix:/run/php/custom_app.sock;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
  • Always restart PHP-FPM after making changes: sudo systemctl restart php8.2-fpm
  • Use php_admin_value instead of php_value for security-sensitive settings
  • Monitor resource usage when setting different limits per host
  • Be consistent with your naming conventions for pool configs

When working with PHP-FPM and Nginx, you can indeed override php.ini settings at the pool level using the php_value and php_admin_value directives. Your example configuration is technically correct, though there's a small syntax improvement needed for post_max_size:

php_value[memory_limit] = 96M
php_value[max_execution_time] = 120
php_value[max_input_time] = 300
php_value[post_max_size] = 25M
php_value[upload_max_filesize] = 25M

The hierarchy of PHP configuration is important to understand:

  1. php.ini (master configuration)
  2. Pool-specific php-fpm.conf (overrides php.ini)
  3. .htaccess or runtime ini_set() (if allowed)

When a value is set in both php.ini and php-fpm conf, the php-fpm configuration will override the php.ini setting for that specific pool.

This approach actually provides significant advantages for multi-host environments:

; /etc/php/7.4/fpm/pool.d/ecommerce.conf
[ecommerce]
user = ecom_user
php_value[memory_limit] = 512M
php_value[max_execution_time] = 180

; /etc/php/7.4/fpm/pool.d/blog.conf
[blog] 
user = blog_user
php_value[memory_limit] = 128M
php_value[max_execution_time] = 60

Different memory limits per host are not problematic - PHP-FPM handles them as separate worker pools. However, consider:

  • Higher memory pools need adequate server resources
  • Monitor each pool's memory usage separately
  • Set appropriate pm (process manager) settings per pool

Typical scenarios where pool-specific settings excel:

; Development environment
php_value[display_errors] = On
php_value[error_reporting] = E_ALL

; Production environment  
php_admin_value[display_errors] = Off
php_admin_value[log_errors] = On

Remember: php_admin_value cannot be overridden at runtime, while php_value can be changed via ini_set().

If settings don't apply as expected:

  1. Check pool-specific error logs
  2. Verify the pool is actually being used by your vhost
  3. Run phpinfo() from a script in that vhost
  4. Restart PHP-FPM after changes: sudo systemctl restart php7.4-fpm