Install Magento 2 on Ubuntu 20.04 | 18.04 with Nginx and Let’s Encrypt

This brief tutorial shows students and new users how to install Magento 2 eCommerce platform on Ubuntu 18.04 | 20.04 with Nginx HTTP server and Let’s encrypt wildcard SSL certificates.

Magento a free and open source eCommerce platform written in PHP that is used by millions of small businesses to sell and manage their products online.

It enables you to create a complete online store, including inventory management, product catalogs, shipping, invoicing and many more.

You can use Magento to run your online stores and build amazing digital experiences with little efforts.

If you’re looking for a enterprise-grade online store platform to sell your products, Magento should probably be a starting point for you. And if you want to learn how to easily install and mange it, then this post is all you need.

For more about Magento, please check their Homepage

To get started with installing Magento, follow the steps below:

Step 1: Install Nginx HTTP Server

Magento requires a web server to function, and Nginx is one of the most popular opensource web server available today.

To install Nginx on Ubuntu, run the commands below:

sudo apt update
sudo apt install nginx

After installing Nginx, the commands below can be used to stop, start and enable Nginx service to always start up with the server boots.

sudo systemctl stop nginx.service
sudo systemctl start nginx.service
sudo systemctl enable nginx.service

To test whether Nginx is installed and functioning, open your web browser and browse to the server’s IP address or hostname.

http://localhost

nginx default home page test

If you see the above page in your browser, then Nginx is working as expected.

Step 2: Install MariaDB Database Server

You’ll also need a database server to run Magento. A database server is where Magento content get stored.

A true open source database server that you can use with Magento is MariaDB database server. It is fast, secure and the default server for almost all Linux servers.

To install MariaDB, run the commands below:

sudo apt-get install mariadb-server mariadb-client

After installing MariaDB, the commands below can be used to stop, start and enable MariaDB service to always start up when the server boots.

sudo systemctl stop mariadb.service
sudo systemctl start mariadb.service
sudo systemctl enable mariadb.service

Next, run the commands below to secure the database server with a root password if you were not prompted to do so during the installation.

sudo mysql_secure_installation

When prompted, answer the questions below by following the guide.

  • Enter current password for root (enter for none): Just press the Enter
  • Set root password? [Y/n]: Y
  • New password: Enter password
  • Re-enter new password: Repeat password
  • Remove anonymous users? [Y/n]: Y
  • Disallow root login remotely? [Y/n]: Y
  • Remove test database and access to it? [Y/n]:  Y
  • Reload privilege tables now? [Y/n]:  Y

To verify and validate that MariaDB is installed and working, login to the database console using the commands below:

sudo mysql -u root -p

type the root password when prompted.

mariadb welcome

If you see a similar screen as shown above, then the server was successfully installed.

Step 3: Install PHP 7.4 and Related Modules

Magento is a PHP based application, and PHP is required to run it. Since some versions of Ubuntu don’t have the latest version of PHP, you can add a third-party PPA repository to install PHP from there.

The command below will add a third-party PPA to Ubuntu.

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:ondrej/php

Then update and upgrade to PHP 7.4

sudo apt update

Next, run the commands below to install PHP 7.4 and related modules.

sudo apt install php7.4-fpm php7.4-common php7.4-mysql php7.4-gmp php7.4-curl php7.4-intl php7.4-mbstring php7.4-xmlrpc php7.4-gd php7.4-xml php7.4-cli php7.4-zip

After installing PHP 7.4, go and configure some basic settings that may be required for Magento to function properly.

Run the commands below to open PHP

sudo nano /etc/php/7.4/fpm/php.ini

Below are good settings to configure for most Magento websites.

file_uploads = On
allow_url_fopen = On
short_open_tag = On
memory_limit = 256M
cgi.fix_pathinfo = 0
upload_max_filesize = 100M
max_execution_time = 360
date.timezone = America/Chicago

That should get PHP 7.4 installed with some basic settings to allow Magento to function.

Step 4: Create Magento Database

When all the servers installed above, it’s now time to begin setting up Magento environment. First, run the steps below to create a blank database for Magento to use.

Logon to MariaDB database console using the commands below:

sudo mysql -u root -p

Then create a database called magento

CREATE DATABASE magento;

Next, create a database user called magentouser and set password

CREATE USER 'magentouser'@'localhost' IDENTIFIED BY 'new_password_here';

Then grant the user full access to the database.

GRANT ALL ON magento.* TO 'magentouser'@'localhost' WITH GRANT OPTION;

Finally, save your changes and exit.

FLUSH PRIVILEGES;
EXIT;

Step 5: Download Magento

At this point, Magento is ready to be downloaded and installed. Use the commands below to download the latest version of Magento.

To get Magento latest release you may want to use Github repository… Install Composer, Curl and other dependencies to get started…

