Installing Apache 2.4 with PHP 5.4 on CentOS 6.5

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.

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

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

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

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!

Leave a Reply