Deploying a Laravel Application to EC2 with RDS: A Comprehensive Step-by-Step Guide

Discover step-by-step instructions on deploying Laravel applications with Amazon RDS on AWS. Learn how to create, configure, and connect your RDS inst

Types of RDS Deployment

Deployment optionsDescription
Multi-AZ DB ClusterCreates a DB cluster with a primary DB instance and two readable standby DB instances, with each DB instance in a different Availability Zone (AZ). Provides high availability, data redundancy, and increased capacity to serve read workloads.
Multi-AZ DB instanceCreates a primary DB instance and a standby DB instance in a different AZ. Provides high availability and data redundancy, but the standby DB instance doesn't support connections for read workloads.
Single DB instanceCreates a single DB instance with no standby DB instances.

Create an RDS in AWS

choose the MYSQL engine version that requires your application

and if you choose Template either Production or Dev/Test then you would also need to select an option for Availability and durability

also, you can change the DB instance class (allocation of the computational, network, and memory capacity required by planned workloads of this DB instance.)

keeping everything default

chooses No so that the DB instance isn't publicly accessible, For security, it is a best practice to keep the database private and make sure it isn't accessible from the internet

Database creation will take some time, after successfully creation of RDS we need to create a new Database for our application and create a new user for the application

Allow Incoming Request to an RDS from EC2

To allow incoming requests from an EC2 instance to an Amazon RDS instance, you need to configure the compute resource in an RDS dashboard, scroll down, and click on setup EC2 connection

.

AWS is Adding new security groups in EC2 (ec2-rds-1)and RDS (rds-ec2-1) to allow communication between them

Prepare the Database in RDS

Connect to an RDS

Connect with your newly created RDS MySQL database with the username (admin by default), hostname (From the Connectivity Tab in RDS Console ), and password you chose at the creation time of MySQL in the AWS RDS service

Change the host URL from your RDS from the connectivity Tab in the AWS RDS console

#installing MySQL client if not available
sudo apt install mysql-client
# First time login into RDS MySQL
mysql -u admin -h [HOST] -p

Create a Database, User, and Give Privileges

We are Creating a non-administrative user for an Application usage and giving it the least privileges.

Create a Database and user for our Laravel application, and also give the user the least privileges it requires for application to the new database (in my case app_database)

CREATE DATABASE app_database;
CREATE USER 'db_user'@'%' IDENTIFIED BY 'password-change-me';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, ALTER, INDEX ON app_database.* TO 'db_user'@'%';
FLUSH PRIVILEGES;

At this step, we are done with our Database setup.

Configuring packages in EC2 instance

Installing PHP

Assuming you have launched an EC2 of your configuration with Ubuntu AMI, connect to it using SSH. Use the private key you choose when creating.

Follow the below steps to Install PHP, This will install to latest PHP version available to the Ubuntu repository.


sudo apt-get update
sudo apt -y install php
# Verify 
php -v
# Installing extra module, extension may require,
sudo apt-get install -y php-cli php-json php-common php-mysql php-zip php-gd php-mbstring php-curl php-xml php-bcmath

Installing composer

Installing composer for Laravel project


curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
sudo chmod +x /usr/local/bin/composer

Cloning your Code OR Create a new Project

git clone https://github.com/Azure-Samples/laravel-tasks.git
cd laravel-tasks

Install dependencies with the following commands

composer install
php artisan key:generate

Run Database Migration, Connect Application with RDS

In most of the real projects in Laravel, we need to run the migration before starting the application

php artisan migrate

Provide Credentials to Application

It is recommended to use AWS Secret Manager But in this demo, we are keeping secrets in an env file.

In .env, configure the database settings (like DB_DATABASE, DB_USERNAME, and DB_PASSWORD) using settings that you create after connecting to RDS

php artisan migrate

now we have run run migrations which means our application has RDS database access

Start the Laravel Application

php artisan serve --host=0.0.0.0

Access the application at the IP address at Port 800

Our Application is running fine, lets setup this up with Apache2

Configure Laravel Applications with Apache2

Install Apache2

sudo apt install apache2

Create a Project directory


sudo mkdir /var/www/laravel-tasks

Assuming the project was initially configured at /home/ubuntu directory

copy all your Project files and folders to /var/www/laravel-tasks

sudo cp -r /home/ubuntu/laravel-tasks/ /var/www/laravel-tasks/

Configure Virtual Host

create a New site in Apache2 in/etc/apache2/sites-available/laravel_task_project.conf Paste the below Apache conf in the file and replace it with your domain

<VirtualHost *:80>
   #Replace with your Domain Name
   ServerName laravel.beyonddevops.engineer
   ServerAdmin usama@usama.cim
   DocumentRoot  /var/www/laravel-tasks/public
   <Directory  /var/www/laravel-tasks>
       AllowOverride All
   </Directory>
   ErrorLog ${APACHE_LOG_DIR}/error.log
   CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Disable the default Apache2 site

sudo a2dissite 000-default.conf

enable the new virtual host

sudo a2ensite laravel_task_project

Enable the Apache rewrite module, and finally, restart the Apache service:

sudo a2enmod rewrite
sudo systemctl restart apache2

Adding A record to your Domain Provider

you need to set A record to your Domain Provider domain name or subdomain, whatever you choose in serverName in laravel_task_project.conf file,

in my case

subdomain laravel.beyonddevops.engineer points to (IP ADDRESS OF EC2)

Sometimes DNS entry may take time Verifying your change with https://dnschecker.org/

Now Access your Site from your Domain name

you will get this error due to permissions

The stream or file "/var/www/laravel-tasks/storage/logs/laravel.log" could not be opened in append mode: Failed to open stream: Permission denied The exception occurred while attempting to log: The stream or file "/var/www/laravel-tasks/storage/logs/laravel.log" could not be opened in append mode: Failed to open stream: Permission de

We need to give the web server (which is serving Laravel Application ) user write access to the storage and cache folders, where Laravel stores application-generated files

Modify the owner of Storage and Cache directories

sudo chown -R www-data.www-data /var/www/laravel-tasks/storage
sudo chown -R www-data.www-data /var/www/laravel-tasks/bootstrap/cache

Configure SSL for your Laravel Application

To configure SSL for your Laravel application using Certbot on an Ubuntu server with Apache, follow these steps

Run the following command to install Certbot and the Apache Certbot plugin

sudo apt install certbot python3-certbot-apache

Before Running the below command please make sure Port 80,443 is open from everywhere, which is required for Lets Encrypt to issue your web server the certificate

Generate SSL Certificate

sudo certbot --apache

Here is what Certbot has done to your configuration

  1. Modify your /etc/apache2/sites-available/laravel_task_project.conf

  2. created certificate and private key file inside /etc/letsencrypt/live/laravel.beyonddevops.engineer/

  3. create a new configuration file for SSL

Visit your domain using a web browser. You should see a padlock icon indicating that the connection is secure

It should also redirect HTTP to HTTPS, just make sure you have inbound traffic open to your security groups of EC2

ย