Lightning Fast LAMP Environment on AWS EC2 for Magento 2.3 with Varnish & HAProxy

Rohan Sharmano comments

blog image

Well we all know that nobody likes a slow website, and this becomes even more crucial for eCommerce site owners. Every second delay can cost you a drop in your conversions.

Talking about eCommerce and you can’t ignore Magento. It is also our preferred eCommerce platform for eCommerce Development.

Magento comes loaded with features and flexibility for developers but this makes it a very large and complex system. Often, we receive requests from eCommerce Merchants to speed up their Magento stores.

Magento is resource hungry and deploying such a huge code base requires a highly optimised environment with supporting hardware configuration.

This guide will provide best practices and configurations for a lighting fast Magento 2 store.

Summary

  1. Operating System on AWS
  2. Apache with HTTP2
  3. PHP-FPM
  4. Apache MPM
  5. PHP Opcache
  6. Magento 2 Optimization
  7. Varnish with SSL using HAProxy
  8. PHP-FPM Tuning
  9. Conclusion

1. Operating System on AWS

So, before we move ahead, we need a server with operating system. In this guide we are using AWS with Ubuntu as our operating system. It is an open-source operating system but you are free to use other Linux distributions like RedHat Enterprise Linux, CentOS, Debian and similar. Please note that Magento doesn’t support Windows & Mac OS.

Memory Requirement: Magento requires at least 2GB of RAM, but we would recommend to have at least 4GB of RAM as you would be requiring third-party extensions or custom code for your store requirements.

If you would like to know how to setup a Ubuntu instance on AWS EC2 then you can check it here

Please keep in mind that you have to open port 80 for the http request. You can do this under security group in AWS console panel, Click here to see how. We would also recommend opening 443 because browsers are now forcing you to have SSL certificates for your website and you would also like to keep your store secure.

2. Apache with HTTP2

Once our Server is ready with required ports open, we can then proceed with web server installation. Magento supports Apache 2.2 or 2.4 and Nginx 1.x. In this guide we are using Apache 2.4 because it is still the most popular web server in the market and very powerful.

Step 1 – Install Apache using Ubuntu Repository

Before we install Apache i would recommend to update and upgrade the packages. Use the following command to do that

sudo apt update
sudo apt upgrade

Apache Installation

sudo apt install apache2

You can now access your default Apache landing page to confirm the installation.

http://your-server-ip

Make sure port 80 is open or else it will not load.

Step 2 – Enable HTTP2

Check Apache Version

apache2 -v

Most likely you will notice that Apache 2.4.29 is the current version that has been installed on our server. If in case the version is less than 2.4.24 then we will be using Ondrej PPA for latest release

To add the PPA , type:

sudo add-apt-repository ppa:ondrej/apache2

Once the PPA is added, update and upgrade Apache:

sudo apt update
sudo apt upgrade

This will update and upgrade apache2 to Apache 2.4.27+.

You will now need to add the following line into your Virtual Host config files between <VirtualHost>..</VirtualHost> tags. You can also add this line to /etc/apache2/apache2.conf file if you want all of your sites to run on HTTP2

Protocols h2 h2c http/1.1

Enable mod_http2

Let’s enable the Apache’s mod_http2 module by using the following command

sudo a2enmod http2

Restart Apache

sudo service apache2 restart

Test HTTP2

You can test your webpage to see if HTTP2 is working on your server by checking the headers or you can also check it here

3. PHP-FPM

We have our Apache installed on the server and now we should proceed with PHP installation. In this guide we are going with PHP-FPM, though the most common approach of running PHP with Apache is mod_PHP because it comes default with Apache.

But since our target is to get optimal performance for our Magento store so we will be proceeding with PHP-FPM.

FastCGI Module

Let us first start with installation of FastCGI module that is required to integrate PHP-FPM with Apache

sudo apt install libapache2-mod-fastcgi

This command will most likely throw the following error

So lets proceed to install it manually using the following command

cd /tmp && wget http://mirrors.kernel.org/ubuntu/pool/multiverse/liba/libapache-mod-fastcgi/libapache2-mod-fastcgi_2.4.7~0910052141-1.2_amd64.deb
sudo dpkg -i libapache2-mod-fastcgi_2.4.7~0910052141-1.2_amd64.deb; sudo apt install -f

PHP Installation

We will be using Ondrej PPA for installation of PHP

sudo add-apt-repository ppa:ondrej/php

Once the PPA is added, Update and Install PHP and PHP-FPM packages

sudo apt update
sudo apt install php7.2 php7.2-fpm php7.2-common

Once installed, php7.2-fpm service will start automatically. You can confirm it by running the following command

sudo systemctl status php7.2-fpm

Apache Configuration

Lets enable required modules for apache configuration

sudo a2enmod actions fastcgi alias proxy_fcgi

So far so good, Let us now configure our sites on Apache to run with FPM/FastCGI.

Since we currently didn’t setup any Virtual Hosts so we will be making this change to the 000-default.conf which you will find in /etc/apache2/sites-available/

Add the following within your <VirtualHost> … </VirtualHost> tags

<FilesMatch \.php$>
    # 2.4.10+ can proxy to unix socket
    SetHandler "proxy:unix:/var/run/php/php7.2-fpm.sock|fcgi://localhost/"
 
    # Else we can just use a tcp socket:
    #SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>

Save the file and restart Apache using following command

sudo service apache2 restart

Test PHP-FPM

Create a info.php file containing <?php phpinfo(); ?> in /var/www/html/

Open http://your-server-ip/info.php in your browser and you will see FPM/FastCGI in Server API column.

Awesome, now we have our PHP installed but we would be requiring some PHP extensions that are required by Magento. You can install them by using the following command

PHP Extensions for Magento

