AWS

How to Install LEMP with RDS on Ubuntu with Let’s Encrypt SSL – AWS

How to Install LEMP with RDS on Ubuntu with Let’s Encrypt SSL – AWS. In this guide you will learn how to install Nginx, PHP 7.4 and configure MySQL in Amazon RDS.

You will also install some common PHP extensions and adjust the PHP configurations. Finally you will install Let’s Encrypt SSL and configure HTTPS.

This setup is tested on an EC2 Instance with Ubuntu 18.04 OS.

Choose Best Hosting for your Business

PlatformReviewsPricing
Siteground★★★★★$3.95
Kinsta – Google Cloud★★★★★$30

Prerequisites

  1. A running EC2 Instance. Learn how to create an AWS EC2 instance.
  2. Assigned a Elastic IP to your EC2 Instance.
  3. Setup Amazon RDS and connect it with EC2 Instance.
  4. Setup and configure Route 53 and point your domain to AWS.
  5. Successful SSH connection to your EC2 Instance.

SSH to your EC2 Instance and perform the steps listed below.

Step 1: Initial Server Setup

Let’s start by updating the local package index with the following command to the latest available version.

sudo apt update
sudo apt upgrade

Once the update is done you can start installing the required packages.

Step 2: Install Nginx

Nginx is available by default in the Ubuntu repository, so you can install it directly using the apt command.

sudo apt install nginx

This will install nginxand all required dependencies.

Step 3: Setup Firewall

Now you can set up Uncomplicated Firewall (UFW) with Nginx to allow public access on default web ports for HTTP and HTTPS

sudo ufw app list

You will see all listed applications.

Output
Available applications:
   Nginx Full
   Nginx HTTP
   Nginx HTTPS
   OpenSSH
  • Nginx Full: This profile opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic)
  • Nginx HTTP: This profile opens port 80 (normal, unencrypted web traffic)
  • Nginx HTTPS: This profile opens only port 443 (TLS/SSL encrypted traffic)
  • OpenSSH: This profile opens port 22 for SSH access.

If you are not going to use SSL you need to enable only the Nginx profile.

Now we will enable Nginx Full.

sudo ufw allow 'Nginx Full'

With this command you can view the status of UFW.

sudo ufw status

You will see the output as follows.

Output
Status: active
 To                         Action      From
 --                         ------      ----
 Nginx Full                 ALLOW       Anywhere                  
 OpenSSH                    ALLOW       Anywhere                  
 Nginx Full (v6)            ALLOW       Anywhere (v6)             
 OpenSSH (v6)               ALLOW       Anywhere (v6)

Step: 4 Check Nginx Installation

Once Nginx is installed it will be started automatically and already be up and running.

Every process in Nginx is managed with the systemctl command. Check the status of Nginx with the following command.

sudo systemctl status nginx 
Output
 nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2020-01-12 15:43:24 IST; 22h ago
     Docs: man:nginx(8)
 Main PID: 22736 (nginx)
    Tasks: 2 (limit: 669)
   CGroup: /system.slice/nginx.service
           ├─22736 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
           └─22737 nginx: worker process

Now we have Nginx installed and configured Firewall.

Step 5: Install PHP 7.4 FPM

Here we will install PHP 7.4 FPM the current latest version available. Add the ondrej/php which has PHP 7.4 package and other required PHP extensions.

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

Once you have added the PPA you can install PHP 7.4 FPM.

Execute the following command to install PHP 7.4 FPM.

sudo apt install php7.4-fpm

After the installation has completed, you can confirm the installation using the following command

php-fpm7.4 -v

Step 6: Install PHP 7.4 Extensions

Installing PHP extensions are simple with the following syntax.

sudo apt install php7.4-extension_name

Now, install some commonly used php-extensions with the following command.

sudo apt install php7.4-common php7.4-mysql php7.4-xml php7.4-xmlrpc php7.4-curl php7.4-gd php7.4-imagick php7.4-cli php7.4-dev php7.4-imap php7.4-mbstring php7.4-opcache php7.4-soap php7.4-zip php7.4-intl -y

Step 7: Configure PHP 7.4 FPM

Now we configure PHP for Web Applications by changing some values in php.ini file.

