How To: Install NginX, PHP-FPM, MySQL, PHP 5.3.10 & WordPress on Ubuntu

 

I’ve used a Linode 512MB VPS running Ubuntu 10.04 LTS for this tutorial. They’re one of the best out there in terms of speed, reliability and performance.

First, let’s start with installing NginX. The easiest way to install NginX on Ubuntu is via apt-get, it installs NginX with a standard configuration, so you won’t have to manually install NginX unless you’re using 3rd party modules or a more advanced configuration.

Before beginning with this tutorial, it is recommended to follow this (Howto: Install NginX on Ubuntu 10.04 (or newer) 32bit via apt-get) tutorial if you have 32bit Ubuntu or this (How to: Install NginX on Ubuntu 10.04 64bit via apt-get) tutorial if you have 64bit Ubuntu.

apt-get install nginx

Once you’re done with that, it’s time to install the required libraries. It will not take much time as I’ve already prepared a list for you.

apt-get install wget nano htop binutils cpp flex gcc libarchive-zip-perl libc6-dev libcompress-zlib-perl m4 libpcre3 libpcre3-dev libssl-dev libpopt-dev lynx make perl perl-modules openssl unzip zip autoconf2.13 gnu-standards automake libtool bison build-essential zlib1g-dev ntp ntpdate autotools-dev g++ bc subversion psmisc libmysqlclient-dev libcurl4-openssl-dev libjpeg62-dev libpng3-dev libxpm-dev libfreetype6-dev libt1-dev libmcrypt-dev libxslt1-dev libbz2-dev libxml2-dev libevent-dev libltdl-dev libmagickwand-dev imagemagick

If the above command gives an error about unmet dependencies, then run:

aptitude install wget nano htop binutils cpp flex gcc libarchive-zip-perl libc6-dev libcompress-zlib-perl m4 libpcre3 libpcre3-dev libssl-dev libpopt-dev lynx make perl perl-modules openssl unzip zip autoconf2.13 gnu-standards automake libtool bison build-essential zlib1g-dev ntp ntpdate autotools-dev g++ bc subversion psmisc libmysqlclient-dev libcurl4-openssl-dev libjpeg62-dev libpng3-dev libxpm-dev libfreetype6-dev libt1-dev libmcrypt-dev libxslt1-dev libbz2-dev libxml2-dev libevent-dev libltdl-dev libmagickwand-dev imagemagick

Now, we’re going to install MySQL using apt-get.

apt-get install mysql-server

Once you’ve installed the above libraries, it’s time to install PHP. We’re going to install PHP manually with our own custom configuration.

mkdir ~/temp_space
 cd ~/temp_space
 wget http://in.php.net/get/php-5.3.10.tar.gz/from/us.php.net/mirror -O php.tar.gz
 tar xzvf php.tar.gz
 cd php-5.3.10

We’ll be working in the folder php-5.3.10, so don’t cd away from it.

Run the following command:

'./configure' '--prefix=/etc/php' '--with-config-file-path=/etc/php' '--with-curl' '--with-pear' '--with-gd' '--with-jpeg-dir' '--with-png-dir' '--with-zlib' '--with-xpm-dir' '--with-freetype-dir' '--with-t1lib' '--with-mcrypt' '--with-mhash' '--with-mysql' '--with-mysqli' '--with-pdo-mysql' '--with-openssl' '--with-xmlrpc' '--with-xsl' '--with-bz2' '--with-gettext' '--with-fpm-user=www-data' '--with-fpm-group=www-data' '--enable-fpm' '--enable-exif' '--enable-wddx' '--enable-zip' '--enable-bcmath' '--enable-calendar' '--enable-ftp' '--enable-mbstring' '--enable-soap' '--enable-sockets' '--enable-sqlite-utf8' '--enable-shmop' '--enable-dba' '--enable-sysvmsg' '--enable-sysvsem' '--enable-sysvshm'

If the above command doesn’t return any error, then continue ahead with the install otherwise, make the required changes.

