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"
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

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

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

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.

[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

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:

<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.

[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 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!