The following is a step-by-step guide for setting up and configuring a LAMP Stack on a 1GB or 2GB RackSpace Cloud Server with the latest CentOS distribution. You will need root access to complete the following steps.
Please note that in these instructions I make the specific effort of installing PHP 5.2, which is still the most compatible/safest PHP version for running Drupal.
- Log in as root
- Set the hostname
sudo hostname yourdomain.com
- Add entry into /etc/hosts:
_public ip address_ yourdomain.com
- Edit /etc/sysconfig/network to set hostname
- Check /proc/sys/kernel/hostname for hostname
- A reboot might be necessary (might as well)
- Set root password to something that is impossible to remember.
- Setup sudo, if it is not already set up (typically it is)
- sudo groupadd sudoers
- sudo groupadd webmaster
- In /etc/bashrc set umask to 0002
- Create a local account (regular user with primary group set to webmaster and secondary group to sudoers)
useradd -m -s /bin/bash -g webmaster -G sudoers irakli
- Set local account’s password:
- Log in as the local account (“irakli” in our examples).
The rest of the tutorial assumes you are working with the local account and sudo into root as necessary.
Yum is a popular package manager for CentOS and RedHat Linux distributions. Unfortunately, standard Yum repositories carry significantly outdated packages. Fortunately, there are third-party Yum repositories with more updated LAMP packages which we can use. One such repository is provided and hosted by RackSpace itself. Let’s set it up:
sudo rpm -Uvh http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/epel-release-1-1.ius.el5.noarch.rpm
sudo rpm -Uvh http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/ius-release-1.0-6.ius.el5.noarch.rpm
For more information about setting up Rackspace’s IUS Community repository, please refer to the following blog post: Reliable Yum Repo for Easy Upgrades to the Latest Packages, on RedHat and CentOS
Setting Up Packages
sudo yum install openssl-devel zlib-devel gcc gcc-c++ make autoconf readline-devel curl-devel expat-devel gettext-devel
sudo yum install libjpeg libpng telnet libxslt freetype freetype-devel
sudo yum install mysql51-server mysql51-devel
sudo yum install php52-devel httpd-devel apr-devel
sudo yum install php52-pear
sudo yum install mod_ssl
sudo yum install php52-mysql php52-gd php52-xml php52-mbstring php52-mcrypt
sudo yum install php52-pecl-apcedit /etc/php.d/apc.ini and enter:
1 2 3 4 5 6 7 8 9
extension=apc.so apc.enabled=1 apc.shm_segments=1 apc.shm_size=64 apc.ttl=7200 apc.user_ttl=7200 apc.num_files_hint=1024 apc.mmap_file_mask=/tmp/apc.XXXXXX apc.enable_cli=1
sudo yum install bind bind-utils bind-devel
sudo yum install postfix openssl
sudo mkdir /var/www/vhosts
sudo mkdir /var/www/default
- sudo vi /etc/httpd/conf.d/00_default.virtualhost.conf and in there enter:
1 2 3 4 5 6 7 8 9
NameVirtualHost *:80 <VirtualHost *:80> ServerAdmin email@example.com DocumentRoot /var/www/default ServerName __default__ ErrorLog logs/default-error_log CustomLog logs/default-access_log common </VirtualHost>
sudo vi /var/www/default/index.html
- in /etc/httpd/conf/httpd.conf replace all /var/www/html with var/www/vhosts
- change “KeepAlive Off” to “KeepAlive On”
- change “KeepAliveTimeout” from 15 to 5
- Uncomment and Add ServerName yourdomain.com
- type following:
1 2 3
cd /var/www/vhosts/ sudo chown -R apache:apache . sudo chmod -R 775 /var/www/vhosts
- Make apache-owned files writable by your local user (“irakli” in our examples):
sudo /usr/sbin/usermod -G sudoers,apache irakli
sudo mkdir -p /var/www/vhosts/yourdomain.com/html
sudo mkdir -p /var/www/vhosts/yourdomain.com/logs
sudo vi /etc/httpd/conf.d/yourdomain.com.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
<VirtualHost *:80> ServerAdmin firstname.lastname@example.org DocumentRoot /var/www/vhosts/yourdomain.com/html ServerName yourdomain.com ServerAlias subdomain.yourdomain.com ErrorLog /var/www/vhosts/yourdomain.com/logs/error_log CustomLog /var/www/vhosts/yourdomain.com/logs/access_log combined UseCanonicalName Off <Directory /var/www/vhosts/yourdomain.com/html> AllowOverride all Options all Order allow,deny Allow from all Deny from none # Insert filter SetOutputFilter DEFLATE # Netscape 4.x has some problems… BrowserMatch ^Mozilla/4 gzip-only-text/html # Netscape 4.06-4.08 have some more problems BrowserMatch ^Mozilla/4.0 no-gzip # NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48 # the above regex won't work. You can use the following # workaround to get the desired effect: BrowserMatch bMSI[E] !no-gzip !gzip-only-text/html # Don't compress images, videos and audio SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png|flv|mp4|m4v|mp3|zip|gz)$ no-gzip dont-vary # Make sure proxies don't deliver the wrong content Header append Vary User-Agent env=!dont-vary </Directory> FileETag none </VirtualHost>
Please do not forget to replace “yourdomain.com” with the actual domain name you are setting up, in the above example code.
sudo chown -R apache:apache /var/www/vhosts
sudo chmod -R 775 /var/www/vhosts
sudo /etc/init.d/httpd configtest
in there enter any text, e.g.: “RESTRICTED”.
sudo /etc/init.d/httpd restart
Apache Caching of Resources
If the website you are deploying is not a Drupal site, make sure to add the following inside the VirtualHost:
1 2 3 4 5 6 7 8 9
You do not need to do this for Drupal. Drupal already does these in .htaccess, but Joomla, for instance, may not.
- Edit /etc/sysconfig/iptables-config and make sure following variables are set to “yes”:
- Open Web ports:
sudo /sbin/iptables -I INPUT -p tcp -m state --state NEW,ESTABLISHED --dport 80 -j ACCEPT
sudo /sbin/iptables -I INPUT -p tcp -m state --state NEW,ESTABLISHED --dport 443 -j ACCEPT
- Restart iptables with:
sudo /sbin/service iptables stop
sudo /sbin/service iptables start
Recommended Settings for Performance Tuning
Performance and scalability tuning of a server is more of an art than science, in the sense that there’re no ready-to-use formulas. Optimal server settings depend on many unique factors: web-app code, traffic to the site, site’s information architecture among other things. It’s virtually impossible to really optimize server settings without thorough understanding of the web application and a lot of testing.
That said, you are not going to run newsweek.com or huffingtonpost.com on a 1GB or 2GB slice and the default settings are typically so off that it is possible to give you a much better starting point.
Following are some recommended settings that help maximize the utilization of the resources on a multi-core server of 1-2GB RAM size (like that on RackSpace cloud). Please note that these settings are just snippets from the respective configuration files and not the entire configuration file. Do not replace existing files with just these setting, rather edit the new settings into the files already created by previous installation steps.
; Some of the larger CMSes are more memory-hungry than others. Set memory_limit to 128M for Drupal, you may need to bump it to 192M.<br>; More lightweight CMSes like WordPress may be fine at 64M<br>memory_limit = 128M<br>max_execution_time = 120<br>max_input_time =120.<br>realpath_cache_ttl=300<br>realpath_cache_size=1M
In /etc/my.cnf (warning: a snippet, not a full configuration):
skip-external-locking = 1<br>skip-name-resolve<br>open-files-limit = 20000<br><br>## Cache<br>thread-cache-size = 16<br>table-open-cache = 2048<br>table-definition-cache = 512<br>query-cache-size = 92M<br>query-cache-limit = 8M<br><br>## Per-thread Buffers<br>sort-buffer-size = 4M<br>read-buffer-size = 2M<br>read-rnd-buffer-size = 8M<br>join-buffer-size = 4M<br><br>## Temp Tables<br>tmp-table-size = 64M<br>max-heap-table-size = 64M<br><br>## Networking<br>back-log = 100<br>#max-connections = 200<br>max-connect-errors = 10000<br>max-allowed-packet = 16M<br>interactive-timeout = 600<br>wait-timeout = 600<br>skip-character-set-client-handshake<br>collation_server = utf8_unicode_ci<br>character_set_server = utf8<br><br>### Storage Engines<br>default-storage-engine = InnoDB<br>innodb = FORCE<br><br>## MyISAM<br>key-buffer-size = 8M<br>myisam-sort-buffer-size = 8M<br><br>## InnoDB<br>innodb-buffer-pool-size = 16M<br>innodb-additional-mem-pool-size= 16M<br>innodb_log_files_in_group = 2<br>innodb-log-buffer-size = 4M<br>#innodb-flush-method = O_DIRECT<br>innodb-file-per-table = 1<br>#innodb-open-files = 300<br>#innodb-thread-concurrency = 16<br>#innodb-support-xa = 0
KeepAlive On<br>MaxKeepAliveRequests 100<br>KeepAliveTimeout 3
Another thing that can adversely affect performance is if a server decides to start using swap partition for memory. On Linux, swap space is there to prevent running out of memory. However, Linux is somewhat frivolous in swapping, in that it may use swap even in the cases when it would not have ran out of memory. When linux uses swap for MySQL or Apache/PHP performance degrades significantly.
If you want to be absolutely sure that swapping never happens you can disable swap. This is dangerous because if you don’t properly project your maximum memory allocation you may run out of space and server will crash. But sometimes the risk is worth the benefit of running the server at top speed. To disable swap: edit the /etc/fstab file and find a record that looks like:
/dev/sda2 swap swap defaults 0 0
The first column shows the partition used for swap: /dev/sda2. It may be different in your case. To disable swap put a comment character (”#” pound character) in front of that line and run the following command as root:
where the argument of “swapoff” should be the partition which swap was mounted on.
Another thing that could be a great idea for a small server is to put it behind a static-HTTP-cache like Varnish. That can really boost your scalability. Configuring Varnish is a complex and large topic that requires its own blog post, however.
Add Startup Scripts
- sudo /sbin/chkconfig —add httpd
- sudo /sbin/chkconfig —level 2345 httpd on
- sudo /sbin/chkconfig —list httpd
- sudo /sbin/chkconfig —add mysqld
- sudo /sbin/chkconfig —level 2345 mysqld on
- sudo /sbin/chkconfig —list mysqld