For PHP 7.4 FPM the php.ini location will be in following directory.

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

Hit F6 for search inside the editor and update the following values for better performance.

upload_max_filesize = 32M 
post_max_size = 48M
memory_limit = 256M
max_execution_time = 600
max_input_vars = 3000
max_input_time = 1000

Once you have modified your PHP settings, hit CTRL+X and Y to save the configuration and restart PHP-FPM for the changes to take effect.

sudo php-fpm7.4 -t
sudo service php7.4-fpm restart

Step 8: Setup Amazon RDS and connect with EC2

Now you can create an RDS database server with MySQL engine and configure security groups to allow connections from EC2 Instance.

Follow the RDS setup guide to configure it with MySQL.

Step 9: Configure Nginx

Next, open the Nginx configuration file, which can be found at /etc/nginx/nginx.conf

sudo nano /etc/nginx/nginx.conf

The worker_processes directive is the amount of CPU cores your instance. In my case, this is 1.

Uncomment the multi_accept directive and set it to on.

Lower the keepalive_timeout directive to 15.

For security reasons, you should uncomment the server_tokens directive and ensure it is set to off.

Add the new client_max_body_size directive below the server_tokens and set the value to 64m.

Uncomment the gzip_proxied directive and set it to any, uncomment the gzip_comp_level directive and set it to the value of 2 and finally uncomment the gzip_types directive.

In order for Nginx to correctly serve PHP you also need to ensure the fastcgi_param SCRIPT_FILENAME directive is set, otherwise, you will receive a blank white screen when accessing any PHP scripts. So open fastcgi_params file by issuing

sudo nano /etc/nginx/fastcgi_params

Add the following at the end of the file

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

That’s all, this is the basic Nginx configuration, hit CTRL+X followed by Y to save the changes. Ensure that the configuration file contains no errors and restart Nginx for the changes to take effect by issuing the following command

sudo nginx -t

If you get a successful message, then proceed with the following command

sudo service nginx restart

If everything worked out fine, you should still be able to see the Nginx welcome page when visiting your domain in the browser. However, unless visiting a known host the server should return a 444 response. So, we remove the default server blocks from Nginx.

sudo rm /etc/nginx/sites-available/default
sudo rm /etc/nginx/sites-enabled/default

Now you need to add a catch-all block to the Nginx configuration. Open the nginx.conf file

sudo nano /etc/nginx/nginx.conf