sudo apt-get install php7.2-bcmath php7.2-ctype php7.2-curl php7.2-dom php7.2-gd php7.2-iconv php7.2-intl php7.2-mbstring php7.2-mysql php7.2-simplexml php7.2-soap php7.2-xsl php7.2-zip

Restart PHP-FPM by using the following command

sudo systemctl reload php7.2-fpm.service

4. Apache MPM

Apache uses Multi-Processing Modules (MPM) to handle and process incoming requests. There are three types of MPM in apache which are Prefork, Worker & Event MPM.

By default, Apache comes with Prefork MPM. We will not go in detail about the pros and cons of each module, but in this guide, we will be using Event MPM which was introduced in Apache 2.4 and best for managing high loads.

Let’s switch the MPM from Prefork to Event mode

sudo a2dismod mpm_prefork
sudo a2enmod mpm_event

Restart Apache

sudo service apache2 restart

Let us now confirm if the Event Mode is enabled

sudo apachectl -V

You will see Server MPM: event in the output

5. PHP Opcache

Opcache is a caching extension in PHP that stores precompiled scripts in shared memory. So, it eliminates the process of compilation on each request as it is reading the precompiled script bytecode from Memory

Let us first start by enabling Opcache. Open php.ini available at the following location:

/etc/php/7.2/fpm/php.ini

Remove Semicolon in front of opcache.enable=1

Following are some recommended PHP Opcache settings for Magento 2:

opcache.memory_consumption=512
opcache.interned_strings_buffer=48
opcache.max_accelerated_files=100000
opcache.revalidate_freq=4

Save the file and restart PHP FPM

sudo systemctl reload php7.2-fpm.service

Confirm PHP Opcache by again opening the php.info in browser

http://your-server-ip/info.php

Perfect, Now we need more extension that would be very beneficial for the performance of our Magento Store

PHP APCu

As per Magento this extension caches file locations for opened files, increasing performance for Magento server calls (including pages, ajax calls, and endpoints)

sudo apt install php7.2-apcu -y

Restart PHP-FPM

sudo systemctl reload php7.2-fpm.service

Confirm it by opening our info.php file in browser

6. Magento 2 Optimization

Our Web server is ready for Magento Installation and all we need is to have a MySQL server.

You can install MySQL on the same server, but our recommendation is to use a separate server for MySQL, preferably on Amazon RDS.

We will not cover the RDS setup in this topic and will proceed with optimizations assuming we have Magento installed on our Server with demo data.

While in Developer Mode go to

Stores > Configuration > Advanced > Developer and make the following changes

Grid Settings > Asynchronous indexing : Enable

CSS Settings > Merge CSS Files : Yes

CSS Settings > Minify CSS Files : Yes

Javascript Settings > Merge JavaScript Files : Yes

Javascript Settings > Minify JavaScript Files : Yes

Javascript Settings > Enable JavaScript Bundling : Yes

Template Settings > Minify HTML : Yes

Stores -> Configuration -> Catalog -> Catalog

Storefront > Use Flat Catalog Category : Yes

Storefront > Use Flat Catalog Product : Yes

Stores -> Configuration -> Sales -> Sales Emails

General Settings > Asynchronous Sending : Enable

System -> Index Management

Set all indexers to “Update by Schedule” mode.

Production Mode

Let’s change the mode to Production now, Login to Magento server as Magento File System Owner and run the following code

bin/magento deploy:mode:set production

7. Varnish with SSL using HAProxy

Varnish is an HTTP reverse proxy that caches content in memory in front of a Web Server. It basically reduces the load on Apache and PHP as all the cacheable pages are managed by Varnish.

Magento 2 comes with built-in support for Varnish caching, though we can continue using Full-Page cache by Magento, but it is recommended to use Varnish because of its performance.

We have created a separate article for Magento and Varnish with SSL Support using HAProxy, Kindly check that for the step by step method.

8. PHP-FPM Tuning

We have successfully installed PHP-FPM, Let’s tune it for an optimal Magento performance.

PHP-FPM has three process managers that manages all the processing. These processes are Static, OnDemand & Dynamic.

We recommend Dynamic process manager for Magento 2

You can locate the PHP-FPM configuration file in /etc/php/7.2/fpm/pool.d/www.conf

Open the file and make the following changes

pm = dynamic
pm.max_children = 70
pm.start_servers = 8
pm.min_spare_servers = 4
pm.max_spare_servers = 16
pm.max_requests = 2000

Please note that these are recommended changes and may require different configurations depending upon the Site Traffic, Available RAM, Virtual Machine Configuration etc.

You can use the following method to figure out the correct values

Check Avg. Memory Consumption by Single PHP-FPM Process

ps -ylC php-fpm7.2 --sort:rss

This will output the following

The column RSS contains the avg. memory usage per process in Kilobytes

Which mean our single PHP-FPM process is consuming about 81976/1024 = 80MB.

Let’s say we have approx. 7GB of available RAM on Server, So to calculate the max_children we will use the following formulae:

(1024 * 7)/80 = 102.

Let’s go with 70 max_children

Please also note that we have just setup the server so there is no traffic on it and almost no load on PHP-FPM processes. You can use Apache Benchmark to send requests to your server and see what is the average memory usage of PHP-FPM after that. Make sure you send requests to non-cached Magento pages like Account Sign Up or else our Varnish will be handing the requests and no load will be coming on PHP-FPM.

9. Conclusion

All the above recommendations and configurations are based on our years of experience working with Magento. Though we cannot guarantee that the above configuration would be ideal for all as every store has its own resources, traffic, customisations etc but this will for sure delivers you a great performance and you can notice it after comparing it with others who are not using them.

Leave a Reply

avatar
  Subscribe  
Notify of

Ready to grow customer lifetime value?

Contact Us Today!