Installing Magento 2.2.2 on AWS Linux 2 with PHP 7.1, Nginx & MariaDB

Magento is one of the most feature-rich and established ecommerce platforms available today and is a sensible choice for anyone looking to take their online retail seriously. Installing the most recent Magento 2 Open Source edition on a LEMP stack on AWS can have a few hurdles and despite their best efforts, the documentation can't always cater for all scenarios. So here's the process of setting up a fresh Magento installation on a AWS LEMP stack.

I'm assuming you have already setup your instance and have logged into it through SSH. I tend to use a saved web security group for all of my servers, with HTTP/S access from anywhere and SSH & MySQL from my ip.

First and foremost, ensure all current packages are up to date:


sudo yum update

Install the Repos and Software

Now we can install the epel, remi and mariadb repos, which we will need to setup all of the software for the server. Interestingly, unlike the classic AWS Linux, the epel repo is not available. Additionally, the standard AWS mariadb package is quite old and incompatible with Magento 2.

Tip: When in the editor press i to insert text and press :x to save.


cd /tmp

wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo yum install ./epel-release-latest-7.noarch.rpm -y

wget http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
sudo yum install ./remi-release-7.rpm -y

sudo vi /etc/yum.repos.d/maria.repo

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.2/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

Now let's install everything we need to run the server, including all extensions required by Magento. This will take a minute or two:


sudo yum install git nginx php71-php-fpm php71-php-cli php71-php-mysqlnd php71-php-mbstring php71-php-xml php71-php-intl php71-php-gd php71-php-mcrypt php71-php-soap php71-php-zip MariaDB-server MariaDB-client -y

That's everything we need to run a modern LEMP stack, you could use the above to setup a server to run other platforms too like Laravel or Drupal.

PHP Config

Lets now setup a symbolic link to our php install, this means we can use the standard php command in the command line and will avoid location issues with other software.


sudo ln -s /usr/bin/php71 /usr/bin/php

If you type php -v you should now get the version info. Time to set some config for php, let's open our php.ini and update it to the Magento recommendations:


sudo vi /etc/opt/remi/php71/php.ini

Find the lines below in the file and update their values. Note: Some lines may need to be uncommented.

Tip: Typing /<search string> and hitting enter will find the next instance of your search string.


cgi.fix_pathinfo = 0
max_execution_time = 1800
memory_limit = 2G
zlib.output_compression = On
session.save_path = "/var/opt/remi/php71/lib/php/session"

Save your php.ini and let's move on to www.conf;


sudo vi /etc/opt/remi/php71/php-fpm.d/www.conf

Edit the file to match the following lines, the last few env values should just need to be uncommented:


user = nginx
group = nginx
listen = /var/run/php-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

What we have also done here is setup a unix socket for php-fpm, this makes things a little more direct and faster in general. In the php.ini, we changed the session save path. Let's create that folder and make its owner nginx:


sudo mkdir -p /var/opt/remi/php71/lib/php/session
sudo chown -R nginx:nginx /var/opt/remi/php71/lib/php/

Now we can start our services and set them to automatically start on boot;


sudo service nginx start
sudo service mariadb start
sudo service php71-php-fpm start

sudo chkconfig nginx on
sudo chkconfig mariadb on
sudo chkconfig php71-php-fpm on

Great stuff! Now you should be able to see your nginx server working by going to the ip address.

Download Magento

Time to download Magento 2.2.2 and extract it into our doc root.


sudo mkdir /var/www
cd /var/www
sudo wget https://github.com/magento/magento2/archive/2.2.2.tar.gz
sudo tar -xzvf 2.2.2.tar.gz
sudo mv magento2-2.2.2/ magento2/

Now we have our files extracted into our doc root, we can set some permissions and ownership:


cd magento2
sudo find var vendor pub/static pub/media app/etc -type f -exec chmod g+w {} \;
sudo find var vendor pub/static pub/media app/etc -type d -exec chmod g+ws {} \;
sudo chown -R :nginx .
sudo chmod u+x bin/magento

Composer

Let's get composer, move it into our path and install our Magento dependencies. This will take a minute or two:


cd /tmp
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/bin/composer
cd /var/www/magento2
sudo composer install

Setup MySQL/MariaDB

Before we can setup Magento, we need to have a working database. Let's secure our MariaDB installation by running the following command, answer yes to everything and setup a root MySQL password.


sudo mysql_secure_installation

Now we have a secure MySQL installation, we can setup our database. You will need the root password you set above to login to MySQL and don't forget to update the values to your preferred username/password.


mysql -u root -p
CREATE DATABASE magento;
GRANT ALL ON magento.* TO 'db_admin' IDENTIFIED BY 'db_password';
exit

Install Magento

Finally, now that we have everything in place we can run the Magento installation. You will need to provide your; domain, database details, personal info, login info, currency and timezone.


cd /var/www/magento2/bin
sudo ./magento setup:install --base-url=http://example.com/ \
--db-host=localhost --db-name=magento --db-user=db_admin --db-password=db_password \
--admin-firstname=John --admin-lastname=Doe --admin-email=admin@example.com \
--admin-user=admin --admin-password=admin123 --language=en_GB \
--currency=GBP --timezone=Europe/London --use-rewrites=1

After a minute or two your installation should complete and the installer will give you your unique admin URI. Be sure to make a note of it.

Nginx Config

Now we can setup our site config in nginx, which will point to the nginx config supplied by Magento. Make sure you make the relevant changes to the domain/ip address.


sudo vi /etc/nginx/conf.d/magento.conf

 upstream fastcgi_backend {
     server unix:/var/run/php-fpm.sock;
 }

 server {
     listen 80;
     server_name example.com;
     set $MAGE_ROOT /var/www/magento2;
     include /var/www/magento2/nginx.conf.sample;
 }

Now restart nginx for the changes to take affect and make one final ownership change:


sudo service nginx restart
cd /var/www/magento2
sudo chown -R :nginx .

Yay!!! Now if we hit our ip address again, we should get our fresh Magento 2 installation!

Cron Job

One final step is to setup the cron jobs required for the Magento scheduler under the nginx user:


sudo crontab -u nginx -e

* * * * * /usr/bin/php /var/www/magento2/bin/magento cron:run | grep -v "Ran jobs by schedule" >> /var/www/magento2/var/log/magento.cron.log
* * * * * /usr/bin/php /var/www/magento2/update/cron.php >> /var/www/magento2/var/log/update.cron.log
* * * * * /usr/bin/php /var/www/magento2/bin/magento setup:cron:run >> /var/www/magento2/var/log/setup.cron.log

Clean up

Once you're happy with the installation, it would be a good idea to remove the Magento archive we downloaded, as it is quite large.


sudo rm /var/www/2.2.2.tar.gz

Congratulations, you should now have a fresh install of Magento 2.2.2 running on a AWS LEMP stack! This of course is just the start, Magento can be quite slow and its caching mechanism is not the best solution for production. The next step would be to improve performance by integrating a cache such as Varnish/Redis. Magento supplies great documentation and config files for both of these.