Find the line with include /etc/nginx/sites-enabled/*;

Below this line add the following

server { 
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}

Hit CTRL+X followed by Y to save the changes and then test the Nginx configuration and restart Nginx.

sudo nginx -t
sudo service nginx restart

Now when you visit the domain name you should receive an error.

Step 10: Configure Nginx Server Blocks for Domain

Create directories to house your website.

sudo mkdir -p /var/www/html/domainname/public
sudo mkdir -p /var/www/html/domainname/logs

Setup correct permissions.

sudo chmod -R 755 /var/www/html/domainname
sudo chown -R www-data:www-data /var/www/html/domainname

Create a new Nginx configuration for your website in the sites-available directory.

 sudo nano /etc/nginx/sites-available/domainname.com

Copy and paste the following configuration, ensure that you change the domain name with your domain name.

 server {
     listen 80;
     listen [::]:80;
     server_name domainname.com www.domainname.com;

     error_log  /var/www/html/domainname/logs/error.log;

     root  /var/www/html/domainname/public/;
     index index.html index.php;

     location / {
         try_files $uri $uri/ /index.php?$args;
     }

     location = /favicon.ico {
         log_not_found off;
         access_log off;
     }

     location ~ \.php$ {
         try_files $uri =404;
         fastcgi_split_path_info ^(.+.php)(/.+)$;
         fastcgi_pass unix:/run/php/php7.4-fpm.sock;
         fastcgi_read_timeout 3600;
         fastcgi_index index.php;
         fastcgi_buffers 16 16k; 
         fastcgi_buffer_size 32k;
         include fastcgi_params;
     }
} 

Hit Ctrl+X followed by Y and Enter to save the file and exit.

To enable this newly created website configuration, make a symbolic link of the file that you just created into the sites-enabled directory.

sudo ln -s /etc/nginx/sites-available/domainname.com /etc/nginx/sites-enabled/domainname.com

Step 11: Install Let’sEncrypt SSL with Nginx

HTTPS is a protocol for secure communication between a server (instance) and a client (web browser). Due to the introduction of Let’s Encrypt, which provides free SSL certificates, HTTPS are adopted by everyone and also provides trust to your audiences.

sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt install python-certbot-nginx

Now we have installed Cert bot by Let’s Encrypt for Ubuntu 18.04, run this command to receive your certificates.

sudo certbot --nginx certonly

Enter your email and agree to the terms and conditions, then you will receive the list of domains you need to generate SSL certificate.

To select all domains simply hit Enter

This will automatically generate the new certificate for your domain.

Open your Nginx configuration and modify it to allow HTTPS connections and install the SSL certificate.

 sudo nano /etc/nginx/sites-available/domainname.com

The following configuration will redirect all http traffic to https with www. If you need to redirect without www you can modify easily.

 server {
    listen [::]:80;
    listen 80;
    
    server_name domain.com www.domainname.com;
    
    return 301 https://www.domainname.com$request_uri;
}

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

     ssl_certificate /etc/letsencrypt/live/domainname.com/fullchain.pem;
     ssl_certificate_key /etc/letsencrypt/live/domainname.com/privkey.pem; 

     error_log  /var/www/html/domainname/logs/error.log; 

     root  /var/www/html/domainname/public/;
     index index.html index.php;

     return 301 https://www.domainname.com$request_uri; 
} 
 
server {
     listen 443 ssl http2;
     listen [::]:443 ssl http2;
     server_name www.domainname.com;

     ssl_certificate /etc/letsencrypt/live/domainname.com/fullchain.pem;
     ssl_certificate_key /etc/letsencrypt/live/domainname.com/privkey.pem;  

     error_log  /var/www/html/domainname/logs/error.log;

     root  /var/www/html/domainname/public/;
     index index.html index.php;

     location / {
         try_files $uri $uri/ /index.php?$args;
     }

     location = /favicon.ico {
         log_not_found off;
         access_log off;
     }

     location ~ \.php$ {
         try_files $uri =404;
         fastcgi_split_path_info ^(.+.php)(/.+)$;
         fastcgi_pass unix:/run/php/php7.4-fpm.sock;
         fastcgi_read_timeout 3600;
         fastcgi_index index.php;
         fastcgi_buffers 16 16k; 
         fastcgi_buffer_size 32k;
         include fastcgi_params;
     }
} 

The http2 value is all that is needed to enable the HTTP/2 protocol.

Hit CTRL+X followed by Y to save the changes.

Check your configuration and restart Nginx for the changes to take effect.

sudo nginx -t
sudo service nginx restart

Step 12: Renewing SSL Certificate

Certificates provided by Let’s Encrypt are valid for 90 days only, so you need to renew them often. So, let’s test the renewal feature using the following command.

Certificates provided by Let’s Encrypt are valid for 90 days only, so you need to renew them often. Now you set up a cronjob to check for the certificate which is due to expire in next 30 days and renew it automatically.

sudo crontab -e

Add this line at the end of the file

0 0,12 * * * certbot renew >/dev/null 2>&1

Hit CTRL+X followed by Y to save the changes.

This cronjob will attempt to check for renewing the certificate twice daily.

Step: 13: Test the Setup

Once you have done the able steps you can create a new test PHP file in your web directory.

sudo nano /var/www/html/domainname/public/info.php

Paste the below code inside the file.

<?php phpinfo();

Save the file.

Now go ahead and check your domain name with the info.php in the url (domainname.com/info.php).

You will see that your domain got redirected to HTTPS and see the PHP information details.

Become a Certified AWS Professional with this easy to learn course now.

Conclusion

Now you have learned how to install LAMP stack with RDS database setup on Amazon EC2 Instance with Ubuntu 18.04. You have also learned how to install SSL and test the setup.

Thanks for your time. If you face any problem or any feedback, please leave a comment below.

Cloudbooklet builds a large collection of Linux based guides and tutorials on Cloud platforms like Google Cloud, AWS, Azure, DigitalOcean and more

Write A Comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.