sudo apt install curl git
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer

After installing curl and Composer above, change into the Nginx root directory and download Magento 2 packages from Github.

When prompted, enter your authentication keys. Your public key is your username; your private key is your password….  ( https://marketplace.magento.com/customer/accessKeys/ )

You’ll have to register for an account to create the key above.

The run the commands below to create a new project called magento.

cd /var/www/
sudo composer create-project --repository=https://repo.magento.com/ magento/project-community-edition magento

Copy and paste the authentication key… (Your public key is your username; your private key is your password)

Output:
Authentication required (repo.magento.com):
Username: 234f2343435d190983j0ew8u3220
Password: 
Do you want to store credentials for repo.magento.com in /opt/magento/.config/composer/auth.json ? [Yn] Y

After downloading Magento packages, run the commands below to install Magento with the following options:

cd /var/www/magento
sudo bin/magento setup:install --base-url-secure=https://example.com/ --db-host=localhost --db-name=magento --db-user=magentouser --db-password=db_user_password_here --admin-firstname=Admin --admin-lastname=User --admin-email=admin@example.com --admin-user=admin --admin-password=admin123 --language=en_US --currency=USD --timezone=America/Chicago --use-rewrites=1
  • The Magento software is installed in the root directory on localhost…. Admin is admin;  therefore: Your storefront URL is https://exmaple.com
  • The database server is on the same localhost as the webserver….
  • The database name is magento, and the magentouser and password is db_user_password_here
  • Uses server rewrites
  • The Magento administrator has the following properties:
    • First and last name are: Admin User
    • Username is: admin
  •  and the password is admin123
  • E-mail address is: admin@example.com
  • Default language is: (U.S. English)
  • Default currency is: U.S. dollars
  • Default time zone is: U.S. Central (America/Chicago)

After that, run the commands below to set the correct permissions for Magento 2 to function.

Then run command below to allow www-data user to own the Magento directory.

sudo chown -R www-data:www-data /var/www/magento/
sudo chmod -R 755 /var/www/magento/

Step 6: Configure Nginx

Below is where you configure Nginx VirtualHost file for the Magento site you’re creating. This file defines how client requests are handled and processed.

Run the commands below to create a new VirtualHost file called magento in the /etc/nginx/sites-available/ directory.

sudo nano /etc/nginx/sites-available/magento

A very good configuration settings for most magento site on Nginx server is below. This configuration should work great.

Copy the content below and save into the file created above.

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

server {
    listen 80;
    listen [::]:80;

    server_name  example.com www.example.com;
    index  index.php;

    set $MAGE_ROOT /var/www/magento;
    set $MAGE_MODE production;

    access_log /var/log/nginx/example.com-access.log;
    error_log /var/log/nginx/example.com-error.log;

    include /var/www/megento/nginx.conf.sample;
}

Save the file and exit.

After saving the file above, run the commands below to enable the new site, then restart Nginx server.

sudo ln -s /etc/nginx/sites-available/magento /etc/nginx/sites-enabled/
sudo systemctl restart nginx.service

At this stage, Magento is ready and can be launched by going to the server’s IP or hostname.

https://example.com

However, if you want to enable SSL or accept web traffic over HTTPS, then you can continue below to install and configure Let’s Encrypt free SSL certificates.

Step 7: Install Let’s Encrypt Wildcard Certificates

At step 6, Magento is ready to use without SSL. However, if you want to serve web traffic over HTTPS, then installing and configuring Let’s Encrypt SSL certificate or other public certificates is a must.

To install Let’s Encrypt, run the commands below.

sudo apt update
sudo apt-get install letsencrypt

The commands above will install certbot tool and all dependencies that will be allowed to make the tool function.

Let’s Encrypt provides many ways to challenge you to validate that you own the domain you want to provide SSL certificates for. You will not be able to generate certificates if you can’t prove that you own the domain you want to secure.

For wildcard certificates, the only challenge method Let’s Encrypt accepts is the DNS challenge, which we can invoke via the preferred-challenges=dns flag.

So, to generate a wildcard cert for domain *.example.com, you run the commands below:

sudo certbot certonly --manual --preferred-challenges=dns --email admin@example.com --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d example.com -d *.example.com

The command options above are explained below:

  • certonly:                                     Obtain or renew a certificate, but do not install
  • –manual:                                    Obtain certificates interactively
  • –preferred-challenges=dns:      Use dns to authenticate domain ownership
  • –server:                                      Specify the endpoint to use to generate
  • –agree-tos:                                 Agree to the ACME server’s subscriber terms
  • -d:                                               Domain name to provide certificates for

After executing the command above, Let’s Encrypt will provide a text string to add a text record to your DNS entry…

Example:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: y
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for example.com

-------------------------------------------------------------------------------
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.

Are you OK with your IP being logged?
-------------------------------------------------------------------------------
(Y)es/(N)o: y

-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.example.com with the following value:

x4MrZ6y-JqFJQRmq_lGi9ReRQHPa1aTC9J2O7wDKzq8

Before continuing, verify the record is deployed.

Go to your DNS provider portal and add a text record for the string above and save…

Let's Encrypt DNS

Wait a few mins before continuing from the prompt.

Some DNS providers take a wile to propagate changes so it may depend on your provider’s platform.

After the changes above and Let’s encrypt is able to validate that you own the domain, you should see a successful message as below:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2020-01-09. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"

The wildcard certificate is now generated and ready to be used.

To verify that the certificate is ready, run the commands below:

sudo certbot certificates

That should display similar screen as below:

Found the following certs:
  Certificate Name: example.com
    Domains: *.example.com
    Expiry Date: 2020-01-05 07:48:04+00:00 (VALID: 85 days)
    Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/example.com/privkey.pem

Now, Let’s Encrypt’s certificates are valid for 90 days… You’ll want to setup a crob job to automate the renewal process… To do that, open crontab and add the entry below:

sudo crontab -e

Then add the line below and save…

0 1 * * * /usr/bin/certbot renew >> /var/log/letsencrypt/renew.log

Save and you’re done!

With Let’s Encrypt installed, reopen Nginx VirtualHost file created above and add Let’s Encrypt configurations to secure your website.

Run the commands below open the file.

sudo nano /etc/nginx/sites-available/magento

Then add the highlighted lines to the VirtualHost file as shown below:

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

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

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name  example.com www.example.com;
    index  index.php;

    set $MAGE_ROOT /var/www/magento;
    set $MAGE_MODE production;

    access_log /var/log/nginx/example.com-access.log;
    error_log /var/log/nginx/example.com-error.log;

    if ($host != "example.com") {
       return 301 https://example.com$request_uri;
    }

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers 'TLS13+AESGCM+AES128:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    ssl_ecdh_curve X25519:sect571r1:secp521r1:secp384r1;

    include /var/www/megento/nginx.conf.sample;
}

