# Step by Step Guide to Setting Up Your Ubuntu 22 VPS for Laravel 11 and PHP 8.2

Embark on a journey into the digital realm as we unveil the secrets to harnessing the full power of Ubuntu 22 on your Virtual Private Server (VPS). In this step-by-step guide, we'll be your navigators through the enchanting landscape of Laravel 11 and the dynamic symphony of PHP 8.2. Get ready to sculpt a virtual masterpiece as we demystify the intricacies of setting up your VPS, transforming it into the ultimate canvas for your web development dreams. Let's dive into the future of coding, where innovation meets simplicity, and where your Ubuntu 22 VPS becomes the stage for the seamless dance of Laravel and PHP 8.2.

## Login in server

Login in server with ssh (with password) \[ Replace `username` with actual username and `ip` with actual IP address of the server \]

```bash
ssh username@ip
```

Login in server with ssh (with private key) \[ Replace `username` with actual username and `ip` with actual IP address of the server \]

```bash
ssh -i path/to/private_key.pem username@ip
```

Update the server

```bash
sudo apt update
```

## Install Apache 2

```bash
sudo apt install apache2
```

## Install NginX (If not Apache2)

```bash
sudo apt install nginx
```

## Install php 8.2

```bash
sudo apt install  ca-certificates apt-transport-https software-properties-common
```

```bash
sudo add-apt-repository ppa:ondrej/php
```

```bash
sudo apt update
```

```bash
sudo apt install php8.2 php8.2-common php8.2-opcache php8.2-cli php8.2-gd php8.2-curl php8.2-mysql php8.2-mbstring php8.2-zip php8.2-xml php8.2-intl
```

## Install MySQL server

```bash
sudo apt install mysql-server
```

Create a user and db in MySQL

Login to MySQL Server

```bash
sudo mysql
```

Create user \[ Replace `admin` with your preferred username, `password` with preferred password \]

```bash
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'password';
```

Grant all access for the user created \[ `admin` in our case \]

```bash
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION;
```

Flush the privilege cache

```bash
FLUSH PRIVILEGES;
```

Create Database \[ Replace `mydatabase` with your preferred name \]

```bash
CREATE DATABASE mydatabase;
```

Exit from mysql with `exit` command

```bash
exit;
```

### Git

Check if git is installed or not. If not, install git with below command

```bash
sudo apt install git
```

## Install Composer

```bash
cd ~ && curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php
```

we’ll verify that the downloaded installer matches the SHA-384 hash for the latest installer found on the [Composer Public Keys / Signatures page](https://composer.github.io/pubkeys.html). To facilitate the verification step, you can use the following command to programmatically obtain the latest hash from the Composer page and store it in a shell variable:

```bash
HASH=`curl -sS https://composer.github.io/installer.sig`
```

Now execute the following PHP code, as provided in the Composer [download page](https://getcomposer.org/download/), to verify that the installation script is safe to run:

```bash
php -r "if (hash_file('SHA384', '/tmp/composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
```

You’ll see the following output:

> Installer verified

If the output says `Installer corrupt`, you’ll need to download the installation script again and double check that you’re using the correct hash. Then, repeat the verification process. When you have a verified installer, you can continue.

To install `composer` globally, use the following command which will download and install Composer as a system-wide command named `composer`, under `/usr/local/bin`:

```bash
sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
```

## Install Node

Step 1:

Replace the version number **setup\_**`20`**.x** with your expected version

```bash
cd ~
curl -sL https://deb.nodesource.com/setup_20.x -o nodesource_setup.sh
```

Step 2:

```bash
sudo bash nodesource_setup.sh
```

Step 3:

```bash
sudo apt install nodejs
```

Install yarn (optional)

```bash
npm install --global yarn
```

## Prepare project

Now, go to server root directory

```bash
cd /var/www/html/
```

Clone the repo here \[ Replace `REPO_URL` with your repo url \]

```bash
git pull REPO_URL
```

If there is a permission issue, give appropriate permission, For now I'm giving all user Read Write and Execute permission with the below command.

```bash
sudo chmod 777 -R /var/www/html/
```

Move to project root \[ Replace 'PROJECT\_ROOT' with project directory name \]

```bash
cd PROJECT_ROOT
```

Install dependency

```bash
composer install
```

Copy ENV

```bash
cp .env.example .env
```

Generate an app encryption key

```bash
php artisan key:generate
```

Update the env with Database credentials \[ Replace `mydatabase`, `admin`, `password` with actual values \]

```bash
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=mydatabase
DB_USERNAME=admin
DB_PASSWORD=password
```

## Setup Apache2 configuration

Open the default conf with below command

```bash
sudo nano /etc/apache2/sites-enabled/000-default.conf
```

Remove everything and paste the below conf \[ Replace 'PROJECT\_ROOT' with project directory name \]  
Note: you can use `Ctrl + K` to remove a line in nano.

```bash
<VirtualHost *:80>
    #ServerAdmin admin@example.com
    #ServerName mydomain.com
    DocumentRoot /var/www/html/PROJECT_ROOT/public

    <Directory /var/www/html/PROJECT_ROOT/public>
        Options Indexes MultiViews FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
```

Now save the file with `Ctrl + S` and exit nano with `Ctrl + X`

Enable module rewrite in apache2

```bash
sudo a2enmod rewrite
```

Then restart apache server with the below command

```bash
sudo service apache2 restart
```

## Setup NginX Configuration

Open the default conf with below command

```bash
sudo nano /etc/nginx/sites-enabled/default
```

Remove everything and paste the below conf \[ Replace 'PROJECT\_ROOT' with project directory name \]  
Note: you can use `Ctrl + K` to remove a line in nano.

```bash
server {
        listen 80;
        listen [::]:80;

        root /var/www/PROJECT_ROOT/html;
        index index.html index.htm index.nginx-debian.html;

        server_name your_domain www.your_domain;

        location / {
                try_files $uri $uri/ =404;
        }
}
```

### Laravel specific NginX Conf

```bash
server {
    listen 80;
    listen [::]:80;
    server_name example.com;
    root /var/www/PROJECT_ROOT/html;
 
    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;
    }
}
```

Then restart NginX server with the below command

```bash
sudo service nginx restart
```

These should be everything. If you encounter any challenges, please don't hesitate to leave a comment or contact me for assistance.

Thank you for reading this.
