Deploy Laravel application with Ubuntu Nginx in EC2 server
Published: 2024-03-17 10:49:57

##Create EC2 instance
First let's create ec2 instance


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hva30in8c5unv32bbrc5.png)

Then you can select the OS. Here I have selected Ubuntu 20.04 LTS which available in free tier


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ashokmh8oaa9v7lsrq4i.png)

After that you have to create a key pair (Or select existing one - Here we assume that you know about what is a key pair and how to login with SSH client like putty). And then you have to let them create new security group or use existing one.

##Install Nginx

In here we assume that you know how to log into the the server using SSH client like putty using username server ip and private key


> ###Learning point
> When you use putty you may notice putty get's disconnected time to time when SSH connection gets automatically closed due to inactivity and you have to login again. This way you can prevent it
> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xf98dcs7n2lakaojx9ov.png)
> Here "seconds between keepalives putty" is 0 by default, but you can set it to number like 5. 
> The keepalive feature sends a small packet of data (a "keepalive packet") from the client to the server at regular intervals. This packet is designed to be ignored by the server, aside from acknowledging its receipt. The sole purpose is to generate network activity, thus signaling to any intermediate devices and the server itself that the connection is still in use, even if no data is being actively transferred.

After login we have to install Nginx. Nginx (pronounced as "Engine-X") is a high-performance HTTP and reverse proxy server, as well as a mail proxy server. It is known for its stability, rich feature set, simple configuration, and low resource consumption. After login with putty into server add below commands in cli one by one.

```
sudo apt update
sudo apt install nginx -y
sudo systemctl status nginx
```
Notice the "-y" option in second command. It gives the answer yes to any prompt which pops up during the installation process. In here I have added the same command without "-y" option.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98rtqnxagxebrqhqbzm4.png)

And they ask this question with a prompt


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxgtn8mcjykq5ag50r01.png)

Now if you go to the server's ip address in the browser you can see this 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b85kcbcffzab9s8221xb.png)

Please make sure to enter ip address without https, since you haven't enabled SSL yet

##PHP
Now add these two commands in console.

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

This `sudo add-apt-repository ppa:ondrej/php -y` command adds a Personal Package Archive (PPA) to your system's list of software sources. PPAs allow you to install and update software that is not included in the official Ubuntu repositories. In this case, ppa:ondrej/php is the PPA provided by Ondřej Surý, a Debian developer, who maintains newer versions of PHP packages than those available in the default Ubuntu repositories

To put it really simple **if you run `sudo apt install php8.1` without running you will get this error**


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h850826faieqjuc6sk06.png)

**The reason behind is ubuntu doesn't know about latest PHP versions available. The above mentioned package informs ubuntu about these versions and that they are safe to install.**

Now install PHP and other related extensions of PHP using theses two commands.

```
sudo apt update

sudo apt install -y php8.1 php8.1-fpm php8.1-mbstring php8.1-xml php8.1-mysql php8.1-curl php8.1-zip
```

Here are couple of things to note..

one thing is we have used "-y". If we hadn't added it here, There will be prompts like before for all the packages we are installing.

This is another thing. Watch carefully. Here we are installing php8.1-fpm.  

**Unlike Apache, which can process PHP internally using the mod_php module, Nginx does not have built-in support to execute PHP scripts. Nginx is a reverse proxy and serves static content very efficiently but relies on an external processor for dynamic content, like PHP. This is where PHP-FPM (FastCGI Process Manager) comes into play.** 

> So PHP-FPM is a must when using nginx with PHP

##Prepare the Project Directory
Now run these three commands

```
cd /var/www/html
sudo mkdir project
cd project
sudo chown -R ubuntu:ubuntu /var/www/html/project
```

Making www-data the owner of web files and directories (like your website's root folder) is done for security and functionality reasons:

1. Security: It limits the permissions to only what's necessary. Only the web server (and users with permissions) can modify or access these files, reducing the risk if there's a security breach.

2. Functionality: It ensures the web server can read, write, or execute files as needed, which is important for dynamic sites that write data to disk, use caches, or manage user uploads.

##Install Composer
Add above commands to install composer.

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

##Install Laravel
Run these two comands

```
cd /var/www/html/project
sudo composer create-project --prefer-dist laravel/laravel .
```

##Configure nginx
`sudo vi /etc/nginx/sites-available/project`   

Copy this content to that file

```
server {
        listen 80;
        server_name your_ip;
    
        root /var/www/html/project/public;
        index index.php index.html index.htm;
    
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
    
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    
        location ~ /\.(?!well-known).* {
            deny all;
        }
    
        error_log /var/log/nginx/project_error.log;
        access_log /var/log/nginx/project_access.log;
    }
```

add your ec2 server ip instead of **your_ip**. And And here we have added php-fpm in this line **fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;**                           

Now run below set of commands

```
sudo ln -s /etc/nginx/sites-available/project /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo chmod -R 775 /var/www/html/project/storage
sudo chown -R www-data:www-data /var/www/html/project
```

Now if we goes to browser you will see this..


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ilgv3vvo63xc4wtc66md.png)

Next tutorial we will discuss about adding domains, SSL and pipelines.