Once you’ve executed the statement above, run this command while you’re still in the directory php-5.3.3 .

 make && make install

After executing the above command, execute the following set of commands. Again, do not cd away from the directory php-5.3.3.

mkdir /var/log/php-fpm
 chown -R www-data:www-data /var/log/php-fpm
 cp -f php.ini-production /etc/php/php.ini
 chmod 644 /etc/php/php.ini
 cp /etc/php/etc/php-fpm.conf.default /etc/php/etc/php-fpm.conf
 cp -f sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
 chmod 755 /etc/init.d/php-fpm
 update-rc.d -f php-fpm defaults

Now we also have to install the PHP PEAR libraries:

apt-get install php5-dev php-pear

You can now change your current directory. Now, we have to install Imagick. To do that, you can just use pecl.

pecl install imagick

Imagick extension has now been installed, you just need to include it in the php.ini file.

nano /etc/php/php.ini

Find the line which says ‘extension’, without the quotes.

Add the following line next to it:

extension = imagick.so

If you get an error saying extension directory not found, then you just have to change the extension_dir variable in php.ini file. Once you install imagick.so, pecl will print the location of the extension such as /usr/lib/php5/20090626+lfs/imagick.so.
Add the /usr/lib/php5/20090626+lfs/ to the extension_dir variable in php.ini.


After installing everything, it is time to configure PHP-FPM and NginX. First, start with editing the php-fpm.conf file. In this case we have the file at location /etc/php/etc/php-fpm.conf. So use your favorite text editor to edit the file, I use nano.

nano /etc/php/etc/php-fpm.conf

PHP-FPM will not start with the default configuration. Uncomment/Change the values of the following lines in the file:

 pid = /etc/php/var/run/php-fpm.pid
 error_log = /etc/php/var/log/php-fpm.log
 log_level = notice
 pm = dynamic
 pm.max_children = 8
 pm.start_servers = 2
 pm.min_spare_servers = 1
 pm.max_spare_servers = 3
 pm.max_requests = 1000
 emergency_restart_threshold = 4
 emergency_restart_interval = 10s
 process_control_timeout = 10s
 daemonize = yes
 listen.backlog = -1
 listen = 127.0.0.1:9000
 listen.owner = www-data
 listen.group = www-data
 listen.mode = 0666
 user = www-data
 group = www-data
 
 rlimit_files = 32768
 
 rlimit_core = unlimited
 

You can use pm = static in the above config, but pm = dynamic is recommended for optimal performance. You can also change the other variables to suit your needs.

Now, we have to edit NginX’s configuration. To do that, open up /etc/nginx/nginx.conf in your text editor.

nano /etc/nginx/nginx.conf

I have the following configuration:

