Magento store is slow!
Well, if you are running your store over magento framework, you might have the very same issue. The problem resides in the fact that your website isn’t properly optimized. The point is, that setting up an architecture for your store isn’t a big deal, tuning it properly is the key to desired performance.
Talking about optimization, a website is properly optimized or not depends upon the way the server responds, how data is being fetched and delivered, server’s load handling capacity, etc. To improve the performance and reduce the load on backend server, a frontend server acting as reverse proxy server can be set-up to perform the caching.
Varnish acts as a http accelerator and a reverse proxy caching server. Varnish Cache visits your server once to cache the page, then all future requests for the same page will be served by Varnish Cache. If it doesn’t have a request cached, it will forward the request to your backend and then cache its output.
Magento 2.x is fully compatible with Varnish cache and it generates Varnish configuration file which can be applied directly without any changes. Magento 1.x, however, isn’t fully compatible with Varnish cache. By default, Varnish doesn’t cache requests with cookies and Magento sends the frontend cookie with every request causing a (near) zero hit-rate for Varnish’s cache. Magento 1.x uses Turpentine which is a full page cache extension for Magento that works with Varnish.
Also, in order to make our store fully secure, SSL should be enabled. In our case, as Varnish runs over HTTP and it doesn’t understand HTTPS requests, we have to set up Nginx that runs over port 443 (allowing HTTPS requests) and pass the requests to the Varnish server. Then Varnish fetch data from the backend as per requests and also keeps a copy of fetched data in order to deliver it when the same requests are made in future.
In addition to this, you might encounter sessions and cookies related issues with Turpentine running along with SSL. I have added some additional files in order to fix this bug.
So, our architecture comprises of :
- Apache acting as a backend server running over port 8080.
- Varnish acting as a reverse proxy caching server running over port 6081.
- Nginx acting as a frontend server, providing SSL termination, running over port 443.
Let’s begin with server installation and configuration.
Update and Install LAMP server.
1 2 3 4 5 |
sudo su apt-get update apt-get install lamp-server^ |
It will install apache2 server, php 5 and mysql server. Check their version.
1 2 3 4 5 |
apache2 -v php -v mysql -V |
Create Database.
1 2 3 4 5 6 7 8 9 10 |
mysql -u root -p mysql> create database magento; mysql> grant all on magento.* to 'magento'@'%' identified by 'magento'; mysql> flush privileges; mysql> exit |
Install necessary PHP extensions.
1 2 3 |
apt-get install libcurl3 php5-curl php5-gd php5-mcrypt php5enmod mcrypt |
For Magento to work properly, adjust PHP memory limit as,
1 |
nano /etc/php5/apache2/php.ini |
Change
1 |
memory_limit = 128M |
To
1 |
memory_limit = 512M |
Now, Install magento, unzip the file and move folder to /var/www/ directory.
Setup Virtual Host.
1 |
nano /etc/apache2/sites-enabled/000-default.conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<VirtualHost *:80> ServerName magento.example.com DocumentRoot /var/www/magento <Directory /var/www/magento/> Options Indexes FollowSymLinks MultiViews AllowOverride All Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> |
Enable rewrite module.
1 2 3 |
a2enmod rewrite service apache2 restart |
Change ownerships.
1 |
sudo chown -R www-data:www-data /var/www/magento/ |
Create the host entry.
1 |
nano /etc/hosts |
Add,
1 |
127.0.0.1 magento.example.com |
Now hit the URL http://magento.example.com, and configure Magento.
Now, for reverse proxy caching, install Varnish server.
1 |
apt-get install varnish |
check the varnish version.
1 |
varnishd -V |
configure varnish.
1 |
nano /etc/default/varnish |
and do the following settings for varnish 3.x.
1 2 3 4 5 6 7 |
DAEMON_OPTS="-p esi_syntax=0x2 \ -p cli_buffer=16384 \ -a :6081 \ -T localhost:6082 \ -f /etc/varnish/default.vcl \ -S /etc/varnish/secret \ -s malloc,256m" |
To make Magento 1.9 work with Varnish cache, install a magento extension, Turpentine.
Install and configure Turpentine.
http://www.magentocommerce.com/magento-connect/turpentine-varnish-cache.html
Sign in with your log in credentials and get the extension key.
Go to admin panel and configure the following settings.
System > Magento Connect > Magento Connect Manager > admin details Login >
- Paste extension key to install
- Refresh the page by clicking bottom link (Refresh) after installation.
- Click Return to admin.
- Logout & Re-login.
Now, Go to,
System > Cache Storage Management >
Enable following cache.
- Varnish Pages
- Varnish ESI Blocks
Disable all the other cache.
System > Configuration > TURPENTINE > varnish option :
- Server : Varnish Version -> Auto
- Server List : 127.0.0.1:6082
- Config File Location : {{root_dir}}/var/default.vcl
- Custom VCL File Location : {{root_dir}}/app/code/community/Nexcessnet/Turpentine/misc/custom_include.vcl
Now,
1 |
nano /etc/varnish/secret |
copy the key and paste it in ‘Varnish Authentication Key’ with ‘\n’ in the end.
1 |
0786bc8a-4607-4079-8961-f093c70fyu7f\n |
And set the rest settings to default settings.
Now go to TURPENTINE > Caching Options
- Backend Host : 127.0.0.1
- Backend Port : 8080
Other setting should be configured as per requirement
Save Configuration.
Goto Admin > System > Cache Storage Management.
Click on
- Flush Magento Cache.
- Flush Cache Storage.
- Apply Varnish Config.
- Save Varnish Config.
Here, Turpentine will generate a VCL file as per our Varnish version. Take backup of default.vcl file and create a symlink of the file generated by Turpentine.
1 2 3 |
mv /etc/varnish/default.vcl /etc/varnish/default.vcl_bkp ln -s /var/www/magento/var/default.vcl /etc/varnish/ |
Varnish runs over HTTP and it doesn’t support SSL. To enable SSL, install and configure Nginx in front of the Varnish.
1 2 3 |
apt-get install nginx nginx -v |
Generate keys and certificate for SSL.
1 2 3 |
sudo mkdir /etc/nginx/ssl sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/magento.key -out /etc/ssl/certs/magento.crt |
Now do the following settings.
1 2 3 4 5 6 7 |
Country Name (2 letter code) [AU]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []: magento.example.com Email Address []: |
Change the ports as,
1 2 |
nano /etc/apache2/ports.conf |
and edit the file as,
1 2 3 4 5 6 7 8 9 10 11 |
#Listen 80 Listen 8080 <IfModule ssl_module> Listen 443 </IfModule> <IfModule mod_gnutls.c> Listen 443 </IfModule> |
Change listening ports in backend server configuration file as,
1 2 3 4 5 |
<VirtualHost *:8080> .. .. .. </VirtualHost> |
Now, configure Nginx for enabling SSL.
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 |
server { listen 80 default_server; #listen [::]:80 default_server ipv6only=on; server_name magento.example.com; return 301 https://$server_name$request_uri; } server { listen 443; server_name magento.example.com; ssl on; ssl_certificate /etc/ssl/certs/magento.crt; ssl_certificate_key /etc/ssl/private/magento.key; ssl_session_timeout 5m; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; #ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; ssl_prefer_server_ciphers on; location / { proxy_pass http://127.0.0.1:6081; include /etc/nginx/proxy_params; add_header Ssl_Offloaded 1; # proxy_set_header Access-Control-Allow-Origin "*"; } location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml|woff2) { root /var/www/magento; access_log off; log_not_found off; expires 360d; } location ~ /\.ht { deny all; } } |
Check Nginx configuration.
1 |
nginx -t |
Setup the proxy parameters.
1 |
nano /etc/nginx/proxy_parameters |
1 2 3 4 5 6 7 8 9 10 11 |
client_max_body_size 100M; client_body_buffer_size 1m; proxy_intercept_errors on; proxy_buffering on; proxy_buffer_size 128k; proxy_buffers 256 16k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_max_temp_file_size 0; proxy_read_timeout 300; |
Adjust apache settings.
1 |
nano /etc/apache2/apache.conf |
Add,
1 |
SetEnvIf Ssl-Offloaded 1 HTTPS=on |
Check Apache configuration.
1 |
apache2ctl -t |
Now go to admin panel, and
System > Configuration > Web > Secure >
Change the settings as,
- Base Link URL : https://magento.example.com/
- Use Secure URLs in Frontend : YES
- Use Secure URLs inAdmin : YES
- Offloader header : HTTP_SSL_OFFLOADED
Now to solve sessions related issues for Turpentine when run over ssl, add the following to magento root directory.
1 2 3 |
mkdir -p /var/www/magento/app/code/community/SupportDesk/CartFormKey/Model mkdir /var/www/magento/app/code/community/SupportDesk/CartFormKey/etc |
1 |
nano /var/www/magento/app/code/community/SupportDesk/CartFormKey/Model/Observer.php |
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 |
<?php class SupportDesk_CartFormKey_Model_Observer { function disableCsrf($observer) { $events = array( 'checkout_cart_add', 'checkout_cart_addgroup', 'checkout_cart_updatepost', 'review_product_post', 'sendfriend_product_sendmail', 'wishlist_index_add', 'wishlist_index_update', 'wishlist_index_cart', 'wishlist_index_send', 'catalog_product_compare_add', ); $route = $observer->getEvent()->getControllerAction()->getFullActionName(); if (in_array($route, $events)) { $key = Mage::getSingleton('core/session')->getFormKey(); Mage::app()->getRequest()->setParam('form_key', $key); } } } |
1 |
nano /var/www/magento/app/code/community/SupportDesk/CartFormKey/etc/config.xml |
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 |
<?xml version="1.0" ?> <config> <modules> <SupportDesk_CartFormKey> <version>1.0.0</version> </SupportDesk_CartFormKey> </modules> <global> <models> <supportdesk_cartformkey> <class>SupportDesk_CartFormKey_Model</class> </supportdesk_cartformkey> </models> <events> <controller_action_predispatch> <observers> <controller_action_before> <class>supportdesk_cartformkey/observer</class> <method>disableCsrf</method> </controller_action_before> </observers> </controller_action_predispatch> </events> </global> </config> |
1 |
/var/www/magento/app/etc/modules/SupportDesk_CartFormKey.xml |
1 2 3 4 5 6 7 8 9 10 |
<?xml version="1.0" ?> <config> <modules> <SupportDesk_CartFormKey> <active>true</active> <codePool>community</codePool> </SupportDesk_CartFormKey> </modules> </config> |
Clear all the sessions and cookies.
1 2 3 |
rm -rf /var/www/magento/var/cache/* rm -rf /var/www/magento/var/session/* |
Restart apache, nginx and varnish to enable all the settings.
1 2 3 4 5 |
service apache2 restart service nginx restart service varnish restart |
Hit the URL https://magento.example.com/
To check cache hits use Varnish tools.
1 2 3 |
varnishhist varnishstat |
Also, server response can be seen by,
1 |
curl -I -k https://magento.example.com/ |
Additionally, to configure Magento with Redis as backend cache, CLICK HERE.
6 comments
And in place of those blocks it would say ESI processing not enabled?
Here’s my config.
DAEMON_OPTS=”-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-p cli_buffer=16384 \
-p esi_syntax=0x2 \
-s malloc,1g”