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 ofphp_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:
- php.ini (master configuration)
- Pool-specific php-fpm.conf (overrides php.ini)
- .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:
- Check pool-specific error logs
- Verify the pool is actually being used by your vhost
- Run
phpinfo()
from a script in that vhost - Restart PHP-FPM after changes:
sudo systemctl restart php7.4-fpm