After the above, restart Nginx and PHP 7.4-FPM

sudo systemctl reload nginx
sudo systemctl reload php7.4-fpm

Next, open your browser and browse to the server domain name. You should see Magento setup wizard to complete. Please follow the wizard carefully.

https://example.com/

Magento homepage should be displayed on your screen.

Ubuntu Magento

Upgrading Magento

If you want to upgrade Magento in the future, simply follow the steps below:

First stop the webserver.

sudo systemctl stop nginx

In the future when you want to upgrade to a new released version, simply run the commands below to upgrade…

cd /var/www/magento
sudo bin/magento maintenance:enable
sudo composer require magento/product-community-edition 2.2.5 --no-update
sudo composer update
sudo php bin/magento setup:upgrade
sudo php bin/magento setup:di:compile
sudo php bin/magento indexer:reindex
sudo php bin/magento maintenance:disable

You may have to re-run the to update Nginx directory permissions…

That’s it!

Congratulation! You have successfully installed Magento on Ubuntu 18.04 | 20.04. If you find any error above, please use the comment form below to report it.

Thanks,

You may also like the post below:

6 thoughts on “Install Magento 2 on Ubuntu 20.04 | 18.04 with Nginx and Let’s Encrypt

  1. Hi,

    Thank you for this how to.

    There is a caveat: Magento still doesn’t support php 7.4, thus a downgrade to 7.3 is required.

    Furthermore there are typos in the nginx magento conf:
    server fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
    include /var/www/magento/nginx.conf.sample;

  2. I had no luck wit the Community Edition of Magento however 2.4 worked fine.
    Just run:
    sudo git clone -b 2.4.0-develop https://github.com/magento/magento2.git
    cd magento
    sudo composer install
    and then: sudo bin/magento setup:install…. (sample above)
    Don’t forget to remove: fastcgi_pass and change m(e)gento to magento as by Giovanni Grimone comments.
    Also had to install Elastic. Pretty easy by following: https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html

  3. Hi, and thank you. I wont use magento 2 with apache. How can install php ?
    Another question is, van i run multi php version? For example i wont use magento 1.9 and magento 2.3 in the same server. How can i do?

  4. Hello. Thx for the tutorial.

    I have a problem :

    when I put this command :

    “cd /var/www/magento
    sudo bin/magento setup:install –base-url-secure=https://example.com/ –db-host=localhost –db-name=magento –db-user=magentouser –db-password=db_user_password_here –admin-firstname=Admin –admin-lastname=User –admin-email=admin@example.com –admin-user=admin –admin-password=admin123 –language=en_US –currency=USD –timezone=America/Chicago –use-rewrites=1”

    I get the answer :

    “sudo: bin/magento: command not found”

    How can I do ?

    Thx.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.