Wednesday, 1 May 2013

One script to install and optimize Nginx,mysql & php-fpm for 512Mb VPS


Just one script to install and optimize Nginx,mysql and php5 ,php-fpm for 512Mb VPS/Cloud instance.

Running website on virtual private server ( I am using DigitalOcean VPS, 5$ per month)  or on amazon ec2 instance is cool. But if you are doing it first time ,setting up and optimizing VPS is tricky task to do.You will required to install all servers and configure it yourself. With default settings, MySQL and apache will not work together on same  512MB VPS. Under heavy load MySQL crashes and your site will be down. And, that's why ,I wrote a script which install all required servers and  fine-tune all the servers. I chose NGINX web server over apache because of small footprint and less memory consumption.

Git Repository 

 https://github.com/junedmunshi/SampleCode/blob/master/web/vpsSetup/

Download


OS

Tested on vanilla ubuntu 12.04 .

Install and setup

chmod +x vpsSetup.sh
chmod +x start.sh
chmod +x stop.sh
sudo ./vpsSetup.sh

To start server

sudo ./start.sh

To stop server

sudo ./stop.sh

But before you run the script

Before you blindly run the script, you should look at configuration files for Nginx and modify it according to your need. Everything should work off the shelf except modifying few parameters in ./nginx/default . Read Nginx section below.
Moreover, you can also change configuration for mysql and php if given configuration file does not suit to your need.Read Mysql and Php5 section below.

What will the script do?

It will,
1) Add required debian repository

2) Install all required packages ( nginx mysql-server mysql-client memcached php5 php-apc php-auth php-net-smtp php-net-socket php-pear php5-curl php5-gd php5-mcrypt php5-mysql php5-fpm php5-memcached php5-tidy vsftpd )

3) Take backup of original mysql configuration file. ( /etc/mysql/my.cnf -> /etc/mysql/my.cnf.org)

4) Optimise mysql by patching configuration file from ./mysql/my.cnf to /etc/mysql/my.cnf

5) Apply same step as 3 and 5 for nginx and php5

Files Detail

  • vpsSetup.sh : Installation script
  • mysql/my.cnf : MySQL server configuration file tuned for 512Mb server running mysql and nginx
  • nginx/nginx.conf : Nginx server configuration file tuned for 512Mb server running mysql and nginx
  • nginx/default : Configuration file for your web application.It will patched to /etc/nginx/sites-available .
  • php5/fmp/php.ini : See the php section below
  • php5/fmp/php-fpm.conf : See the php section below
  • php5/fpm/pool.d/www.conf : Tuned for 512Mb server.

If services do not start after applying optimal settings

  1. If Nginx does not start , it may be possible that there is something wrong with either /etc/nginx/ngnix.conf or site-available/default.
    Run sudo service nginx start and look for error.
  2. If MySQL does not start , please check MySQL troubleshoot guide.http://junedmunshiblog.blogspot.in/2013/05/troubleshooting-mysql.html

Nginx

1)nginx/default
It is your web application configuration file. Current settings are configured for php, fast cgi and cakephp .
Things to check before you deploy:
port   
servername : your domain name   
root : path to your website code 
access_log and error_log : very useful for debugging your website code (not nginx) 
location : control behaviour for specific locations such "/" or "*.js,*.css,*.jpg (any assests)" 
Note:
1) Following line is not required if you are not using cakephp. Following line ensure that images,css etc. will load properly without generating "path not found " error from theme/plugin.
try_files $uri $uri/ /../plugins/$1/webroot/$2/$3 /../View/Themed/$2/webroot/$3/$4 ;
2) You may want to turn of access_log and log_not_found for images,xml etc. files once your site functions properly.
2)ngnix.conf

MySQL

my.cnf
1 You may consider further tuning following parameters under '[mysqld]' section if current settings are not best fit for you.
   key_buffer = 16K      (Default is 16M)   
   max_allowed_packet = 1M  (Default is 16M)    
   thread_stack = 64K        (Default is 192K)   
   thread_cache_size  = 4    (Default is 8)   
2 Innodb
  Disable if not needed.Uncomment #skip-innodb
2 Fine tune if you are using it.
   innodb_buffer_pool_size = 16M         (Default is 128M)  
   innodb_additional_mem_pool_size = 2M   

PHP

1) ./php5/fpm/php.ini
The only difference between original and patch file is as below.
;cgi.fix_pathinfo=1 -> cgi.fix_pathinfo=0
2) php5/fpm/php-fpm.conf
3) php5/fpm/pool.d/www.conf
php_admin_value[memory_limit] = You can increase if you have more RAM
php_value[upload_max_filesize] = Change it otherwise leave it if you don't care
php_value[max_execution_time] = Change it otherwise leave it if you don't care
user = www-data 
group = www-data  



Troubleshooting MySQL job failed to start


MySQL start fails

$ sudo service mysql start
start: Job failed to start

Troubleshoot

  1. Try to find out what is wrong.
     
    • Start mysqld manually in verbose mode

      $ sudo mysqld --verbose --user=root

    • Check dmesg

      $ dmesg


  2. Mysqld start manually (Step1) without any error, however,  `sudo service mysql start` still fails. Check following settings are proper  in your /etc/mysql/my.cnf; 

    # The MySQL server
    [mysqld]
    user = mysql
    pid-file = /var/run/mysqld/mysqld.pid
    socket = /var/run/mysqld/mysqld.sock
    port = 3306
    basedir = /usr
    datadir = /var/lib/mysql
    tmpdir = /tmp
    lc-messages-dir = /usr/share/mysql



MySQL crashes under heavy load on Webserver.

 Simulate heavy traffic

 $ ab -n 1000 -c 100 http://yourdomainname/

         ab : Apache HTTP server benchmarking tool
         -n number of requests
         -c concurrent requests

 General cause

  1. Generally mysql crashes because it runs out of memory.

  2. There could be other reasons also. Execute dmesg or look at mysql logs. Path for MySQL logs are specified in mysql.cnf.