PHP-FPM
How to switch to PHP-FPM
Use the cumulative guide maintained in general section .
Per-user php.ini settings in php-fpm
If you need to make changes to the php.ini in php-fpm, you can do so from Admin Level -> Custom Httpd Configuration -> domain.com: php-fpm 5.x and in the 2nd textarea called |CUSTOM2|. The sytnax is different from a php.ini and might look like:
php_value[memory_limit] = 256M
where it might be php_value, php_admin_value, php_flag, php_admin_flag, etc. depending on the setting.
Example:
To alter the per-user disable_functions, eg to add mail to the list, set this in CUSTOM2:
php_admin_value[disable_functions] = exec,system,passthru,shell_exec,escapeshellarg,escapeshellcmd,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname,mail
Note that disable_functions
is special. The caveat is that you can not override what is already defined. You can only append to that array. The phpinfo() page will show disable_functions
from the CUSTOM2 section. To remove some functions from the disable_functions
array (to make them available for domains), the global customization is needed: https://docs.directadmin.com/webservices/php/secure-php/ .
You can alternatively turn on the** user_ini.filename** setting, read below.
Per-path php settings, controllable by the User
Enabled by default. Php run in cgi or php-fpm can edit their php.ini file, and set something like
user_ini.filename = ".user.ini"
which will allow some of the php.ini settings to be set by the User, by creating a .user.ini file in their public_html or other web paths, in cases like php-fpm, where .htaccess files are not available for php settings.
Related: http://php.net/manual/en/configuration.file.per-user.php
Why cannot I see /tmp/ content with PHP-FPM?
With CentOS 7, you may have noticed that even though your script may working as expected, you're not able to see the session files or temporary files in the /tmp folder.
The reason for this, is that with CentOS 7 supports a feature called:
PrivateTmp=true
What this feature does, is mounts /tmp
and /var/tmp
as private file systems, visible only to that process. So when php-fpm writes to /tmp
, it's not the /tmp
that you can see from ssh.. it's a virtual path, visible only to that process. Once the process stops, the virtual /tmp
is removed.
Man page from systemd.exec:
PrivateTmp=
Takes a boolean argument. If true, sets up a new file system namespace for the executed processes and mounts private /tmp and /var/tmp directories inside it, that
are not shared by processes outside of the namespace. This is useful to secure access to temporary files of the process, but makes sharing between processes via
/tmp or /var/tmp impossible. All temporary data created by service will be removed after service is stopped. Defaults to false.
If you don't like this behavior, edit /etc/systemd/system/php-fpm73.service
and set PrivateTmp=false. Reload daemon units and restart php-fpm to apply changes:
systemctl daemon-reload
systemctl restart php-fpm73
PHP version 7.3 in above example. Do the same for other versions.
WARNING: server reached max_children setting
If you are getting this error:
WARNING: [pool convoice] server reached max_children setting (10), consider raising it
To raise the limit globally, change directadmin.conf value first:
da config-set php_fpm_max_children_default 100
systemctl restart directadmin
Rewrite configs and restart "php-fpm" service:
da build rewrite_confs
systemctl restart php-fpm73
For a per-Domain setting change, go to:
Admin Level -> Custom Httpd Config -> domain.com: php-fpm55
When viewing the php-fpm custom config, in the |CUSTOM1| token area, set a higher value, eg:
|?MAX_CHILDREN=200|
and save. This should override the default value from the template.
I wish to have global custom PHP-FPM configuration
To create true global CUSTOM1 and CUSTOM2 pre tokens, loaded in before other tokens for the php-fpm.conf templates, all Users, all php versions, create the following files:
/usr/local/directadmin/data/templates/custom/php-fpm.conf.custom1
/usr/local/directadmin/data/templates/custom/php-fpm.conf.custom2
If either exists, they'll be added into their respective CUSTOM1 or CUSTOM2 tokens for all php-fpm.conf rewrites.
per-User global php CUSTOM tokens
With the more common use of the php version selector, you may want your custom php-fpm configs to span all php versions. 2 new textareas in the Custom Httpd Config -> domain.com: php-fpmXX page for "global php-fpm CUSTOM1" and "global php-fpm CUSTOM2"
You may edit configuration manually by modifying files:
/usr/local/directadmin/data/users/username/php/php-fpm.conf.custom1
/usr/local/directadmin/data/users/username/php/php-fpm.conf.custom2
which will be set into the CUSTOM1/CUSTOM2 tokens before the php-fpm73.conf.custom1
files (for example). But both global and per-php, if present, will end up into the same token.
When you save data into either of these fields, the CUSTOM1/CUSTOM2 tokens set to span all php versions that the User may select from. The bottom 2 boxes, as before, will only apply to that given php version.
There is also the "save to all php versions" which copies your data to all custom tokens for each php version. When checked, the CUSTOM1/CUSTOM2 tokens will be saved to the php-fpm customX files, for all active php versions (as set in the options.conf).
Example:
/usr/local/directadmin/data/users/username/php/php-fpm56.custom1
/usr/local/directadmin/data/users/username/php/php-fpm56.custom2
/usr/local/directadmin/data/users/username/php/php-fpm72.custom1
/usr/local/directadmin/data/users/username/php/php-fpm72.custom2
The php-fpmXX.conf
is only written for the active/selected php version. When a User changes their php version via the Domain Setup php selector, the custom changes set by the Admin would apply through all versions, without the need for another set of the custom settings.
php-fpm check before sending to AddHandler
If you access a php file through apache/php-fpm, but it does not exist, this will throw:
No input file specified
or
File not found.
A simple solution is to not pass it to php-fpm if it's missing, and let apache throw the usual 404 from the website's setup. To accomplish this, a simple <If ..> check tag can be added around the AddHandler in the VirtualHosts, to look for the REQUEST_FILENAME variable.
|*if HAVE_PHP1_FPM="1"|
<FilesMatch "\.(inc|php|phtml|phps|php|PHP1_RELEASE|)$$">
<If "-f %{REQUEST_FILENAME}">
#ProxyErrorOverride on
AddHandler "proxy:unix:/usr/local/php|PHP1_RELEASE|/sockets/|USER|.sock|fcgi://localhost" .inc .php .phtml .php|PHP1_RELEASE|
</If>
</FilesMatch>
|*endif|
as per the documentation here, in the "Proxy via handler" section.
Credit to zEitEr on the forum for finding/posting the solution.