I've integrated this into virtualmin for automatically creating/removing fpm pools. Here's the guide which applies to both centos and debian servers :
1- Install latest version of php-fpm using remi or dotdeb repository.
** Apache 2.4 is shipped with Centos 7.x or Debian 8.x so you can use these default packages instead **
2- Compile latest version of apache 2.4.x from source :
- Install pcre development package :
(yum install pcre-devel) or (apt-get install libpcre3-dev)
cd /usr/src
wget http://mirror.olnevhost.net/pub/apache/apr/apr-1.5.2.tar.bz2
wget http://mirror.olnevhost.net/pub/apache/apr/apr-util-1.5.4.tar.bz2
wget http://mirror.olnevhost.net/pub/apache/httpd/httpd-2.4.25.tar.bz2
tar -jxf httpd-2.4.25.tar.bz2
tar -jxf apr-1.5.2.tar.bz2
tar -jxf apr-util-1.5.4.tar.bz2
wget http://mirror.olnevhost.net/pub/apache/apr/apr-util-1.5.4.tar.bz2
wget http://mirror.olnevhost.net/pub/apache/httpd/httpd-2.4.25.tar.bz2
tar -jxf httpd-2.4.25.tar.bz2
tar -jxf apr-1.5.2.tar.bz2
tar -jxf apr-util-1.5.4.tar.bz2
mv apr-1.5.2 /usr/src/httpd-2.4.25/srclib/apr
mv apr-util-1.5.4 /usr/src/httpd-2.4.25/srclib/apr-util
mv apr-util-1.5.4 /usr/src/httpd-2.4.25/srclib/apr-util
cd httpd-2.4.25
./configure --prefix=/opt/apache2 --with-mpm=event --enable-rewrite --enable-ssl --enable-proxy-fcgi --with-included-apr
./configure --prefix=/opt/apache2 --with-mpm=event --enable-rewrite --enable-ssl --enable-proxy-fcgi --with-included-apr
chown -R nobody /usr/src
sudo -u nobody make
make install
You can use my simple init startup script for centos or debian.(End of the article) enable it at boot startup :sudo -u nobody make
make install
cd /etc/init.d
(SEE END OF THIS ARTICLE, SAVE THE INIT FILE AS httpd24)
(service httpd stop OR service apache2 stop)
(chkconfig httpd off OR chkconfig apache2 off)
(service httpd stop OR service apache2 stop)
(chkconfig httpd off OR chkconfig apache2 off)
chmod a+x httpd24
chkconfig httpd24 on- Now edit /opt/apache2/conf/httpd.conf, comment the following lines :
#<Directory />
# AllowOverride none
# Require all denied
#</Directory>
- comment out the following lines :
LoadModule ssl_module modules/mod_ssl.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule actions_module modules/mod_actions.so
- Enable expires and deflate modules for more performance :
LoadModule expires_module modules/mod_expires.so
LoadModule deflate_module modules/mod_deflate.so
- Alter User and Group line to appropriate user and group.LoadModule actions_module modules/mod_actions.so
- Enable expires and deflate modules for more performance :
LoadModule expires_module modules/mod_expires.so
LoadModule deflate_module modules/mod_deflate.so
( www-data for debian, apache for centos )
- Add mod_expires and mod_deflate configurations to the end of httpd.conf file :<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# Default directive
# ExpiresDefault "access plus 15 days"
# My favicon
ExpiresByType image/x-icon "access plus 15 days.
# Images
ExpiresByType image/gif "access plus 15 days"
ExpiresByType image/png "access plus 15 days"
ExpiresByType image/jpg "access plus 15 days"
ExpiresByType image/jpeg "access plus 15 days"
# CSS
ExpiresByType text/css "access 15 days.
# Javascript
ExpiresByType application/javascript "access plus 15 days"
</IfModule>
<IfModule deflate_module>
<Location />
SetOutputFilter DEFLATE
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|swf)$ no-gzip dont-vary
</Location>
</IfModule>
NOTE: make sure that you have proxy and proxy_fcgi modules enabled in your apache config file, check your httpd.conf in Centos or run the following commands in Debian:
a2enmod proxy
a2enmod proxy_fcgi
3- Configure virtualmin to use the new installed apache2 :
Virtualmin -> Webmin -> Servers -> Apache webserver -> Module config -> System configuration :
root:/opt/apache2
executable:/opt/apache2/bin/httpd
apachectl:/opt/apache2/bin/apachectl
command to start:/etc/init.d/httpd24 start
command to stop: /etc/init.d/httpd24 stop
apply configuration:/opt/apache2/bin/apachectl graceful
apache pid file:/opt/apache2/logs/httpd.pid 4- Integrate php-fpm to virutalmin :
Virtualmin -> System Settings -> Server Templates -> Default Settings -> Apache website
Add the following line after DirectoryIndex line of the 'Directives and settings for new websites' section :
<FilesMatch "\.php$">
SetHandler "proxy:fcgi://localhost:${UID}/"
</FilesMatch>
Alter the following settings to and save the configuration :SetHandler "proxy:fcgi://localhost:${UID}/"
</FilesMatch>
Automatically add appropriate SuExec directive? : No
Default PHP execution mode : mod_php
And Also do the same for sub-server templates :
Download my php-fpm script folder for virtualmin (See end of the article) :And Also do the same for sub-server templates :
Virtualmin -> System Settings -> Server Templates -> Sub-servers -> Apache website
Set the Directives and settings for new websites to From default settings
mkdir /script
cd /script
(SEE END OF THE ARTICLE, SAVE FILE AS php-fpm)
chmod a+x php-fpm
Now enable the script :chmod a+x php-fpm
Virtualmin -> System Settings -> Virtualmin Configuration -> Actions upon server and user creation
Command to run after making changes to a server : /script/php-fpm
Always show output from pre and post commands? : Yes
5- Apply configuration for you existing domains :
virtualmin disable-feature --web --virtualmin-awstats --logrotate --webalizer --all-domains
virtualmin enable-feature --web --virtualmin-awstats --logrotate --webalizer --all-domains
Enable Subdomains :
virtualmin enable-feature --web --all-domains
I've removed some of the virtualmin feature which I didn't use ( dav, mailman, ... ). You may need to compile some extra apache modules.Enable Subdomains :
virtualmin enable-feature --web --all-domains
6 - Fixing Script installer issue :
Script installer didn't detect php version unless you compile and install mod_php for httpd :
cd /usr/src
yum install -y libxml2-devel
wget http://us2.php.net/get/php-5.4.31.tar.bz2/from/this/mirror
tar -jxf php-5.4.21.tar.bz2
cd php-5.4.21
./configure --prefix=/usr --with-apxs2=/opt/apache2/bin/apxs
make
cp libs/libphp5.so /opt/apache2/modules
Add the following lines to /opt/apache2/conf/httpd.conf, after LoadModules section (~ Line 158)
<IfModule prefork.c>
LoadModule php5_module modules/libphp5.so
</IfModule>
And also :
Virtualmin -> Webmin -> Servers -> Apache webserver -> Module config :
Always detect Apache modules automatically? : YESNote: Virtualmin adds NameVirtualHost directive to httpd.conf file which is not needed anymore. You might remove the line manually.
It's all ! Now you've run an AWESOME config on your server, enjoy it !
Mos
-----
Attachments
-----
httpd24 startup script for CentOS (save it as /etc/init.d/httpd24):
#!/bin/bash
#
# Startup script for the Apache Web Server
#
# chkconfig: - 85 15
# description: Apache is a World Wide Web server. It is used to serve \
# HTML files and CGI.
# processname: httpd
# pidfile: /opt/apache2/logs/httpd.pid
# config: /opt/apache2/conf/httpd.conf
fullpath=/opt/apache2/bin/apachectl
desc="Apache web server"
case "$1" in
'start')
echo "Starting $desc: "
$fullpath start
RETVAL=$?
;;
'stop')
echo "Stopping $desc: "
$fullpath stop
RETVAL=$?
;;
'restart')
echo "Restarting $desc: "
$fullpath restart
RETVAL=$?
;;
'status')
echo "Status of $desc: "
$fullpath --status-all
RETVAL=$?
;;
*)
echo "Usage: $0 { start|stop|restart|status }"
RETVAL=1
;;
esac
exit $RETVAL
#!/bin/sh -e
### BEGIN INIT INFO
# Provides: httpd
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start/stop httpd web server
### END INIT INFO
#
# httpd This init.d script is used to start apache2.
# It basically just calls apache2ctl.
fullpath=/opt/apache2/bin/apachectl
desc="Apache web server"
case "$1" in
'start')
echo "Starting $desc: "
$fullpath start
RETVAL=$?
;;
'stop')
echo "Stopping $desc: "
$fullpath stop
RETVAL=$?
;;
'restart')
echo "Restarting $desc: "
$fullpath restart
RETVAL=$?
;;
'status')
echo "Status of $desc: "
$fullpath --status-all
RETVAL=$?
;;
*)
echo "Usage: $0 { start|stop|restart|status }"
RETVAL=1
;;
esac
exit $RETVAL
#!/bin/bash
# Script to check and create fpm pools
# Simply create the target fpm pool at uid port : 127.0.0.1:UID
# Set the User and Group of fpm pool to User and Group of domain
if [ -d /etc/php-fpm.d ]; then
os="centos";
confdir="/etc/php-fpm.d/";
fpm="/etc/init.d/php-fpm";
elif [ -d /etc/php5/fpm/pool.d ]; then
os="debian";
confdir="/etc/php5/fpm/pool.d/";
fpm="/etc/init.d/php5-fpm"
fi
# There's no need to create pools for sub-servers
if [ "$VIRTUALSERVER_PARENT" = "" ]; then
if
[[ "$VIRTUALSERVER_ACTION" = "CREATE_DOMAIN" && "$VIRTUALSERVER_WEB" = "1" ]] ||
[[ "$VIRTUALSERVER_ACTION" = "MODIFY_DOMAIN" && "$VIRTUALSERVER_WEB" = "1" && ! -f $confdir$VIRTUALSERVER_UID.conf ]] ||
[ "$VIRTUALSERVER_ACTION" = "ENABLE_DOMAIN" ]; then
# Create the pool for main domain
echo -e "\nCreating fpm pool $VIRTUALSERVER_USER at 127.0.0.1:$VIRTUALSERVER_UID with config file $confdir$VIRTUALSERVER_UID.conf"
#
echo "[$VIRTUALSERVER_USER]" > $confdir$VIRTUALSERVER_UID.conf
echo "listen = 127.0.0.1:$VIRTUALSERVER_UID" >> $confdir$VIRTUALSERVER_UID.conf
echo "listen.allowed_clients = 127.0.0.1" >> $confdir$VIRTUALSERVER_UID.conf
echo "user = $VIRTUALSERVER_USER" >> $confdir$VIRTUALSERVER_UID.conf
echo "group = $VIRTUALSERVER_GROUP" >> $confdir$VIRTUALSERVER_UID.conf
echo "pm = dynamic" >> $confdir$VIRTUALSERVER_UID.conf
echo "pm.max_children = 20" >> $confdir$VIRTUALSERVER_UID.conf
echo "pm.start_servers = 2" >> $confdir$VIRTUALSERVER_UID.conf
echo "pm.min_spare_servers = 2" >> $confdir$VIRTUALSERVER_UID.conf
echo "pm.max_spare_servers = 3" >> $confdir$VIRTUALSERVER_UID.conf
echo "pm.max_requests = 2000" >> $confdir$VIRTUALSERVER_UID.conf
echo "chdir = $VIRTUALSERVER_HOME" >> $confdir$VIRTUALSERVER_UID.conf
echo ";request_slowlog_timeout = 0" >> $confdir$VIRTUALSERVER_UID.conf
echo "slowlog = $VIRTUALSERVER_HOME/logs/"$VIRTUALSERVER_DOM"_slow_log" >> $confdir$VIRTUALSERVER_UID.conf
echo "php_admin_value[error_log] = $VIRTUALSERVER_HOME/logs/"$VIRTUALSERVER_DOM"_error_log" >> $confdir$VIRTUALSERVER_UID.conf
echo "php_admin_value[session.save_path] = $VIRTUALSERVER_HOME/tmp" >> $confdir$VIRTUALSERVER_UID.conf
echo "php_admin_flag[log_errors] = on" >> $confdir$VIRTUALSERVER_UID.conf
echo ";php_admin_value[memory_limit] = 32M" >> $confdir$VIRTUALSERVER_UID.conf
echo "Applying php-fpm configuration"
$fpm reload
fi
# Remove php-fpm pool when deleting a virtual-server
if [[ "$VIRTUALSERVER_ACTION" = "DELETE_DOMAIN" ]] ||
[[ "$VIRTUALSERVER_ACTION" = "MODIFY_DOMAIN" && "$VIRTUALSERVER_WEB" = "0" && -f $confdir$VIRTUALSERVER_UID.conf ]] ||
[ "$VIRTUALSERVER_ACTION" = "DISABLE_DOMAIN" ]; then
echo "Removing fpm pool $confdir$VIRTUALSERVER_UID.conf";
if [ -f $confdir$VIRTUALSERVER_UID.conf ]; then
rm -fr $confdir$VIRTUALSERVER_UID.conf;
fi
$fpm reload
fi
fi
sed -i /opt/apache2/conf/httpd.conf -e '/^NameVirtualHost/d'
Thanks for the steps and confirming this works.
ReplyDeleteIs there any reason why not to just overwrite the existing copy of apache so it can be managed directly by virtualmin/webmin?
Since you use /opt/ I assume this was originally done in debian and then you converted the script to centos.
The version of default apache package on debian and centos is 2.2 which doesn't support tcp/ip fcgi to work with php-fpm.
Delete2.4.x introduces new mod_proxy_fcgi so it can contact php-fpm pools directly.
I've installed httpd 2.4.x in /opt folder ( no matter what os ) and integrated it to virtualmin in step #3 so you'll be able to manage it directly using both webmin/virtualmin.
Please note that using PHP-FPM with TCP/IP or a socket with too open permissions is a severe security fuck-up waiting to happen.
ReplyDeleteYou're right ...
DeleteI've asked apache developers for socket connection fpm support :
http://httpd.apache.org/docs/2.4/mod/mod_proxy_fcgi.html
See comments ...
Great Tutorial,
ReplyDeleteBut there is a problem with /script/php-fpm it show an error when it come to the step of applying configuration to existing domains, it show:
/script/php-fpm: 18: /script/php-fpm: [[: not found
/script/php-fpm: 19: /script/php-fpm: [[: not found
/script/php-fpm: 48: /script/php-fpm: [[: not found
/script/php-fpm: 49: /script/php-fpm: [[: not found
thanx for your help
I think you need to ask the question on a linux forum, I've tested the script on centos and debian.
Delete'[[' is something like 'if statement' but I don't have any idea why it's not working for you !
I changed #/bin/sh to #/bin/bash and this is fixed.
DeleteAny chance of getting the php-fpm script somewhere? Can't download it anymore
ReplyDeleteI attached it to the post.
DeleteI cannot get scripts to install in virtualmin following this guide: "This script cannot be installed, as this virtual server does not meet its requirements : Could not work out exact PHP version" I followed the part about script install.. any suggestions.. everything else seems fine but I really like to fix this part?
ReplyDeleteI updated the post to fix this.
DeleteI see /opt/apache2/conf/httpd.conf for editing conf file first but then it is /opt/apache24/conf/httpd.conf. Is this a typo?
ReplyDeleteI cannot find /opt/apache24/conf/httpd.conf
I corrected the typo! thanks.
DeleteWhat directory should we mkdir /script? root? src? init.d?
ReplyDelete/script should be on / directory.
DeleteThanks a lot for guide. I think we should keep error log location same.
ReplyDeleteI am going to give this a go with Centos 7 so Apache 2.4 should already be there and good to go. I am thinking I can just skip step 3 and change the file path to httpd.conf where needed.
ReplyDeleteHello, I am going to try this on Ubuntu 16.04 lts.
ReplyDeleteI notice you don't turn off mpm-prefork/mod-php, and turn on mpm-worker (or mpm-event)? Why? You would significantly cut down on your Apache overhead...
You are right, Ive now updated this post and replaced mpm_prefork with mpm_event.
Delete