Deploy Laravel App on AWS

How To Install and Configure Laravel with Nginx on Ubuntu 24.04 (LEMP) with PHP 8.2

Introduction

Laravel is a popular open-source PHP framework known for its elegant syntax and comprehensive tools for building modern web applications. Its robust ecosystem and built-in features have made it a favorite among developers, leading to its rapid adoption in recent years.

In this guide, you'll learn how to install and configure a new Laravel application on an Ubuntu 24.04 LTS server. We'll use Composer to download and manage the framework dependencies and Nginx to serve the application.

Prerequisites

To follow this guide, you will need to have an AWS EC2 instance up and running. This guide does not cover the setup of AWS or how to connect to your instance, as we will start from the point where you already have an Ubuntu instance on AWS. Let's get started.

1. Prepare for installing the required PHP and Nginx

In AWS EC2 instances, all root privileges are delegated to the default user. Therefore, you need to use the sudo command before executing any commands that require superuser privileges. This tells the server that you are authorized to run these commands. For example, to update the package list, you would run sudo apt update.

ubuntu@ip-172-31-20:~$ sudo apt update

2. Install Nginx

Install Nginx using the following command:

ubuntu@ip-172-31-20:~$ sudo apt install nginx -y

Now to verify that nginx works. We will need to visit the IP address of the server in the browser.

http://172-31-20

You will see a page like this:

3. Install PHP 8.2 and PHP-FPM

Since PHP 8.2 is relatively new, you might need to add a third-party repository to get the latest version. Use the following commands to add the repository and install PHP 8.2 along with PHP-FPM.

ubuntu@ip-172-31-20:~$ sudo add-apt-repository ppa:ondrej/php

4. Install PHP-FPM

ubuntu@ip-172-31-20:~$ sudo apt install php8.2-fpm

Okay, let's check whether our PHP version has worked or not.

ubuntu@ip-172-31-20:~$ php --version
PHP 8.2.20 (cli) (built: Jun  8 2024 21:38:01) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.20, Copyright (c) Zend Technologies
    with Zend OPcache v8.2.20, Copyright (c), by Zend Technologies

Awesome! It's worked. Before installing Laravel, you need to install several PHP modules required by the framework. These extensions provide additional support for handling character encoding, XML processing, etc. Here is the server requirement.

ubuntu@ip-172-31-20:~$ sudo apt install zip unzip php8.2-zip php8.2-curl php8.2-xml php8.2-intl

5. Installing the Composer

We’ll use Composer to install Laravel and its dependencies. You can install Composer by following the digital ocean guide on How to Install Composer on Ubuntu 22.04. That's the same installation on Ubuntu 24.04. You can feel free to start with Step 2! I already covered the php additional dependencies.

6. Installing the Node.js

Download your desired Node.js version PPA installation script. For example, run the following command to use the Node.js version 22.x.

ubuntu@ip-172-31-20:~$ curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh

Run the Node.js setup script

ubuntu@ip-172-31-20:~$ sudo -E bash nodesource_setup.sh

Install Node.js using the following command.

ubuntu@ip-172-31-20:~$ sudo apt-get install -y nodejs

View the installed Node.js and NPM version on your server.

ubuntu@ip-172-31-20:~$ node -v
v22.3.0
ubuntu@ip-172-31-20:~$ npm -v
10.8.1

7. Installing Laravel App

So right now we have Nginx, PHP, PHP-FPM, and Composer installed. Let's start cloning the Laravel repo from GitHub. To do that, we need to generate an SSH key pair on the server, copy the public key, and save it as a deployment key on GitHub.

ubuntu@ip-172-31-20:~$ ssh-keygen -f /home/ubuntu/.ssh/id_rsa -t rsa -N ''

Okay. Let's print that key.

ubuntu@ip-172-31-20:~$ cat /home/ubuntu/.ssh/id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2*****ubuntu@ip-172-31-20

And paste that key into your repo Settings>Deploy keys.

That's it. And we need to check /www the directory which is owned by the root user or not. Let's change our directory ~ home to /var using:

ubuntu@ip-172-31-20:~$ cd /var

List down all of the directory and file permissions:

ubuntu@ip-172-31-20:/var$ ls -la
drwxr-xr-x  3 root root   4096 Jun 28 09:24 www

That's not good /www the directory is owned by the root user which means if we want to write any files in this directory we will have to use sudo. Okay, let's change the owner to Ubuntu. We need to change the owner chown belong to the user ubuntu and the group ubuntu for /www . Here is the command:

ubuntu@ip-172-31-20:/var$ sudo chown ubuntu:ubuntu www

Why www directory? The www directory in Nginx is commonly used as the document root or web root directory where your website's files (such as HTML, CSS, JavaScript, images, etc.) are stored. When Nginx is configured to serve a website, it looks in this directory to find the files to serve to users. If you want to learn more about nginx, php-fpm like that check it out here.

And let's check again.

ubuntu@ip-172-31-20:/var$ ls -la
drwxr-xr-x  3 ubuntu ubuntu   4096 Jun 28 09:24 www

Cool now. Right? Next, let's clone our Laravel app from GitHub. Change directory to /www and clone it.

