How I configured my LAMP stack.
Building a VPS is a lot like planning the foundation to your home, you need to have everything done correctly before you can start building up.
I chose a base install of Ubuntu Server 12.10, and knew that I needed at a minimum a LAMP server. But there are a number of other tools that are needed and are usually not available in a shared hosting environment.
Environment
- Ubuntu Server 12.10
- PHP 5.4.6
- MySQL 5.5.29
- Apache 2.2
- Varnish 3.0.3
- Ruby 2.0.0
- Rails 4.0.0.rc1
- Gem 2.0.3
- Python 2.7.3
- Node Js v0.6.19
- Composer
Performance Tuning
It’s important to note that I really know nothing about optimizing a VPS environment, but these are some of the steps that I took with results that worked for me. Out of the box, I had a bunch of issues with keeping the server alive on 512mb of ram using all the default configuration options. Under extreme load, things like MySQL would shut down and since a VPS is DIY there is nothing in place to restart it or report the issue.
Apache
Apache is not the best when it comes to performance, but since I am running a number of client sites it makes sense since Apache is better supported than its lighter alternatives.
Each connection to Apache is around 10mb, so you can see how fast you can max out your system memory, I made the following modifications to /etc/apache2/apache2.conf
MaxKeepAliveRequests 70
KeepAliveTimeout 2
StartServers 1
MinSpareServers 1
MaxSpareServers 5
MaxClients 5
MaxRequestsPerChild 300
Decreasing the number of spare connections, clients, and servers drastically reduced the amount of memory consumed.
PHP
To help secure the server a number of functions were disabled in the php.ini such as shell_exec. I would recommend searching for a list of recommended functions that you can safely live without.
PHP didn’t seem to cause many issues for me, but I did reduce the amount of memory it could have, increased the execution time, number of files that could be uploaded, and increasing the file size limit were personal preferences.
I made the following modifications to /etc/php5/apache2php.ini
max_input_time = 60
memory_limit = 96M
upload_max_filesize = 10M
max_file_uploads = 20
MySQL
MySQL is where I noticed a lot of overhead, it seems to be defaulted to operate with a lot more memory than I think is standard to most VPS servers.
I made the following modifications to /etc/mysql/my.cnf
key_buffer = 8M
max_allowed_packet = 8M
thread_stack = 192K
thread_cache_size = 8
query_cache_limit = 1M
query_cache_size = 16M
Caching
Using Varnish I was able to bump things into overdrive.
These results show 400 users over 60 seconds, you see that around 12 seconds the response time begins to climb. This actually had more to do with network throughput and processing ability. Each request is unique and my CMS also uses a statistics API that I as well host, so each hit would take the IP and look up the GEO details on an API locally. So there was a bit more IO than reported here. Still, Without making these changes I was lucky to get 10 connections without MySQL crashing.
Other notes
New Relic – I host a number of sites for other people, one of the issues with a VPS are that its all on me to fix and maintain the server. Using New Relic allows me to keep an eye on the site’s performance. More importantly, I am able to track each site by setting individual apps.
Automatic MySQL Backup – Normally you would have your database located on another server or at least distributed, I run a rather small time setup and don’t see the need for managing multiple servers. To safeguard my data and my client’s data I created a shell script that will give me a gzipped dump of my database and copy it to my backups folder run with a daily Cron task.
#!/bin/sh
DAY=`/bin/date +%Y%m%d`
mysqldump -u root -ppineapple23 –all-databases | gzip > /home/adam/Dropbox/ironhide_backup/ironhide-$DAY.gz
echo “Nightly Backup Successful: $(date)” >> /var/log/mybackup.log
Dropbox CLI Automatically setting up a backup seemed to be a bit confusing to me, did some searching and found that DropBox has a command-line interface. I simply joined my server to my account, excluded all the other junk, now my database backups will now get synced off-site, and for free!