How to setup Opencart with Nginx and MySql


In recent years, nginx is fast overtaking apache as the default web server due to it's smaller footprint and easier configuring ability.

Yet, nginx does not seem to be mainstream yet in the OpenCart community. When I had to create an opencart setup, I had to look up multiple blog posts to create a setup that would work. Interestingly, once opencart was up and running, the whole setup worked like a charm.

Since I worked on an debian based server, I have used the synaptic package manager. Kindly adapt it to the needs of your own package manager.

So here are the steps to get an working opencart setup from scratch.

###System update
Since it is php we are dealing with here, it is always advisable to pick up the latest packages to not miss out on any of the security updates and fixes.

sudo apt-get update

###nginx
Before installing nginx, we should add the appropriate software sources and update.

echo "deb http://ppa.launchpad.net/nginx/stable/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/nginx-stable.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C
sudo apt-get update
sudo apt-get install nginx

nginx will not start automatically. To start nginx, run

sudo service nginx start

To check if nginx is running, run

ps ax | grep nginx

You can check further by directing your browser to the server ip address.

###MySQL Installation
MySQL is one of the best open source databases available. It is often preferred by startups for their speed and ease of use. Opencart is tightly integrated with MySQL and integrating with any other database management system will require an OpenCart expert to do a lot of tuning in the core. So let us close our eyes and type

sudo apt-get install mysql-server

The installation will prompt for a password for root. Enter a secure password.
The mysql server should start running automatically. Test it by running

ps ax | grep mysql

If there are is no process by the name 'mysqld', run the following command to start mysql.

sudo service mysql start

###PHP Installation

Let us install php5 first in case it is not present already.

sudo apt-get install php5 

Next, let us install the php extensions needed by Opencart

sudo apt-get install php5-mysql php5-curl php5-gd php5-mcrypt php5-zlib 

What is PHP-FPM?

PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation with some additional features useful for sites of any size, especially busier sites.

Since we don't use apache, and nginx performs as a reverse proxy (i.e it forwards all request from the user to the fastcgi process seamlessly) we need a FastCGI process at the other end of nginx to process the php requests.

sudo apt-get install php5-fpm

###PHP Configuration
The following changes need to be made in the php configuration file. Open up the php-fpm's php.ini file.

sudo vim /etc/php5/fpm/php.ini

Find the line, cgi.fix_pathinfo=1, and change the 1 to 0.

cgi.fix_pathinfo=0

This is a security risk, since if the fix_pathinfo is 1, then, in case of a request for a missing file, the php interpreter will find the file closest in path to the requested file and execute it. On the other hand, setting the number to 0 ensures that only php files that match the exact requested path will be executed.

We need to make another small change in the php5-fpm configuration.Open up www.conf:

sudo nano /etc/php5/fpm/pool.d/www.conf

Find the line, listen = 127.0.0.1:9000, and change the 127.0.0.1:9000 to /var/run/php5-fpm.sock.

listen = /var/run/php5-fpm.sock

Now, php-fpm will only handle requests originating within the host operating system, a much safer option.

Restart php-fpm:

sudo service php5-fpm restart

###Nginx Configuration
We need to configure nginx to say how the php files need to be handled. It needs to be pass the php requests to PHP-FPM for execution and return the results back to the client. Basically in the context of php files, nginx will be a reverse proxy for PHP-FHM.

We will be changing the example.com's config file. But this can be made in the default nginx site file too.

sudo vim /etc/nginx/sites-available/example_com.config

server {
    listen 80;
    server_name www.example.com;
    access_log /var/log/nginx/example_opencart.log;               
    root /usr/share/nginx/html/example/;
    index index.php index.html;
    location /image/data {
        autoindex on;
    }
    location /admin {
        index index.php;
    }
    location / {
        try_files $uri @opencart;
    }
    location @opencart {
        rewrite ^/(.+)$ /index.php?_route_=$1 last;
    }
# Make sure files with the following extensions do not get loaded by nginx because nginx would display the source code, and these files can contain PASSWORDS!
location ~* \.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|\.php_ {
    deny all;
}
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
}
location ~*  \.(jpg|jpeg|png|gif|css|js|ico)$ {
    expires max;
    log_not_found off;
}
location ~ \.php$ {
    try_files $uri =404;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

}

Let us test it by adding a php info file.

sudo vim /usr/share/nginx/html/example/info.php

Add the following code to the file and save.

<?php
phpinfo();
?>

Restart nginx

sudo service nginx restart

You can see the nginx and php-fpm configuration details by visiting http://example.com/info.php

###Setting up MySQL Database
We need to setup a mysql database for opencart.

Invoke mysql from the commandline

mysql -u root -p

Create the database for opencart by running the following command at the mysql prompt.

create database opencartdb;

Create the user for opencart app by running the following command at the mysql prompt.

CREATE USER 'opencart_user'@'localhost' IDENTIFIED BY 'somepassword';

Now we need to ensure the opencart_user has all privileges on opencartdb.

GRANT ALL ON opencartdb.* TO 'opencart_user'@'localhost';

Please note that the above configuration assumes that mysql and opencart run on the same server.

###Installing Opencart
Upload the opencart files to the directory you want to install it in. Navigate to the directory you have copied the files to and setup the config pages.

cp config-dist.php config.php
cp admin/config-dist.php admin/config.php

The server needs write permissions on the following files. If mode 755 does not work, try with 0777

chmod 0755 image/
chmod 0755 image/cache/
chmod 0755 cache/
chmod 0755 download/
chmod 0755 config.php
chmod 0755 admin/config.php

Once the install is over, change the config files to 0444 or 0644 as that is more secure. The folders can be 0755.

Next, visit the store homepage e.g. http://www.example.com or http://www.example.com/store/

You should be taken to the installer page. Follow the on screen instructions.

After successful install, delete the /install/ directory from ftp.

Thats it! You are done!