ubuntu@ip-172-31-20:/var/www$ git clone git@github.com:ShaungBhone/weshop.git

Great. Now cd to weshop folder and let's install the composer. Notice that we are handling the production version of our app.

ubuntu@ip-172-31-20:/var/www/weshop$ composer install --ignore-platform-reqs --no-dev

We're running composer install --ignore-platform-reqs --no-dev will install only the necessary production dependencies, ignoring any platform requirements, and excluding the development dependencies.

8. Asset Bundling (Vite)

Laravel is now default support with Vite by providing an official plugin and Blade directive to load your assets for development and production. So, we need to install node modules on our server.

ubuntu@ip-172-31-20:/var/www/weshop$ npm install && npm run build

9. Configuring Laravel

We’ll now edit the .env file to customize the configuration options for the current application environment. At this time, we don't have .env file. Just an example file in here. Let's copy that environment file.

ubuntu@ip-172-31-20:/var/www/weshop$ cp .env.example .env
ubuntu@ip-172-31-20:/var/www/weshop$ nano .env

Let's generate the key.

ubuntu@ip-172-31-20:/var/www/weshop$ php artisan key:generate

We don’t need to set up all of them now. Just cover some values.

APP_NAME=Weshop
APP_ENV=production
APP_KEY=base64:qUYh8NpeFrPtJavWF0b8yVSaavzaNTOswv9KZh5Xb9I=
APP_DEBUG=false
APP_URL=http://172.31.20
ASSET_URL=http://172.31.20

Fantastic, we're almost there! All of the Laravel configurations are now complete. But, we need to tell the Nginx "This is our laravel application! I want to show it on the web server". Let's go back to the terminal. Before we configure nginx to display our Laravel application, we need to change back the ownership of the /www directory to a user and a group called www-data.

ubuntu@ip-172-31-20:/var$ sudo chown -R www-data:www-data www

ubuntu@ip-172-31-20:/var$ ll
drwxr-xr-x  4 www-data www-data 4096 Jun 28 14:15 www/

Perfect.

10. Setting up Nginx

We still need to configure Nginx to serve the content. To do this, we’ll create a new virtual host configuration file at /etc/nginx/sites-available:

ubuntu@ip-172-31-20:/var$ cd /etc/nginx/sites-available

The following configuration file contains the recommended settings for Laravel applications on Nginx. So, let's create a new one called weshop.

ubuntu@ip-172-31-20:/etc/nginx/sites-available$ sudo nano weshop

And paste that code.

server {
    listen 80;
    listen [::]:80;
    server_name _;
    root /var/www/weshop/public;
 
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
 
    index index.php;
 
    charset utf-8;
 
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
 
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }
 
    error_page 404 /index.php;
 
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_hide_header X-Powered-By;
    }
 
    location ~ /\.(?!well-known).* {
        deny all;
    }
}

The server_name is left blank, we will use this attribute to match requests coming from a specific domain to a specific nginx block in the future.

We need to activate the weshop new virtual host configuration file into the /etc/nginx/sites-enabled/ The final thing you need to know is that nginx will only read the above blocks that are enabled. To enabled use this command:

sudo ln -s /etc/nginx/sites-available/weshop /etc/nginx/sites-enabled/

In the Nginx configuration file's 'sites-available' directory, the default site configuration is still present. Nginx cannot operate with multiple default sites, so we need to remove the existing default site configuration.

ubuntu@ip-172-31-20:/etc/nginx/sites-available$ ll
total 16
drwxr-xr-x 2 root root 4096 Jun 28 18:49 ./
drwxr-xr-x 8 root root 4096 Jun 28 09:24 ../
-rw-r--r-- 1 root root 2412 Nov 30  2023 default
-rw-r--r-- 1 root root  786 Jun 28 18:49 weshop
ubuntu@ip-172-31-20:/etc/nginx/sites-available$ sudo rm -rf default

And site-enabled directory. Change directory to /etc/nginx/sites-enabled.

ubuntu@ip-172-31-20:/etc/nginx/sites-enabled$ ll
total 8
drwxr-xr-x 2 root root 4096 Jun 28 18:54 ./
drwxr-xr-x 8 root root 4096 Jun 28 09:24 ../
lrwxrwxrwx 1 root root   34 Jun 28 09:24 default -> /etc/nginx/sites-available/default
lrwxrwxrwx 1 root root   33 Jun 28 18:54 weshop -> /etc/nginx/sites-available/weshop
ubuntu@ip-172-31-20:/etc/nginx/sites-enabled$ sudo rm -rf default

To apply the changes, reload Nginx with:

ubuntu@ip-172-31-20:~$ sudo systemctl reload nginx

Now go to your browser and access the application using the server’s domain name or IP address.

http://172.31.20

Boom. you will see your Laravel app.

Conclusion

In this tutorial, you’ve set up a new Laravel application on top of a LEMP stack (Linux, Nginx, MySQL and PHP), running on an Ubuntu 24.04 server with php 8.2. However, I didn't cover MySQL, you can use any other AWS RDS Postgres, SQLite etc.

If you have any error, you can contact me sbdev.business@gmail.com. Follow me and googling with keywords Shaung Bhone. Thank you.

Last updated