user www-data;
 worker_processes  4;
 worker_rlimit_nofile 32768;
 error_log  /var/log/nginx/error.log;
 pid        /var/run/nginx.pid;
 
 events {
     worker_connections  4096;
     multi_accept on;
     accept_mutex_delay 50ms;
 }
 
 http {
     include       /etc/nginx/mime.types;
 
     access_log  /var/log/nginx/access.log;
 
     sendfile        on;
     #tcp_nopush     on;
 
     #keepalive_timeout  0;
     keepalive_timeout  65;
     tcp_nodelay        on;
     expires max;
     server_tokens off;
     gzip  on;
     gzip_static on;
     gzip_proxied any;
     gzip_types text/plain text/css application/x-javascript text/xml text/javascript application/xml;
     gzip_vary  on;
     gzip_disable "MSIE [1-6].(?!.*SV1)";
 
     include /etc/nginx/conf.d/*.conf;
     include /etc/nginx/sites-enabled/*;
 }

You can adjust keepalive_timeout if you have a website which has more user interaction such as forums, video sites, etc. then you can adjust it to make user experience better. Pages are served faster to the user if keepalive_timeout is more. server_tokens disables showing the version of NginX it HTTP headers. worker_processes should be equal to the number of CPUs, run the following command to check the number of CPUs

grep processor /proc/cpuinfo

worker_connections should be equal to the number of connections each worker_process can handle. The total no. of connections this configuration can handle is: 16384. worker_rlimit_nofile is the maximum number of descriptors that can be opened by Nginx’s process. You can set it to a higher/lower value depending upon your usage. You’ll find rlimit errors in Nginx logs if this variable is set to a lesser value.

Gzip helps serve the files faster as they’re compressed before they are sent to the user.

Now, restart NginX and PHP-FPM to make sure everything’s fine in the configuration.

service php-fpm restart
 service nginx restart

Finally, it’s time to create the Nginx zone file for your WordPres blog. Start by creating a file in the location /etc/nginx/sites-enabled named after your website, it can be anything. If you’re managing many sites and blogs together then it can very useful and time saving. For this blog, I created a file called tutspundit.com for this blog installation.

My zone file is as follows:

server {
 
             listen   80;
             server_name  www.tutspundit.com;
             rewrite ^/(.*) http://tutspundit.com/$ 1 permanent;
 
            }
 
 
 server {
   listen   80;
   access_log  /var/www/tutspundit.com/log/access.log;
  error_log      /var/www/tutspundit.com/log/error.log info;
 server_name     tutspundit.com;
 root /var/www/tutspundit.com/public_html;
 
 location / {
 index index.php;
 # if the requested file exists, return it immediately
 if (-f $ request_filename) {
         break;
 }
 
 # all other requests go to WordPress
 if (!-e $ request_filename) {
         rewrite . /index.php last;
 }
 }
 
 ## Images and static content is treated different
     location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$  {
       access_log        off;
       expires           30d;
       root /var/www/tutspundit.com/public_html;
     }
 
 
 ## Parse all .php file in the /var/www directory
     location ~ ^.+.php {
         fastcgi_split_path_info ^(.+.php)(.*)$ ;
         fastcgi_pass   backend;
         fastcgi_index  index.php;
         fastcgi_param  SCRIPT_FILENAME  /var/www/tutspundit.com/public_html$ fastcgi_script_name;
         include fastcgi_params;
         fastcgi_param  QUERY_STRING     $ query_string;
         fastcgi_param  REQUEST_METHOD   $ request_method;
         fastcgi_param  CONTENT_TYPE     $ content_type;
         fastcgi_param  CONTENT_LENGTH   $ content_length;
         fastcgi_intercept_errors        on;
         fastcgi_ignore_client_abort     on;
         fastcgi_read_timeout 180;
 
     }
 
     
     ## Disable viewing .htaccess & .htpassword
     location ~ /.ht {
         deny  all;
     }
 }
 
 
 upstream backend {
         server 127.0.0.1:9000;
 
 }

The first server{} block is used to redirect all requests from www.tutspundit.com to tutspundit.com. The 2nd server{} block is used to create the rules for the server listening to tutspundit.com. The rules inside the location / {} block are used to enable WordPress URL rewriting.

All the files for the domain are stored at /var/www/tutspundit.com/. /var/www/tutspundit.com/public_html serves the files to the users. You must make your own changes reflecting the location of your WordPress install. upstream backend{} block is used to add PHP-FPM as a backend for processing PHP.

Save & close the file making required changes. Make a directory at /var/www/ named after your domain name (It can be anything, really. It should reflect the configuration in your zone file.)

 mkdir /var/www/tutspundit.com/public_html
 mkdir /var/www/tutspundit.com/log

Restart Nginx again to make sure everything’s fine. Change your directory to /var/www/tutspundit.com/public_html and install WordPress in it. Now, you must change the ownership of the files and do chmod 755. It enables WordPress to: use the installation/update feature, make changes to the files, etc.

chown www-data:www-data -R /var/www/tutspundit.com/public_html
 chmod 755 -R /var/www/tutspundit.com/public_html

That’s it! You’ve got WordPress installed on your VPS running Nginx. Feel free to drop a comment on this article if you need some help.

 

Leave a Reply