High Performance Server Configuration in the Age-of-the-Cloud


Building web servers for hosting reliable and performant web sites is a black art. I’d like to discuss how we setup our CentOS servers and manage them conveniently using Webmin. We have learned a few things over time and thought it would be valuable to share the knowledge.

Many of our clients come to us with the intention for us to create a new website with them. However, once a new site is built – it still has to live somewhere. One of the services that we provide for our clients is helping them make the right choices when it comes to internet hosting.

Hosting is a big business and there are a huge multitude of choices available for these services. Some of the considerations that need to be answered are:

  1. Registrar – where can I register my domain?
  2. DNS settings – how can I manage my Domain Name Services?
  3. Hosting Services – what provider should I use for hosting services?
  4. Web Server – what type of machine will be used for the webserver?
  5. Server Maintenance – how will I manage this server and ensure that my site is secure?

These questions all need to be answered for each site that we build. Of course, there are many factors that go into this decision:

Website Considerations

Considerations to bear in mind when deciding on a web-hosting solution.

Some of our clients have specific needs for some or all, of these questions. However, the majority of our clients don’t have such specific needs, nor do they have specific interest in how all of this gets done. And that is perfectly fine, that’s where we come in. We are more than happy to lend our experience and take care of everything.

This leaves us with a problem of our own – how do we best manage all the websites, for every client, each with different needs?

To answer this, I am going to explain how we prefer to setup our CentOS 6.4 servers and how we manage them all using Webmin and Virtualmin.

Our Setup

Of course we have systems to manage all the variations in setup that we need for our clients. There is no way we could manage things successfully without having a compact, consistent solution for doing all of this.

The solution that we have converged on, after much experimentation, is to run our own dedicated hosting servers. On these servers we are able to host all of the virtual domains for our clients, while still maintaining both our sanity and server security.

Without opening debate on all of the variables that go into making a decision of our preferred setup. This is the list of our choices (we love to hear criticism, if you have something to comment on, we’re all ears):

  • CentOS 6.4
  • Webmin / Virtualmin
  • Apache Webserver (+ NGiNX, on demand)
  • Percona Server (high performance MySQL database)
  • PHP 5.4
  • FastCGI (high performance CGI for PHP)
  • PostFix Mail

The key thing from this list that I’m going to talk about is Webmin / Virtualmin. This is the software that will provide us with our main interface to the machine, control all the virtual hosts and server security.

Webmin is a web-based interface for system administration for Unix. Using any modern web browser, you can:

  • setup user accounts
  • Apache
  • DNS
  • file sharing
  • and much more

Webmin removes the need to manually edit Unix configuration files like /etc/passwd and lets you manage a system from the console or remotely.


Although CentOS 6.4 Linux is a Grade A Supported System we have had some trouble with the standard setup. We have chosen to run Fast CGI as our PHP interpreter and there are some problems with FastCGI via Webmin on CentOS.

Webmin / Virtualmin

This is the server / cluster management layer. As we are doing initial server setup, from a newly provisioned operating system, so all commands are run as root:

Webmin will be happier if we set the server’s name before we begin. Let’s assume we’re building a new server called webmin.76design.com. Check hostname -f and if it’s not webmin.76design.com, then:

vim /etc/sysconfig/network

hostname webmin.76design.com

vim /etc/hosts webmin.76design.com webmin localhost

Thus, we are ready to install Virtualmin:

cd /root
wget http://software.virtualmin.com/gpl/scripts/install.sh -O /root/install.sh
/bin/sh ./install.sh

When complete, browse to webmin and run the Post-Installation Wizard (default webmin port is 10000):


Here is what the interface will look like at this stage:


I know that beauty is in the eye of the beholder, but I think this UI is simply a gorgeous example of functional
Utilitarianism. À chacun son goût

Webmin Installation Tweaks

Once webmin is installed and passes initial checks, these are the next steps that we need for our server goals:

  1. Percona Server (high performance MySQL database)
  2. PHP 5.4
  3. MySQL
  4. FastCGI (high performance CGI for PHP)

These each are have little issues on CentOS, so I thought it important to capture our experiences here. Each of these subsections has cost me time during setup in the past.

However, the Webmin Post-Installation Wizard is never happy, out of the box, if native mysql is not in place during install. I find it’s easiest to install Webmin over the native MySQL substrate, and then, when complete, remove the native MySQL and install Percona and updated PHP.

Install Percona Server

Percona provides a high performance drop-in replacement for the native MySQL database server. There are several reasons why we choose Percona as our database server. We like the InnoDB support, especially for our Laravel projects and the exceptional performance it affords.

Percona Server is an enhanced, drop-in MySQL® replacement… with Percona Server:

  • Queries will run faster and more consistently
  • You can consolidate servers on powerful hardware
  • Sharding is delayed or avoided entirely
  • You can save money on hosting fees and power
  • You can spend less time tuning and administering
  • You can achieve higher uptime
  • Troubleshooting does not require guesswork


