Installing Apache 2.4 with PHP 5.4 on CentOS 6.5
| about 6 minutes to read
php-fpm apache tutorial system administration
Recently, we were looking into how to install Apache 2.4 and PHP 5.4 with PHP-FPM on our CentOS boxes, as PHP 5.3 with Apache 2.2 was feeling a bit outdated. Since CentOS 7 isn’t quite out yet, we put together a process to install these on our CentOS 6.5 servers (Update: Now that CentOS 7 is out, the process is a lot more straightforward: just run yum install httpd php php-fpm
. If you need more recent versions of PHP, you can always install IUS on CentOS, or Debian-based distros have the ability out of the box to install multiple PHP versions side by side.)
The process is a little involved, but it really works well. You can find it after the break. Special thanks to Geekpeek for providing prebuilt Apache 2.4 RPM’s for CentOS!
Keep in mind that I tried to write this guide to be as accessible as possible, but it does assume some level of familiarity with command-line Linux.
Apache 2.4/PHP 5.4/PHP-FPM/CentOS 6.5 Documentation
Initial Server Setup
Install CentOS using _minimal_ options, and set up your network.
Copy-paste the following:
yum update -y
yum -y install wget
yum groupinstall -y "Development Tools"
wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
yum -y install rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
yum install -y --enablerepo=rpmforge-extras libxml2-devel curl-devel nano mysql-server ntp ntpdate ntp-doc openssl openssl-devel libmcrypt libmcrypt-devel libpng libjpeg libpng-devel libjpeg-devel curl-devel
chkconfig ntpd on
ntpdate pool.ntp.org
service ntpd start
The extra blank line at the end of these preformatted code blocks are so that you can copy-paste the entire code block. Your SSH session should run all the commands successively.
Here are some sample rules for our network configuration for iptables; modify these rules if your network configuration does not match ours.
iptables -F
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
#this is to get rid of null packets
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
#defend syn-flood attacks
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
#defend xmas packets
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
iptables -A INPUT -s 10.1.111.0/24 -m state --state NEW -p tcp -m tcp --dport 22 -j ACCEPT
iptables -A INPUT -s 10.1.111.0/24 -m state --state NEW -p tcp -m tcp --dport sftp -j ACCEPT
iptables -A INPUT -s 10.1.111.0/24 -m state --state NEW -p tcp -m tcp --dport 137 -j ACCEPT
iptables -A INPUT -s 10.1.111.0/24 -m state --state NEW -p tcp -m tcp --dport 138 -j ACCEPT
iptables -A INPUT -s 10.1.111.0/24 -m state --state NEW -p tcp -m tcp --dport 139 -j ACCEPT
iptables -A INPUT -s 10.1.111.0/24 -m state --state NEW -p tcp -m tcp --dport 445 -j ACCEPT
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P INPUT DROP
Once rules are entered, type:
iptables-save | sudo tee /etc/sysconfig/iptables
service iptables restart
cd ~
MySQL DB Setup
Run following commands:
service mysqld start
chkconfig mysqld on
Run mysql_secure_installation from the command line and follow the instructions.
The only thing you should have to do is set a new root password, then answer “Y” to every prompt presented.
httpd Setup
Copy-paste the following lines:
wget http://geekpeek.net/download/httpd-2.4.9-RPM-full.x86_64.tgz
tar -xvzf httpd-2.4.9-RPM-full.x86_64.tgz
cd httpd-2.4.9-RPM-full.x86_64
yum -y localinstall * --skip-broken
cd ..
We grab a custom httpd binary because it contains features that are required for FPM. A more maintainable option may be to use IUS, which has a CentOS 6 compatible repository.
Open /etc/httpd/conf/httpd.conf and add the following to the bottom of the file:
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
Include /etc/httpd/sites-enabled/
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1
</pre>
Find the ServerName
directive, and change it to ServerName [Main IP of the server]:80
.
Find the DirectoryIndex
line in the file, and change it to DirectoryIndex index.php index.html
Find the AllowOverride
line in the file that is inside the <Directory "/var/www/html">
block, and change it to AllowOverride All
Uncomment the following lines:
LoadModule proxy_module lib64/httpd/modules/mod_proxy.so
LoadModule proxy_http_module lib64/httpd/modules/mod_proxy_http.so
LoadModule proxy_fcgi_module lib64/httpd/modules/mod_proxy_fcgi.so
LoadModule rewrite_module lib64/httpd/modules/mod_rewrite.so
Save the file and exit.
Copy paste the following lines:
cd /etc/httpd
mkdir sites-available
mkdir sites-enabled
cd sites-available
service httpd start
chkconfig httpd on
The sites-available directory is where the virtual host .conf files are created.
Compiling PHP
Copy-paste the following lines:
mkdir ~/php
cd ~/php
wget http://us1.php.net/distributions/php-5.4.29.tar.bz2
tar jxf php-5.4.29.tar.bz2
cd php-5.4.29
./configure --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-libdir=lib64 --with-apxs2 --with-mysql --with-mysqli --with-zlib --enable-mbstring --enable-zip --enable-fpm --with-gd --with-mcrypt --enable-pdo --with-pdo-mysql --with-curl
make && make install
If you wanted, you could compile PHP 5.5 as well. IF you do, don’t forget the --enable-opcache
flag!
PHP-FPM Config
Copy-paste the following lines:
mv /usr/local/etc/php-fpm.conf.default /usr/local/etc/php-fpm.conf
cd /usr/local/etc
mkdir pool.d
nano php-fpm.conf
Remove all data below the “Pool definitions” header, and replace withinclude=/usr/local/etc/pool.d/*.conf
In the pool.d folder in your current directory, make a file named www.conf for the default site.
[www]
user=www-data
group=www-data
listen=127.0.0.1:9000
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 200
listen.backlog = -1
catch_workers_output = yes
security.limit_extensions = .php .html
php_admin_value[open_basedir]=/var/www/html/
php_admin_value[upload_tmp_dir]=/var/www/html/tmp/
php_admin_value[session.save_path]=/var/www/html/tmp/
php_admin_value[error_log]=/var/www/html/error_log
DO NOT use this for a virtual host site!
Add a user, as below:
useradd www-data
groupadd www-data
usermod -g www-data www-data
Copy-paste the following code and run it:
cd ~/php/php-5.4.29/sapi/fpm
mv init.d.php-fpm /etc/init.d/php-fpm
mv /root/php/php-5.4.29/php.ini-production /etc/php.ini
cd /etc/init.d
chmod 755 php-fpm
chkconfig php-fpm on
service php-fpm start
Setting Up a New Site
Navigate to /etc/httpd/sites-available and create a new .conf file for the virtual host. Typically, this should be named domain.conf
.
Obviously, domain.conf
should be adjusted to match the name of the site you’re creating…
Some rules for vhost .conf files:
- the FCGI port (here listed as XXXX) must match the planned port for the FPM instance! This will be different for each vhost in our planned config.
- The IP is, obviously, the IP on which the site will be available. If you have multiple virtual hosts on the same IP, remember to add a NameVirtualHost directive in/etc/httpd/conf/httpd.conf for that IP.
Here is a sample virtual host configuration file:
<VirtualHost IP.of.the.site:80>
ServerAdmin admin@example.com
DocumentRoot /path/to/site
ServerName www.example.com
ServerAlias example.com
<Directory /path/to/site>
AllowOverride All
Options FollowSymLinks
Require all granted
</Directory>
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:XXXX/path/to/site/$1
ErrorLog /path/to/site/error_log
TransferLog /path/to/site/access_log
</VirtualHost>
Now, set up the FPM pool. Navigate to /usr/local/etc/pool.d and create a new file. Typically, this should be named domain.conf
.
Obviously, domain.conf
should be adjusted to match the name of the site you’re creating…
[domain]
user=$pool
group=$pool
listen=127.0.0.1:XXXX
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 200
listen.backlog = -1
catch_workers_output = yes
php_admin_value[open_basedir]=/path/to/site/
php_admin_value[upload_tmp_dir]=/path/to/site/tmp/
php_admin_value[session.save_path]=/path/to/site/tmp/
php_admin_value[error_log]=/path/to/site/error_log
Remember, adjust “XXXX” to the next available port number for a PHP-FPM instance. The first one should be 9001, probably – and then increment each one successively by 1. Make sure you set the security context of the port to http_port_t if you're using SELinux!
Pool values default to whatever’s listed in the php.ini. I recommend you change the memory_limit, upload_max_filesize, max_file_uploads, etc. there, then make exceptions in the pool on a case by case basis.
Remember to add the user.
useradd domain
groupadd domain
usermod -g domain domain
Once you have your virtual host and FPM pool set up, to put the site live, run the following commands:
ln -s /etc/httpd/sites-available/domain.conf /etc/httpd/sites-enabled/domain.conf
service httpd graceful
service php-fpm restart
Remember to adjust domain.conf to the name of your virtual host config file.
If all went well, you should now have a complete LAMP stack running with new versions of Apache and PHP, including the PHP-FPM tool, running on CentOS 6.5. Feel free to leave comments or feedback below!