Jump to content

Required changes when going from mod_php to php-fpm


NotionCommotion

Recommended Posts

One of my virtual hosts contained php_value upload_max_filesize 8M which resulted in error when running as php-fpm.  Also, looks like .htaccess files are no longer used.  Any other gotcha's???

Reading up on it, looks like I want to move all .htaccess instructions to a https://www.php.net/manual/en/configuration.file.per-user.php file.  Should be straight forward enough.

Looking at https://www.php.net/manual/en/configuration.changes.php, looks like I should scan /etc/httpd/* as well as any virtual sites defined elsewhere for "php_" and move these requirements elsewhere.  Will this also have to be a per directory .user.ini file?  Reason I ask is I always thought it was better performance to when possible use apache's conf file than a .htaccess file.

Link to comment
Share on other sites

.htaccess is an Apache configuration file. It is not a PHP configuration file. Odds are that most of what's in there cannot be copied into a per-user file - which you shouldn't be using anyway, that should be a pool configuration.

Read up on how php-fpm works before you continue with this.

Link to comment
Share on other sites

5 minutes ago, requinix said:

.htaccess is an Apache configuration file. It is not a PHP configuration file. Odds are that most of what's in there cannot be copied into a per-user file

Good.  Likely anything in .htaccess which contains php_* is suspect, right?
 

5 minutes ago, requinix said:

a per-user file - which you shouldn't be using anyway, that should be a pool configuration.

Thanks, I will look into it.

 

6 minutes ago, requinix said:

Read up on how php-fpm works before you continue with this.

Any recommendations who to trust?  Maybe one of these?

Link to comment
Share on other sites

30 minutes ago, NotionCommotion said:

Good.  Likely anything in .htaccess which contains php_* is suspect, right?

Well, yeah. php_value/flag and php_admin_value/flag.

30 minutes ago, NotionCommotion said:

Any recommendations who to trust?  Maybe one of these?

Who to trust? Check the domain.

Oh, and if their most recent news is from 2011, maybe skip that one.

Link to comment
Share on other sites

I mean, of the four you listed:
- cwiki.apache.org - good place for Apache information
- php-fpm.org - sounds official, but PHP already has a domain for stuff so what is this supposed to be?
- www.php.net - good
- linux.die.net - so maybe this one isn't so obvious, but they're a great place to find man pages online

If you want to learn about php-fpm then probably the best place to start looking would be php.net.

But beyond that, install php-fpm on a 'nix based system and look at the configuration files they start you out with. Presumably the people who wrote them knew what they're doing, right?

Link to comment
Share on other sites

Thanks requinix.  Will do.

I originally thought that www.php.net would be best but it is a little sparse, and I think only has https://www.php.net/manual/en/book.fpm.php.  And it doesn't explain "how php-fpm works" but only the directives.

Yes, I've been going through the configuration files.  Threw me for a loop when /etc/php.ini went missing.  I since found it in /etc/opt/remi/php73/php.ini.  Related, it seems like I will not be using /etc/php-fpm.d/*conf, but instead /etc/opt/remi/php73/php-fpm.d/*conf.  I think I am going down the right path.

Link to comment
Share on other sites

You are looking at the function reference. The installation docs... aren't much better.

You know how your web server has one main process and then uses multiple child processes to do stuff? (In general.) php-fpm does the same thing. There's a fair bit about that you can configure, but unless you're setting up and fine-tuning a production environment, the default files you get will work fine.

Link to comment
Share on other sites

I looked both at the function references and the installation docs and even the comments.  Not too impressive.

Part of my difficulty is trying for the first time to have multiple versions of php available at the same time.  I think that is why all my normal /etc/php.ini files are located elsewhere, and evidently, I am using a https://www.softwarecollections.org/en/.  I just uninstalled everything and installed a single version.

I now have the following relevant files /etc

