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/open in new window .

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 hereopen in new window, in the "Proxy via handler" section.

Credit to zEitEr on the forumopen in new window for finding/posting the solution.

per-User disable_functions

With php-fpm, the disable_functions php.ini option cannot have items added later. As such, handling different values for this setting for different Users requires a different approach, as compared to simple flags or string variables.

In this example, we want to allow proc_open and proc_close for one User, but block it for everyone else - we need to remove those functions from the disable_functions list.

The idea with this approach is to not use it at all in the php.ini, to allow it to be set on a per-User basis in the Users' php-fpmXX.conf files. We'll ensure that you can still use a default list of disable_functions values for all Users, without needing to set it for each account. We'll be using the Global Custom Templates to set the defaults for everyone, and the per-User global php tokens for any account where you want to change the value. Related forum threadopen in new window

NOTE: It's important to note that this removes the disable_functions for cron/CLI php calls, globally for all accounts. Only use this guide if you're ok with this.

  1. We'll need to disable the disable_function from the main php.ini. You have 2 options, either disable the custombuild secure_php option (which prevents a few other security measures), or simply disable custombuild from wriring the php.ini file. For this example, we'll just disable the writing of the php.ini, and manually comment out the disable_functions line from the php.ini.
    da build set secure_php yes
    da build set php_ini yes
    da build php_ini
    da build set php_ini no
    php --ini
    
    Where the above should set the most recent secured php.ini file, disable the writing of the php.ini, and show you which php.ini you'll need to edit (Loaded Configuration File), find the disable_functions line, and comment it out.
  2. Create 2 system templates to setup and use the disable_functions within all Users' php-fpmXX.conf files.
    1. Create: /usr/local/directadmin/data/templates/custom/php-fpm.conf.custom1 with code:
      |?DF=php_admin_value[disable_functions] = exec,system,passthru,shell_exec,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|
      
      This is your default disable_functions list, so set it however you'd like most Users to have it.
    2. Create: /usr/local/directadmin/data/templates/custom/php-fpm.conf.custom2 with code:
      |DH|
      
      This takes the list that you set above, and adds it into the CUSTOM2 token for each Users' php-fpmXX.conf file.
  3. Update all User's php-fpmXX.conf files:
    da build rewrite_confs
    
    In theory, all Users are now re-secured with the new disable_functions list.
  4. For any User where you wish to change their disable_functions list:
    1. go to: Admin Level » Custom HTTPD Configurations » domain.com : click php-fpm.conf X.X
    2. In the php-fpm Global |CUSTOM1| textarea, add code:
      |?DF=php_admin_value[disable_functions] = exec,system,passthru,shell_exec,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname|
      
      where in this example, we've removed proc_close and proc_open. Hit "Save".
    3. Restart php-fpm, eg. for php-fpm 8.3:
      service php-fpm83 restart
      
Last Updated: