Setting Up CentOS 5 to Host a LAMP Web Application

November 1st, 2011 Permalink

CentOS is far from my favorite Linux distribution, but I don't think that there is any particularly rational reason for that. It does the job. Perhaps I look on it with disfavor because out of the box it isn't set up with good package repositories by default, so you have to go looking for those before you can get started on setting up a new server. In any case, this post outlines the steps I take when setting up a new CentOS 5 machine for use as a standalone Drupal server, though it works just as well for any LAMP web application.

Log in, Sudo to Root

sudo su -

You want that "-" at the end there - omit it and you'll have issues because you won't get the full root environment path.

Add the Necessary RPM Repositories

You will be using the Yum package manager. Unfortunately the default repositories are a little light on software for CentOS, unlike Fedora, which means you'll have to use other tools along the way. So first off you'll want to add a decent repository to your system, a short process which starts by finding your version of CentOS and server architecture (i.e. i*86 or x86_64):

cat /etc/redhat-release
uname -a

Then go find the RPM server that matches your architecture at http://dag.wieers.com/rpm/FAQ.php#B2. e.g. for CentOS 5.6 on i386 you want the RHEL5 server:

http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.i386.rpm

Then run:

rpm -Uhv [rpmforge-release url goes here]
yum update yum

That will set you up to use the new package repository in addition to the defaults. Or if you know your way around the package management system pretty well, you do skip the above instructions and add the appropriate repositories manually - your choice.

Install The Basics

You might start with this, which will get most of Apache, PHP and MySQL, and a bunch of necessary supporting packages through their dependencies:

yum install httpd mod_ssl php php-mysql php-pdo php-xml php-imap
yum install php-mcrypt php-mbstring php-pecl-memcache php-gd php-common
yum install mysql mysql-server gd gd-devel ImageMagick

Note that php* and php53* are two different sets of packages for CentOS, and they will conflict - which is not the case for repositories for Fedora, for example. Here I'm going with the older set of packages for the sake of momentary convenience.

Next, you want to get the APC bytecode cache installed, which requires a side-trip off into PECL. PHP is slow without a bytecode cache, and all modern PHP frameworks and applications tend to assume that you are using one:

yum install php-pear php-devel httpd-devel pcre-devel
pecl install apc
echo "extension=apc.so" > /etc/php.d/apc.ini

Install Memcached

Now try to install memcached:

yum install memcached

This may or may not work. On CentOS 5.6, the package for perl-Net-SSLeay available through yum is 1.30, and it needs to be 1.33 or later for the package dependencies to resolve. You may also have issues with perl-IO-Socket-SSL. You will have to take the following actions on CentOS 5.* on x86_64 to solve these problems by updating the packages through RPM. Some of the package names will be different for other versions of CentOS, and it should hopefully be easy to see where and how they will be different:

cd /root
rpm -e perl-Net-SSLeay-1.30-4.fc6
rpm -e perl-IO-Socket-SSL-1.01-1.fc6
wget http://packages.sw.be/perl-Net-SSLeay/perl-Net-SSLeay-1.36-1.el5.rfx.x86_64.rpm
wget http://packages.sw.be/perl-IO-Socket-SSL/perl-IO-Socket-SSL-1.34-1.el5.rfx.noarch.rpm
rpm -i perl-Net-SSLeay-1.36-1.el5.rfx.x86_64.rpm
rpm -i perl-IO-Socket-SSL-1.34-1.el5.rfx.noarch.rpm

Then once again try:

yum install memcached

Which should now work.

Install Monit

Monit is a monitoring and alerting package. If you aren't using it, you probably should be. This installation is easy:

yum install monit

Set up Services

Using chkconfig makes it trivial to set various necessary services to run on startup:

chkconfig --levels 2345 httpd on
chkconfig --levels 2345 mysqld on
chkconfig --levels 2345 memcached on
chkconfig --levels 2345 monit on

Configure Memcached

Open up /etc/init.d/memcached in your favorite text editor and alter these lines:

PORT="11211"
USER="nobody"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS=""

Change them as follows, to boost the number of connections and cache, and ensure that memcached is only listening on localhost.

PORT="11211"
USER="nobody"
MAXCONN="20480"
CACHESIZE="512"
OPTIONS="-l 127.0.0.1"

These are generally useful production values, and cachesize is measured in Megabytes - if you are setting up a test server, you'll probably want to scale back the memory to 64. In fact, you should probably ignore any recommendation I make on cache size and maximum number of concurrent connections and think through what your application and server hardware demand that those numbers should be.

Then restart Memcached:

/etc/init.d/memcached restart

Configure MySQL

Turn on the query cache: in /etc/my.cnf add the following under the [mysqld] heading, add the following lines for a sensibly sized query cache for most applications. You will hopefully have a better idea as to how large a cache benefits your own web application, so adjust as you see fit.

query_cache_type=1
query_cache_size=20M

Then restart MySQL:

/etc/init.d/mysqld restart

Now add the users and databases you need, and set a root user password.

Configure APC

Add these lines to the default APC file you created in /etc/php.d/apc.ini:

apc.enabled=1
apc.shm_segments=1
apc.optimization=0
apc.shm_size=64

The important item is the definition for apc.shm_size, as the default of 32 is too small for most PHP applications. Tinkering with APC beyond this point is something to look into when you get to the optimization stage of your work, but that's far beyond the scope of this post. Use Google and you'll find a lot of discussion and many pointers on this topic.

Configure PHP

Make whatever changes are needed by your application to the PHP configuration - it will work as-is, but you will probably want to adjust memory allocations, alter error reporting, set expose_php = Off, and so forth.

Configure Apache

Set up the Apache configuration as needed - in particular note that Monit will treat the default out of the box behavior of an empty Apache root directory as a failure, as this returns a 403 error code. You will probably want to put an empty index.html file into /var/www/html to make things go more smoothly.

Configure Monit

The version of Monit installed through Yum may be initially set to store its running ID and state in either an unhelpful or non-existent directory. That will have to be changed, and you will also want to alter some of the configuration parameters in any case - so create a file /etc/monit.d/monitrc and put the following lines in it:

set idfile /var/run/monit-id
set statefile /var/run/monit-state
set daemon 60
set logfile /var/log/monit.log

For most of my simple single-server applications, I then create a trivial set of instructions that set monit to watch over the httpd, mysql, and memcached processes without issuing notifications or doing much more than restarting on failure. Create the file /etc/monit.d/httpd and put the following instructions into it:

check process httpd with pidfile /var/run/httpd.pid
  group www
  start program = "/etc/init.d/httpd start"
  stop program = "/etc/init.d/httpd stop"
  if failed host localhost port 80 protocol HTTP
    with timeout 10 seconds
    then restart
  if 5 restarts within 5 cycles
    then timeout

In /etc/monit.d/mysql:

check process mysqld with pidfile /var/run/mysqld/mysqld.pid
   group database
   start program = "/etc/init.d/mysqld start"
   stop program = "/etc/init.d/mysqld stop"
   if failed host localhost port 3306 protocol mysql then restart
   if 5 restarts within 5 cycles then timeout

In /etc/monit.d/memcached:

check process memcached with pidfile /var/lock/subsys/memcached
  group www
  start program = "/etc/init.d/memcached start"
  stop program = "/etc/init.d/memcached stop"
  if failed host localhost port 11211 then restart
  if 5 restarts within 5 cycles then timeout

Monit also offers options for notifications, restarting on high load, logging activity, and many other amenities, so you may want to add more to this very basic configuration.

Install Your Web Application

The basic server set up is now done. You can carry on to the next step of installing your web application code, schema, and data - and then you're ready for visitors.