The following steps are not redundant. Not installing these EPEL extensions first will result in unmet dependencies during the subsequent Percona upgrade. We want these repositories: {EPEL, Percona} in this order:

rpm -Uhv http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum install -y mysql mysql-server mysql-libs
service mysqld restart
yum remove -y mysql*
rpm -Uhv http://www.percona.com/downloads/percona-release/percona-release-0.0-1.x86_64.rpm
yum -y --enablerepo=percona install \
    Percona-Server-client-56 \
    Percona-Server-server-56 \
    Percona-Server-shared-56 \
yum -y upgrade


Use Remi Collet’s RPM repository to ensure that we have the latest and most secure PHP that we’ll need for our projects. You can trust him – we do, his repository is a great help for providing recent updates:

php -v # reference
rpm -Uhv http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
yum -y --enablerepo=remi install php
yum -y --enablerepo=remi install php-mcrypt
php -v # sanity check

We like CentOS, precisely because of it’s slow adoption of new dependencies. This gives us a choice about the packages that we want to keep cutting-edge, while letting the CentOS community help keep the OS itself secure. When it comes to PHP, we want the latest versions.


Remove strict handling (with Percona 5.6), set:

Webmin | Servers | MySQL Database Server | MySQL Server Configuration
vim /etc/my.cnf

default-storage-engine = InnoDB

check or start the database server:

service mysql status service mysql restart


For some reason there seems to be a problem with Virtualmin and CentOS 6.4 running FastCGI. This is a performance consideration, so I’m not willing to give up this functionality. There seem to be 2 alternative solutions to get this working:

  1. comment out SetHandler:

    Webmin | Servers | Apache Webserver | Global configuration | Edit Config Files (php.conf)
    vim /etc/httpd/conf.d/php.conf

    <FilesMatch \.php$>
      #SetHandler application/x-httpd-php
  2. prevent disabling of #php_admin_value in:

    Webmin | Servers | Apache Webserver | Virtual Server | Edit Directives
    vim /etc/httpd/conf/httpd.conf

      #php_admin_value engine Off

Either of these will do the trick. The first is more general, but you may have to use the second if you know that you will have Virtualhosts that actually require the SetHandler PHP. I have seen this requirement with Drupal Multi-Site installations, your mileage may vary.

Post Install Checks


It’s pretty important to know what time it is (and pretty amateur not to), so go to:

Webmin | Hardware | System Time

and setup a network timeserver to coordinate with. After all, this machine probably lives at a data center, so it’s going to be online.


Setting up postfix is no mean feat. Normally our webservers want to at least be able to send mail, but typically mail services are best handled by dedicated software. To achieve this basic goal, we need to ensure that the virtual domain is able to get mail off the server and into the wild (so, restrict virtual alias map):

Webmin | Servers | Postfix Mail Server | Virtual Domains
vim /etc/postfix/main.cf

virtual_alias_maps = hash:/etc/postfix/virtual
virtual_alias_domains = webmin.76design.com

Once outbound mail makes it into the wild, the best we can do to make sure it will be accepted by the recipient systems is to:

  1. enable “grey listing” via postgrey [Virtualmin | Email Messages | Email Greylisting]
  2. set appropriate SPF records at DNS level listing this webserver as a permitted sender – [Virtualmin | Server Configuration | Suggested DNS Records]
  3. (setup DKIM if you really want to build a mailserver – out of scope here)

Server Hardening

At this stage we have pretty solid setup for a dedicated server. Of course, we’re now responsible for a new, first-class citizen on the internet, so it’s going to be accosted. We need to do all the things that we’d normally do to ensure this computer is secured. Mostly this discussion is out of scope here, but here is a very short checklist:

  • install ssh keys for your users – ssh-copy-id ...
  • /etc/ssh/sshd_config – lock down “PermitRootLogin”, “UsePAM” (passwords are so `90’s)
  • disable unneeded services (FTP, really?)
  • iptables firewall (allow hacks from your office only)


In conclusion, we have outlined the steps for setting up a high performance webserver. Our server is based on:

  1. Operating System – fresh install of CentOS 6.4
  2. Server ManagementVirtualmin
  3. DatabasePercona Server
  4. PHP version – PHP 5.4
  5. CGI – FastCGI
  6. Mail – PostFix Mail

There are a couple caveats that I have addressed here that we run into during a standard install. Hopefully these notes might save you a little bit of hair pulling.

This may all be cakes and pies, but stay tuned for my next article when I plan to talk about how to automate this whole installation business with Ansible as a provisioning solution that will save us all the time and hassle of configuring new hardware by hand.

That’s right, next we’ll build a robot…

Written with StackEdit in Markdown.