drwxr-xr-x   6 root root      121 Aug 25 17:10 httpd
drwxr-xr-x   2 root root     4096 Aug 25 19:43 php.d
-rw-r--r--   1 root root     4937 Jul 30 15:30 php-fpm.conf
drwxr-xr-x   2 root root       21 Aug 25 19:43 php-fpm.d
-rw-r--r--   1 root root    63437 Jul 30 15:30 php.ini
drwxr-x---   2 root root       35 Aug 25 15:38 phpMyAdmin
drwxr-xr-x   2 root root     4096 Aug 25 19:43 php-zts.d

I don't recall if I previously had /etc/php.d and php-zts.d, but expect I did.

All my virtual hosts are in /etc/httpd/virtualhosts/*.conf, and they all operate but without PHP because mod_php is not installed.  I am pretty sure I should leave them there, but somehow instruct them to use php-fpm.  Not sure, but looks like I create pools in /etc/php-fpm.d/*conf, and not individual virtualhosts in this directory.  Am I going down the right path?

 

Link to comment
Share on other sites

Okay, I added the following ProxyPassMatch directive to the httpd virtual host and php works and php.info shows: Server API    FPM/FastCGI

<VirtualHost *:80>
    ServerName testing.tapmeister.com
    DocumentRoot /var/www/testing/public
    <Directory "/var/www/testing/public">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
        RewriteEngine On
    </Directory>
    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/testing/public/$1
    DirectoryIndex /index.php index.php
</VirtualHost>

I have the default out of the box pool located at /etc/php-fpm.d/www.conf, and it listens on 127.0.0.1:9000, thus this virtualhost uses that pool, true?  My virtualhost doesn't use the name /etc/php-fpm.d/www.conf somehow to determine this, but just the IP and port (assume tcp sockets and not unix sockets)?

4 hours ago, requinix said:

.htaccess is an Apache configuration file. It is not a PHP configuration file. Odds are that most of what's in there cannot be copied into a per-user file - which you shouldn't be using anyway, that should be a pool configuration.

So, if I wanted another virtualhost to a different upload_max_filesize, I can't put "php_value upload_max_filesize 16M" in the httpd virtualhost's conf file or associated .htaccess file, but would create a new pool which would contain "php_value[upload_max_filesize] = 16M"?  Instead of using file www.conf, I will probably name them either specific for a given sight or maybe "large_filesize.conf".

And if I wanted to create another virtualhost which would use a different version of PHP,  then I need some totally different directory structure such as  /etc/opt/remi/php56/.. and /etc/opt/remi/php73/.., and would create different pools for each?

As far as ports go, just use 127.0.0.1:9000, 127.0.0.1:9001, 127.0.0.1:9002, etc?

Link to comment
Share on other sites

8 hours ago, NotionCommotion said:

Reason I ask is I always thought it was better performance to when possible use apache's conf file than a .htaccess file

It's better to put your Apache configuration inside apache's main (or vhost) configuration file then disable .htaccess file processing.  However that's the kind of optimization that you only really need to do if you're trying to run a high traffic site and need every bit of performance you can get.  Making a change such as a new redirect or rewrite rule would then require editing the configuration and reloading apache.  Not a terrible thing but more cumbersome than editing the site-specific .htaccess.

3 hours ago, NotionCommotion said:

And if I wanted to create another virtualhost which would use a different version of PHP,  then I need some totally different directory structure such as  /etc/opt/remi/php56/.. and /etc/opt/remi/php73/.., and would create different pools for each?

Yes, if you want multiple versions of PHP then you need to have them all installed separately in a way that doesn't conflict.  Hopefully your package management system takes care of that for you.  For example, I use ubuntu and the ondrej/php PPA which installs the configurations into /etc/php with a sub-folder for the version and api type.  I use FPM so my configuration is in /etc/php/7.3/fpm/ with pools defined in /etc/php/7.3/fpm/pools.d/

3 hours ago, NotionCommotion said:

So, if I wanted another virtualhost to a different upload_max_filesize, I can't put "php_value upload_max_filesize 16M" in the httpd virtualhost's conf file or associated .htaccess file, but would create a new pool which would contain "php_value[upload_max_filesize] = 16M"?  Instead of using file www.conf, I will probably name them either specific for a given sight or maybe "large_filesize.conf".

Yes.  You could do a per-site setup, per user, or something different.  That's pretty much up to you and what you find most convinent.  What I prefer to do is create a separate pool for each system user that hosts sites.  I configure that pool with settings appropriate for their site and also configure it to run using their user account so there's no need really to deal with permission problems when the site whats to manipulate the files.  For example, a typical pool configuration might look something like:

[kicken]
prefix = /var/run/php7-fpm
user = $pool
group = www-data
listen.owner = www-data
listen.group = www-data
listen.mode = 0600
listen = $pool.sock
php_value[error_log] = /var/log/php7-fpm/$pool-error.log
php_value[session.save_path] = /var/lib/php7/$pool/sessions
php_flag[log_errors] = on
php_value[memory_limit] = 32M
php_value[upload_max_filesize] = 500M
php_value[post_max_size] = 501M
php_value[max_input_vars] = 5000

I made a copy of the default www pool when I first set things up and made some general changes (like error log, session path, using $pool instead of hard-coded names) and save that as a template.  Each time I need to add a new pool I just copy that template, rename the pool and make tweaks if necessary.  I prefer using unix sockets vs TCP sockets as /var/run/php7-fpm/kicken.sock is easier to remember than 127.0.0.1:9038 or whatever port you want to use for that pool.

On the apache side of things, I have a separate configuration file for all the PHP stuff that looks like

Define PHP7_POOL_DEFAULT "proxy:unix:/var/run/php7-fpm/www-data.sock|fcgi://localhost"
Define PHP7_POOL_KICKEN "proxy:unix:/var/run/php7-fpm/kicken.sock|fcgi://localhost"
Define PHP7_POOL_USERX "proxy:unix:/var/run/php7-fpm/userx.sock|fcgi://localhost"
Define PHP7_POOL_USERY "proxy:unix:/var/run/php7-fpm/usery.sock|fcgi://localhost"
Define PHP7_POOL_USERZ "proxy:unix:/var/run/php7-fpm/userz.sock|fcgi://localhost"

ScriptAlias /phpsource.cgi      /usr/lib/cgi-bin/php7-source
Action php-source /phpsource.cgi virtual
<FilesMatch "\.phps">
        SetHandler php-source
</FilesMatch>
<Directory /usr/lib/cgi-bin>
        Require all granted
</Directory>
<FilesMatch ".+\.ph(ar|p|tml)$">
        SetHandler ${PHP7_POOL_DEFAULT}
</FilesMatch>

The pool's are setup as variables that can be used in the vhost configurations, and it sets up a default configuration.  I set mine up to support highlighted .phps extensions also using a traditional CGI setup, but that can be skipped/ignored.  

In each vhost I set it to the right pool by giving it it's own FilesMatch with the appropriate handler.

<VirtualHost *:443>
        ServerName aoeex.com
        ServerAlias www.aoeex.com
        <FilesMatch ".+\.ph(ar|p|tml)$">
                SetHandler ${PHP7_POOL_KICKEN}
        </FilesMatch>
</VirtualHost>

Setting up multiple versions is just a matter of installing each version's php-fpm package, configuring a pool for that version, and pointing apache to whatever socket you setup for that pool.  Fairly simple.  I used to have a 5.6 setup going as well due to some old third-party software but I was finally able to move to single 7.3 version recently.  Ideally you'd want to only have a single version going, and only use multiple versions if you really need to for some specific reason.

 

  • Great Answer 1
Link to comment
Share on other sites

Thank kicken,

Nice comprehensive help.  Good to know I am mostly going down the right path.

Ah, so the user is kicken, userx, usery, etc and the files are g+w so that www-data may write to them.  Makes sense.  Does $pool resolve to [kicken] (or whatever is in this first block)?

Was considering unix sockets, and will do so.  I see my use of ProxyPassMatch is not needed.  I thought its use was probably not appropriate and will change.

Does your vhost not need the typical <Directory "/var/www/aoeex/public">...<Directory>?  How does it know where your actual files are?

What is this part all about?

ScriptAlias /phpsource.cgi      /usr/lib/cgi-bin/php7-source
Action php-source /phpsource.cgi virtual
<FilesMatch "\.phps">
        SetHandler php-source
</FilesMatch>

Thanks!

Edited by NotionCommotion
Link to comment
Share on other sites

1 hour ago, NotionCommotion said:

Ah, so the user is kicken, userx, usery, etc and the files are g+w so that www-data may write to them.  Makes sense.  Does $pool resolve to [kicken] (or whatever is in this first block)?

PHP will end up running as user kicken, userx, usery etc so the files don't need g+w.  The PHP files actually don't even need group www-data as apache doesn't really mess with them, but non-php files need it and g+r so they can be served.  $pool does resolve to whatever the name of the pool is in the brackets (minus the brackets themselves).

1 hour ago, NotionCommotion said:

Does your vhost not need the typical <Directory "/var/www/aoeex/public">...<Directory>?  How does it know where your actual files are?

It's all there, I just trimmed out the more or less standard/irrelevant stuff.  My actual config is much longer with rewrite rules, redirect, special paths, etc.

1 hour ago, NotionCommotion said:

What is this part all about?

To enable source highlighting.  Ignore it if you don't need that feature.

 

Link to comment
Share on other sites

Rewrites are handled by apache at the early stages of the request, prior to any of the PHP stuff.  No need to adjust anything there.

Using PHP-FPM you're effectively separating apache and php.  A request comes in and apache does everything it needs to do up to the point it determines that the request is for a *.php file.  Once it determines that it pass the request over to PHP-FPM which will process it and pass back the results which apache then can run any configured post-processing on before sending on to the user.

 

Link to comment
Share on other sites

99.9% of the way there.  By the way, I spent a fair amount of time looking for direction, and found nothing as good as your earlier post!

Following you lead, I have the following pool.

Define PHP7_POOL_DEFAULT "proxy:unix:/var/run/php-fpm/apache.sock|fcgi://localhost"

But get the following error:

ERROR: [pool apache] the prefix '/var/run/php-fpm' does not exist or is not a directory

I fixed this by executing:

sudo mkdir /var/run/php-fpm

But after rebooting the server, the error returned.

I found that /var/run/ is a symlink to /run/, and also tried doing creating this directory as well.  Should I have manually created the socket directory?  How do I make it persist?


Also, according to https://medium.com/@jacksonpauls/moving-from-mod-php-to-php-fpm-914125a7f336, one needs to add the following
to prevent additional errors for non-existant files: AH01071: Got error ‘Primary script unknown\n’.  I haven't done so.  Is their advice valid?

<FilesMatch \.php$>
  <If "-f %{SCRIPT_FILENAME}">
    SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
  </If>
</FilesMatch>


Thanks!

Edited by NotionCommotion
Link to comment
Share on other sites

 

Maybe adding RuntimeDirectory=/run/php-fpm to the service?

cat /usr/lib/systemd/system/php73-php-fpm.service

# It's not recommended to modify this file in-place, because it
# will be overwritten during upgrades.  If you want to customize,
# the best way is to use the "systemctl edit" command.

[Unit]
Description=The PHP FastCGI Process Manager
After=syslog.target network.target

[Service]
Type=notify
EnvironmentFile=/etc/opt/remi/php73/sysconfig/php-fpm
ExecStart=/opt/remi/php73/root/usr/sbin/php-fpm --nodaemonize
ExecReload=/bin/kill -USR2 $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

 

Link to comment
Share on other sites

2 hours ago, NotionCommotion said:

Following you lead, I have the following pool.


Define PHP7_POOL_DEFAULT "proxy:unix:/var/run/php-fpm/apache.sock|fcgi://localhost"

But get the following error:


ERROR: [pool apache] the prefix '/var/run/php-fpm' does not exist or is not a directory

I fixed this by executing:


sudo mkdir /var/run/php-fpm

But after rebooting the server, the error returned.

I found that /var/run/ is a symlink to /run/, and also tried doing creating this directory as well.  Should I have manually created the socket directory?  How do I make it persist?

lol remember the forum downtime a few weeks ago? This exact problem.

php-fpm isn't nice enough to create the directory itself so just choose another location for it. Such as /var/run without a subdirectory. Or, since you're running remi stuff, in a suitable place somewhere under /opt.

Link to comment
Share on other sites

21 minutes ago, requinix said:

lol remember the forum downtime a few weeks ago? This exact problem.

php-fpm isn't nice enough to create the directory itself so just choose another location for it. Such as /var/run without a subdirectory. Or, since you're running remi stuff, in a suitable place somewhere under /opt.

Really?  If it wasn't you, I wouldn't believe so.

I thought that /run (and thus /var/run as it is a symlink to /run) was RAM and not hard drive space and as such should be used (granted, I believe my VPS uses a SSD so maybe it doesn't matter).  I suppose I can make a symlink from /opt/somewhere to /run or do some special mounting, but then got to remember that I did so.

I like the idea of going to just /var/run or /run, but don't understand well enough to know if it is a good idea.  So, the actual path has no affect?  Is it kind of like  some listen for given port type of thing?  And for that matter, why is "preffix" set to it?

Link to comment
Share on other sites

2 hours ago, NotionCommotion said:

Really?  If it wasn't you, I wouldn't believe so.

From our Slack, August 3rd:

image.png

(later I moved the socket to somewhere else)

2 hours ago, NotionCommotion said:

I thought that /run (and thus /var/run as it is a symlink to /run) was RAM and not hard drive space and as such should be used (granted, I believe my VPS uses a SSD so maybe it doesn't matter).  I suppose I can make a symlink from /opt/somewhere to /run or do some special mounting, but then got to remember that I did so.

It is (probably) RAM, and it is definitely suited for stuff like sockets and PID files, but when you have to worry about creating a php-fpm subdirectory manually then that's a decent reason to think about moving the file somewhere else.

/var/run/$pool.sock is fine if you want to make use of the RAM-ness. Or you could trade in the RAM-ness and gain the "php-fpm" subdirectory by putting it in the remi paths that already exist.

Or you could manually create /var/run/php-fpm every time, such as with a @reboot cronjob. It really isn't that important what you do.

2 hours ago, NotionCommotion said:

I like the idea of going to just /var/run or /run, but don't understand well enough to know if it is a good idea.  So, the actual path has no affect?  Is it kind of like  some listen for given port type of thing?  And for that matter, why is "preffix" set to it?

- No effect, nope. (You're still subject to restrictions imposed by file ownership and permissions, of course.)
- A socket file is a lot like a regular network (TCP/IP) socket. But a file. And a little nicer for things that only need to talk within the same system.
- "prefix" is just what they called it. Apache is looking for the socket file and discovering that the parent directory doesn't exist. Why call it "prefix"? Dunno.

Link to comment
Share on other sites

Thanks again!  All perfect.

On 8/25/2019 at 7:32 PM, kicken said:

I used to have a 5.6 setup going as well due to some old third-party software but I was finally able to move to single 7.3 version recently.  Ideally you'd want to only have a single version going, and only use multiple versions if you really need to for some specific reason.

I ended up installing 7.3 the normal way, and it uses /etc/php.ini,  /etc/php-fpm.conf, etc, and 7.2 as the one off and it uses /etc/opt/remi/php72/*.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.