Step-by-Step Guide: Installing Magento on Ubuntu 22.04 with Nginx and Elasticsearch

Magento is a powerful, open-source e-commerce platform developed in PHP. Since Adobe’s acquisition in 2018, it’s also known as Adobe eCommerce. Magento allows users to build scalable, professional shopping websites, featuring both single-store and multi-store configurations. It is highly extensible with numerous modules that enhance its functionality.

This guide will walk you through the installation of the Magento open-source community edition, which is equipped with all the essential features needed to set up a robust online store. Additionally, we’ll install Elasticsearch for efficient product catalog searching, Redis for session management and caching, and serve it all using the Nginx server.

Prerequisites

  • A server running Ubuntu 22.04 with at least 2GB of RAM, although more memory might be necessary depending on your specific requirements.
  • A non-root user with sudo privileges.
  • A fully qualified domain name (FQDN) for the server, e.g., magento.example.com
  • Ensure your system’s packages are up to date:
    $ sudo apt update
    $ sudo apt upgrade
    
  • Install essential packages, several of which may already be present on your system:
    $ sudo apt install wget curl nano software-properties-common dirmngr apt-transport-https gnupg2 ca-certificates lsb-release ubuntu-keyring unzip -y
    

Step 1 – Configure Firewall

Begin by configuring the firewall. Verify if Ubuntu’s default UFW (Uncomplicated Firewall) is running:

$ sudo ufw status

You should see an output similar to:

Status: inactive

Allow the SSH port to avoid breaking the current connection when enabling the firewall:

$ sudo ufw allow OpenSSH

Permit HTTP and HTTPS connections:

$ sudo ufw allow http
$ sudo ufw allow https

Activate the firewall:

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Confirm the firewall’s status again:

$ sudo ufw status

The output should be similar to:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443                        ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)

Step 2 – Install PHP and its Extensions

Ubuntu 22.04 includes PHP version 8.1.2, which is slightly outdated. To install the latest PHP 8.2 version, we’ll use Ondrej’s PPA:

$ sudo add-apt-repository ppa:ondrej/php

Install PHP and necessary extensions for Magento:

$ sudo apt install php8.2-fpm php8.2-mysql php8.2-bcmath php8.2-xml php8.2-zip php8.2-curl php8.2-mbstring php8.2-gd php8.2-tidy php8.2-intl php8.2-cli php8.2-soap php8.2-xsl libsodium-dev libsodium23 libssl-dev libcurl14-openssl-dev

Verify the PHP installation:

$ php --version
PHP 8.2.5 (cli) (built: Apr 14 2023 04:27:02) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.5, Copyright (c) Zend Technologies
    with Zend OPcache v8.2.5, Copyright (c), by Zend Technologies

Step 3 – Install Composer

Composer, a PHP dependency management tool, is essential for Magento installation. Download the Composer binary and verify the version:

$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
$ php composer-setup.php --2.2
$ php -r "unlink('composer-setup.php');"
$ sudo mv composer.phar /usr/local/bin/composer
$ composer --version
Composer version 2.2.21 2023-02-15 13:07:40

Step 4 – Install MySQL

Install the latest MySQL version on Ubuntu 22.04 and check the version:

$ sudo apt install mysql-server
$ mysql --version
mysql  Ver 8.0.33-0ubuntu0.22.04.1 for Linux on x86_64 ((Ubuntu))

Configure MySQL for root access and enhance security:

$ sudo mysql
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourPassword12!';
mysql> exit
$ sudo mysql_secure_installation

Step 5 – Configure MySQL

Log into MySQL and create a database and user for Magento:

$ sudo mysql -u root -p
mysql> CREATE DATABASE magento;
mysql> CREATE USER 'magentouser'@'localhost' IDENTIFIED BY 'Your_password2';
mysql> GRANT ALL PRIVILEGES ON magento.* TO 'magentouser'@'localhost';
mysql> FLUSH PRIVILEGES;
mysql> exit

Step 6 – Install Nginx

Download the latest Nginx version through the official repository. Import the signing key, add the repository, update, and install Nginx:

