Installing Apache 2.4 with PHP 5.4 on CentOS 6.5

posted | about 5 minutes to read

tags: 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"
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
service ntpd start

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 -m state --state NEW -p tcp -m tcp --dport 22 -j ACCEPT
iptables -A INPUT -s -m state --state NEW -p tcp -m tcp --dport sftp -j ACCEPT
iptables -A INPUT -s -m state --state NEW -p tcp -m tcp --dport 137 -j ACCEPT
iptables -A INPUT -s -m state --state NEW -p tcp -m tcp --dport 138 -j ACCEPT
iptables -A INPUT -s -m state --state NEW -p tcp -m tcp --dport 139 -j ACCEPT
iptables -A INPUT -s -m state --state NEW -p tcp -m tcp --dport 445 -j ACCEPT
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j 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:

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
Include /etc/httpd/sites-enabled/ 
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://$1

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/
LoadModule proxy_http_module lib64/httpd/modules/
LoadModule proxy_fcgi_module lib64/httpd/modules/
LoadModule rewrite_module lib64/httpd/modules/

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

Compiling PHP

Copy-paste the following lines:

mkdir ~/php
cd ~/php
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

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 with include=/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.

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

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.

Here is a sample virtual host configuration file:

    DocumentRoot /path/to/site
    <Directory /path/to/site>
        AllowOverride All
        Options FollowSymLinks
        Require all granted
    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://$1
    ErrorLog /path/to/site/error_log
    TransferLog /path/to/site/access_log

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.

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

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

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!