Deploying a Laravel Application with Nginx on AWS

Matt Little
Strategio

--

In this tutorial, we are going to deploy a Laravel application to AWS. The Laravel application is going to be a simple login/register system hosted on an EC2 instance. We will also have a MySQL RDS database as well to store the user data. As for the AWS infrastructure in the tutorial, I am going to be using a Terraform configuration file that I made in a previous blog of mine. If you would like to check out that blog, you can do so here: https://medium.com/strategio/using-terraform-to-create-aws-vpc-ec2-and-rds-instances-c7f3aa416133

We will be using the following technologies in this tutorial:

  • PHP 8.1
  • Laravel 9
  • Nginx
  • Composer

What is PHP?

PHP is a popular scripting language that is geared towards web development. It allows you to turn your static web pages into more dynamic and interactive pages. You can read more about PHP on their website: https://www.php.net/

What is Laravel?

Laravel is a free and open-source PHP framework that provides tools for making developing applications easier. You can read more about Laravel on their website: https://laravel.com/

What is Nginx?

Nginx is a free and open-source HTTP server and a reverse proxy. The great thing with Nginx is how simple it is to configure. It can also handle high loads of traffic. Many companies use it like Netflix, Hulu, Airbnb, and GitHub. You can read more about Nginx on their wiki: https://www.nginx.com/resources/wiki/

What is Composer?

Composer is a PHP dependency manager. It allows you to specify what dependencies you need for your PHP project and it will manage them for you. Think of it like npm with Node.js or pip with Python. You can read more about Composer on their website: https://getcomposer.org/doc/00-intro.md

Prerequisites:

Tasks:

  • Run the Terraform configuration to build the AWS infrastruture
  • Install PHP 8.1, Nginx, and Composer on our EC2 instance
  • Configure Nginx for our EC2 instance
  • Set up the Laravel project on the EC2 instance

Step One — Initializing the AWS Infrastructure with Terraform

  1. Clone the Terraform config from the repo and cd into the directory with the following command:
git clone https://github.com/dispact/terraform-custom-vpc.git \
&& cd terraform-custom-vpc

2. Create a file called secrets.tfvars and open it up in your editor of choice

3. Add the following variables to the secrets.tfvars file:

db_username="admin" // This is going to be your DB master userdb_password="laravelpassword" // This is going to be your DB master user passwordmy_ip="x.x.x.x" // Put your actual IP address here, this is so that you can SSH into the EC2 instance

4. Save the secrets.tfvars file and close out of your editor

5. We also need to create a Key Pair for this Terraform configuration. Go ahead and run the following command:

ssh-keygen -t rsa -b 4096 -m pem -f tutorial_kp && mv tutorial_kp tutorial_kp.pem && chmod 400 tutorial_kp.pem

5. Run the following commands:

terraform init
terraform apply -var-file="secrets.tfvars"

6. When prompted, enter: yes

7. Terraform will begin creating the infrastructure in AWS. This will take a few minutes.

Tip: If you have issues running terraform init, try running:
terraform init -upgrade

8. Once Terraform is done, you will see 4 outputs:

  • database_endpoint
  • database_port
  • web_public_dns
  • web_public_ip

Remember these outputs. We will need them when we are configuring Nginx and Laravel.

9. Go ahead and SSH into the EC2 instance.

ssh -i "tutorial_kp.pem" ubuntu@$(terraform output -raw web_public_dns)

Step Two—Installing PHP 8.1, Nginx, and Composer

  1. First, we need to add the PHP repo to apt
sudo add-apt-repository ppa:ondrej/php -y

2. Update apt and install PHP 8.1, Nginx, and Composer

sudo apt update && sudo apt upgrade -y && sudo apt install -y \ software-properties-common nginx composer php8.1-fpm php8.1-mysql \ php8.1-mbstring php8.1-xml php8.1-bcmath php8.1-curl

Step Three — Configuring Nginx

Anywhere you see 0.0.0.0, replace that with your web_public_ip

  1. First, let’s create the server directory.
sudo mkdir /var/www/0.0.0.0

2. Now that the directory has been created, give Nginx permissions over that directory.

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

3. Let’s create our Nginx config file.

cd /etc/nginx/sites-available && sudo cp default 0.0.0.0

4. Open this file up in your favorite terminal editor, I will be using Vim.

sudo vim 0.0.0.0
  • Change root /var/www/html → root /var/www/0.0.0.0/public
  • Add index.php to the list of index files right below that
  • Change server_name _;server_name 0.0.0.0;
  • Add the following lines below server_name:
add_header X-Frame-Options “SAMEORIGIN”;
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}

5. Go ahead and save the file.

6. Now to enable this configuration, we have to do what is called a symbolic link. First, we need to delete the default enabled configuration.

cd /etc/nginx/sites-enabled && sudo rm default

7. Now we will enable our configuration through a symbolic link.

sudo ln -s ../sites-available/0.0.0.0

Step Four — Setting up the Laravel Project

  1. Let’s head on over to our server directory.
cd /var/www/0.0.0.0

2. Clone the Laravel Project to this directory.

git clone https://github.com/dispact/laravel-auth-system.git .

3. Install the composer dependencies.

composer install

4. Let’s edit our environment variable file. I will be using vim to edit this.

sudo cp .env.example .env && sudo vim .env
  • Change the following variables:
APP_URL=http://0.0.0.0DB_HOST=<database_endpoint_from_terraform_output>
DB_PORT=<database_port_from_terraform_output>
DB_DATABASE=tutorial // This was defined in variables.tf
DB_USERNAME=admin // This was defined in secrets.tfvars
DB_PASSWORD=laravelpassword // This was defined in secrets.tfvars
  • Go ahead and save the .env file.

5. Generate the app key for our project

sudo php artisan:key generate

6. Now we just need to initialize the database and seed it with data

sudo php artisan migrate:fresh --seed

7. We should be good to go now. Let’s head on over to the server’s webpage (http://0.0.0.0) and check it out. You should see something like this:

8. Now you can either create an account and log in or use the one that we seeded into the database.

Email: test@example.com
Password: password

9. If successful, you should see this message:

To avoid any unnecessary charges in AWS, you can tear down the infrastructure we made with Terraform by using this command:

terraform destroy -var-file="secrets.tfvars"

Woohoo!

Congratulations, through this tutorial you learned how to deploy a Laravel 9 application to AWS on an EC2 instance inside a Custom VPC with a MySQL RDS database. If you have any questions, please leave a comment. Follow me for more content like this!

--

--

Matt Little
Strategio

Self-taught Engineer with an interest in Software/DevOps Engineering