$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg arch=amd64] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
$ sudo apt update
$ sudo apt install nginx
$ nginx -v
nginx version: nginx/1.24.0
$ sudo systemctl start nginx

Step 7 – Install SSL

Set up Certbot to generate SSL certificates via Snapd, which is pre-installed with Ubuntu 22.04. Verify and install Certbot:

$ sudo snap install core && sudo snap refresh core
$ sudo snap install --classic certbot
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Generate the SSL Certificate:

$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m name@example.com -d magento.example.com
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
$ sudo systemctl list-timers
$ sudo certbot renew --dry-run

Step 8 – Install Elasticsearch

Install Elasticsearch 7.x required by Magento for search functionality:

$ wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list
$ sudo apt update
$ sudo apt install elasticsearch

Limit Elasticsearch’s memory usage based on your server’s capacity:

$ sudo nano /etc/elasticsearch/jvm.options.d/memory.options

Add the following configuration:

-Xms1g
-Xmx1g

Enable and verify Elasticsearch’s functionality:

$ sudo systemctl enable elasticsearch --now
$ curl http://localhost:9200

Step 9 – Install Redis Server

Install Redis for session and cache storage:

$ curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
$ sudo apt update
$ sudo apt install redis
$ redis-server -v

Secure and verify Redis:

$ redis-cli
127.0.0.1:6379> acl setuser default >Your_Redis_Password
127.0.0.1:6379> AUTH Your_Redis_Password
127.0.0.1:6379> ping
127.0.0.1:6379> exit

Step 10 – Download Magento

Prepare the web root for Magento and obtain authentication keys from Magento’s website. Create the Magento project using Composer:

$ sudo mkdir /var/www/magento -p
$ sudo chown $USER:$USER /var/www/magento/ -R
$ cd /var/www
$ composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition magento

Set permissions and ownership:

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

Step 11 – Install Magento

Initiate Magento installation with Elasticsearch and Redis configurations:

$ bin/magento setup:install \
--base-url=http://magento.example.com \
--use-secure=1 \
--base-url-secure=https://magento.example.com \
--use-secure-admin=1 \
--db-host=localhost \
--db-name=magento \
--db-user=magentouser \
--db-password=Your_password2 \
--admin-firstname=Navjot \
--admin-lastname=Singh \
--admin-email=navjot@example.com \
--admin-user=navjot \
--admin-password=admin_password \
--language=en_US \
--currency=USD \
--timezone=America/Chicago \
--use-rewrites=1 \
--elasticsearch-host=http://127.0.0.1 \
--elasticsearch-port=9200 \
--session-save=redis \
--session-save-redis-db=0 \
--session-save-redis-password=redis_password \
--cache-backend=redis \
--cache-backend-redis-db=2 \
--cache-backend-redis-password=redis_password \
--page-cache=redis \
--page-cache-redis-db=4 \
--page-cache-redis-password=redis_password

Note the admin URI and create Magento cron jobs:

$ php bin/magento cron:install
$ crontab -l

Step 12 – Configure PHP-FPM

Update PHP-FPM configurations for Nginx and increase timeout settings:

$ sudo nano /etc/php/8.2/fpm/pool.d/www.conf

Change:

user = nginx
group = nginx
listen.owner = nginx
listen.group = nginx

Adjust execution times, memory limits, and file size limits:

$ sudo sed -i 's/max_execution_time = 30/max_execution_time = 180/' /etc/php/8.2/fpm/php.ini
$ sudo sed -i 's/memory_limit = 128M/memory_limit = 256M/' /etc/php/8.2/fpm/php.ini
$ sudo sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 25M/g' /etc/php/8.2/fpm/php.ini
$ sudo sed -i 's/post_max_size = 8M/post_max_size = 25M/g' /etc/php/8.2/fpm/php.ini
$ sudo sed -i 's/zlib.output_compression = Off/zlib.output_compression = On/g' /etc/php/8.2/fpm/php.ini
$ sudo systemctl restart php8.2-fpm
$ sudo chgrp -R nginx /var/lib/php/sessions

Step 13 – Configure Nginx

Edit the Nginx configuration for Magento.

