won’t talk about pros and cons of PHP-FPM, FastCGI, APC and all that stuff, there are tons of articels around, see also the links below.
main urge was to speed up PHP with APC, get rid of preforked Apaches, run PHP scripts as their native user and many more.
just giving an overview how I’ve easily set it up here, having different „customers“ programming their own PHP scripts and also Debian packages ready to run.
intro
main requirements have been:
- Opcode Cache
- every PHP script should run as the same user the virtualhost is owned
- Debian packages should still run as www-data
- run Apache as MPM Worker
install
install all the required packages.
aptitude install apache2-mpm-worker libapache2-mod-fastcgi php5-fpm php-apc
enable needed modules.
a2enmod actions alias fastcgi
config
create config file for PHP-FPM and FastCGI in /etc/apache2/conf.d/php5-fpm.
# Configure all that stuff needed for using PHP-FPM as FastCGI # Set handlers for PHP files. # application/x-httpd-php phtml pht php # application/x-httpd-php3 php3 # application/x-httpd-php4 php4 # application/x-httpd-php5 php <FilesMatch ".+\.ph(p[345]?|t|tml)$"> SetHandler application/x-httpd-php </FilesMatch> # application/x-httpd-php-source phps <FilesMatch ".+\.phps$"> SetHandler application/x-httpd-php-source # Deny access to raw php sources by default # To re-enable it's recommended to enable access to the files # only in specific virtual host or directory Order Deny,Allow Deny from all </FilesMatch> # Deny access to files without filename (e.g. '.php') <FilesMatch "^\.ph(p[345]?|t|tml|ps)$"> Order Deny,Allow Deny from all </FilesMatch> # Define Action and Alias needed for FastCGI external server. Action application/x-httpd-php /fcgi-bin/php5-fpm virtual Alias /fcgi-bin/php5-fpm /fcgi-bin-php5-fpm <Location /fcgi-bin/php5-fpm> # here we prevent direct access to this Location url, # env=REDIRECT_STATUS will let us use this fcgi-bin url # only after an internal redirect (by Action upper) Order Deny,Allow Deny from All Allow from env=REDIRECT_STATUS </Location> FastCgiExternalServer /fcgi-bin-php5-fpm -socket /var/run/php5-fpm.sock -pass-header Authorization
for every PHP file a Handler will be set and also some access restrictions. for the Handler a virtual Action is defined. virtual here means it will not be checked if the given file exists. the Alias is needed in any case, especially later when you go for running PHP as an other user. be careful with the Alias directory-path, don’t use any slashes as described here.
at this point you should be already able to run PHP scripts with PHP-FPM as user www-data with APC enabled. but the main focus here is on running PHP scripts just as an other user. lets go forward.
let’s party
create a new user and add www-data into its group.
adduser --disabled-login tux adduser www-data tux
create the documentroot and set permissions.
mkdir -p /var/www/tux/htdocs chown -R tux:tux /var/www/tux chmod 755 /var/www/tux chmod 750 /var/www/tuc/htdocs
looks like overkill to have only the htdocs directory, but be prepared for some directories like log, session, tmp, …
a small index.php for tux could have the following code. keep care of ownership and permissions.
<?php system('whoami'); phpinfo(); ?>
splash into the pool
create an additional PHP-FPM pool for user tux by just copying www.conf.
[tux] user = tux group = tux listen = /var/run/php5-fpm-tux.sock pm = dynamic pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 chdir = /
restart PHP-FPM.
service php5-fpm restart
check if new PHP-FPM instances are running.
ps -ef | grep php-fpm
root 12065 1 0 15:36 ? 00:00:00 php-fpm: master process [...] www-data 12066 12065 0 15:36 ? 00:00:00 php-fpm: pool www www-data 12067 12065 0 15:36 ? 00:00:00 php-fpm: pool www tux 12068 12065 0 15:36 ? 00:00:00 php-fpm: pool tux tux 12069 12065 0 15:36 ? 00:00:00 php-fpm: pool tux
create a virtual host config for which tux is the owner.
<VirtualHost *:80> ServerName tux.kmplabs.org ServerAdmin webmaster@kmplabs.org DocumentRoot /var/www/tux/htdocs <Directory /var/www/tux/htdocs/> Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny Allow from all </Directory> Alias /fcgi-bin/php5-fpm /fcgi-bin-php5-fpm-tux FastCgiExternalServer /fcgi-bin-php5-fpm-tux -socket /var/run/php5-fpm-tux.sock -pass-header Authorization ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
enable new virtual host and restart apache.
a2ensite tux service apache2 restart
that’s it!
references
quick & dirty
use php-fpm with apache in debian (mod_fastcgi), en, 2013-02-02
Apache2 mpm worker + fastcgi + php5-fpm on debian, en, 2012-11-02
Apache Worker, FastCGI, PHP-FPM and APC, en, 2012-01-29
explaining differences, more in detail
installing apache + mod_fastcgi + php_fpm on …, en, 2011-04-08
PHP-FPM: Mit der Lizenz zum Verwalten, de, 2011-07-20
Apache2, PHP-FPM, FastCGI and APC Opcode Cache, fr, 2010-08-14
some ideas why to go for FastCGI and Opcode Cache
FastCGI with a PHP APC Opcode Cache, en, 2009-07-07
Hello,
this is a very nice howto.
I have one question:
Why do you add www-data into tux’s group? Is this not a security problem, because www-data now has again the same permissions like the folder has the group www-data?
Do I need to add www-data to the users group?
Is it possible to avoid this with suexec?
Thank you very much!
Flo
@Flo: I’m doing this in my own setup with Nginx/Lighttpd since ~2 years. It’s the best way to control permissions, because you can add whoever you wan’t to the users group for same access as the webserver. With the group permissions you can hide include-dirs or other internal stuff (like config file from web apps) from the webserver and/or others easily. You don’t need the world-role in permissions anymore. It’s just a great thing, because the user is the real owner of his web-directory – including his own group 🙂
@Hödlmoser: „be careful with the Alias directory-path“ – you saved my ass after hours of googl’ing. Stupid bug, realy 😛
Hi sorry to bother you first of all nice post, I have already set a working lamp with php5-fpm the only problem is to be able to highlight sources with phps extensions I try your config without deny from all on *.phps files I suppose I have to do something like
Action application/x-httpd-php-source /fcgi-bin/php5-fpm virtual
but what is the correct syntax ???? I found nothing on php5-fpm doc. I want to use source highlight as I want to share sources on a educationnal project do you manage to make highlitement working with php5-fpm ???? For now whenever I am using a GET on myserver.com/myscript.phps it is downloaded. Shame on me !
[…] To install Apache2, and PHP FPM, I will be using some of the instructions available at http://blog.kmp.or.at. […]
keep an eye on listen.owner and listen.group in fpm pool config! you need that properties since the latest security fix for php5!
BAM!!! I just ran through another setup using suexec – the object was similar to what you accomplished, but he wasn’t as specific about what went where, or why – or how to test things on your way through the setup. That guys setup might have some advantages, but I can’t see what they would be. The disadvantages was having scripts here and there to do this and that and the other thing … convoluted to say the least.
You’rs just worked FLAWLESSLY first time through, no fixing errors like I was doing with the other one. I spent 2 hours messing with the other one, crashed my vps in the process … less than 30 min and I’m up and running THANK YOU SO MUCH!!!
Excellent thank you.
If copying per user config from http://www.conf, remember to change the pool name as well.
Else if you have multiple sites, they will fail trying to use the same pool name I believe.
“
; Start a new pool named ‚www‘.
; the variable $pool can we used in any directive and will be replaced by the
; pool name (‚www‘ here)
[www]
„
This is by far the most fine guide I’ve ever seen. Just a note for those who have Apache 2.4: Allow/Deny is deprecated and must be replaced as:
Order Deny,Allow -> Require all denied
Deny from All -> [delete line]
Allow from env=REDIRECT_STATUS -> Require env REDIRECT_STATUS
or just use https://httpd.apache.org/docs/current/mod/mod_access_compat.html
Wow this one took me a while to find. Thank you for posting.
Ok, I’ve been using this setup for a while, mostly undisturbed except for adding a few sites. I just set it up on a newer machine running Debian 8 with Apache 2.4, and php 5.6 and looked a little closer at phpinfo output, and it raised a few questions.
1. Php 5.6 has Zend Opcache built in, although it doesn’t have user caches. APC has user caches as well. APCu is only user caches, and can be used to augment Zend Opcache. So my question is – when I installed php-apc, does it override Zend Opcache and use APC instead, or is it now running Opcache with APCu? It appears that is running Opcache / APCu, and this is how I’d like it to be operating.
2. I’ve never used suEXEC so forgive me if this is a dumb question … This method uses „a kind of suEXEC“ – why not use suEXEC? Is it a security hole, or a pain to manage?
3. Is there a relatively easy way to analyze performance of the opcache? A way to determine if the user maybe HAS a user cache, but the site is instead using the server-wide cache in error?
thanks for all your remarks concerning Debian Jessie and Apache 2.4. but I haven’t upgraded my Apache and its VM to Debian Jessie yet. so I’v no experience. when I go for upgrade I will update this post, for sure.
Oh, and one more thing I wanted to add unrelated to the previous question:
If you’re using Apache 2.4, DEFINITELY do what the guy above suggests, or it won’t work. The first setup I did in December was on 2.2 and went flawlessly. This time I beat my head against the wall changing this and that and the other thing – then I found the comment up there about 2.4 …
Well by that time I had changed too much chasing the issue, so I wiped it out and started over – this time following Iskrens advice. His advice is solid, but it’s not 100% complete.
In the php5-fpm config file, there are other places. His example uses the entry in , but above it there are two other entries in sections that have to be updated accordingly.
In the virtualhost config file, there is an order allow/deny allow from all. Use the Apache 2.4 way here too:
order allow/deny
Allow from all
becomes „Require all granted“
in Debian Stretch libapache2-mod-fastcgi got deprecated https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=835374 so just disable php5-fpm conf, enable php7.0-fpm conf and also proxy-fcgi module.
for your virtual hosts replace Alias and FastCgiExternalServer by
<FilesMatch ".+.ph(p[3457]?|t|tml)$">
SetHandler "proxy:unix:/run/php/php7.0-fpm-tux.sock|fcgi://localhost"
</FilesMatch>
thats it.