$ sudo nano /etc/nginx/nginx.conf

Add the following setting:

server_names_hash_bucket_size  64;

Create Magento’s Nginx configuration file:

$ sudo nano /etc/nginx/conf.d/magento.conf

Insert the Magento-specific Nginx configuration:

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

server {
  listen 80;
  listen [::]:80;
  server_name magento.example.com;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name magento.example.com;

  set $MAGE_ROOT /var/www/magento;
  include /var/www/magento/nginx.conf.sample;
  client_max_body_size 25m;

  access_log /var/log/nginx/magento.access.log;
  error_log  /var/log/nginx/magento.error.log;

  # TLS configuration
  ssl_certificate /etc/letsencrypt/live/magento.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/magento.example.com/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/magento.example.com/chain.pem;
  ssl_protocols TLSv1.2 TLSv1.3;

  ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384';
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:50m;
  ssl_session_timeout 1d;

  # OCSP Stapling ---
  ssl_stapling on;
  ssl_stapling_verify on;
  ssl_dhparam /etc/ssl/certs/dhparam.pem;
}

Validate Nginx’s configuration and restart the service:

$ sudo nginx -t
$ sudo systemctl restart nginx

Step 14 – Disable Two-factor Authentication

If sendmail isn’t configured, disable Magento’s two-factor authentication modules:

$ php /var/www/magento/bin/magento module:disable Magento_AdminAdobeImsTwoFactorAuth
$ php /var/www/magento/bin/magento module:disable Magento_TwoFactorAuth
$ php /var/www/magento/bin/magento setup:di:compile
$ php /var/www/magento/bin/magento c:c

Step 15 – Access the Administration Portal

Retrieve the admin URI:

$ php /var/www/magento/bin/magento info:adminuri

Navigate to your admin portal at https://magento.example.com/admin_19uadb and log in with your admin credentials:

Ensure SMTP is configured for email functionality and re-enable two-factor authentication if required.

Step 16 – Enable and Configure Two-factor Authentication

Re-enable the two-factor authentication modules in Magento:

$ php /var/www/magento/bin/magento module:enable Magento_AdminAdobeImsTwoFactorAuth
$ php /var/www/magento/bin/magento module:enable Magento_TwoFactorAuth
$ php /var/www/magento/bin/magento setup:upgrade
$ php /var/www/magento/bin/magento setup:di:compile
$ php /var/www/magento/bin/magento c:c

If you face issues accessing the admin area, deploy the static content forcefully and adjust file permissions:

$ php /var/www/magento/bin/magento setup:static-content:Deploy -f
$ cd /var/www/magento
$ sudo find var generated vendor pub/static pub/media app/etc -type f -exec chmod g+w {} +
$ sudo find var generated vendor pub/static pub/media app/etc -type d -exec chmod g+ws {} +
$ sudo chown -R :nginx .

Utilize Google Authenticator for two-factor authentication during login.

Conclusion

This guide covers the comprehensive installation of Magento on Ubuntu 22.04, utilizing Nginx and Elasticsearch for optimal performance. If you have further queries, feel free to leave a comment below.

FAQ

What is Magento?
Magento is an open-source e-commerce platform written in PHP, which is now also marketed as Adobe eCommerce. It’s used for building customizable and scalable online stores.
What are the prerequisites for installing Magento?
You need a server with Ubuntu 22.04, at least 2GB of RAM, a non-root user with sudo privileges, a domain name, and to ensure the system packages are up to date.
Why do I need Elasticsearch and Redis for Magento?
Elasticsearch is required by Magento for fast and efficient product searches, while Redis is used for improved session and cache management performance.
How do I configure SSL for Magento?
SSL is configured using Certbot, which can be installed through Snapd or Ubuntu’s repository. The guide provides detailed steps to create and verify SSL certificates.
How can I access the Magento administration portal?
You can access the administration portal by navigating to the administration URI provided during setup, typically in the format of https://your-domain/admin_XXXX.
How do I set up two-factor authentication for Magento?
Two-factor authentication can be set up using applications like Google Authenticator. The guide covers the steps to enable and configure it for additional security.