Deploy a NuxtJS App and Laravel API on a Linux Server
Tags: ubuntu, javascript, laravel, vue
Published: 2023-10-31 21:07:14

In this tutorial, we will learn how to deploy a NuxtJS app and Laravel on a Linux server. NuxtJS will serve as the frontend view and Laravel as the backend. We have already discussed Laravel API and NuxtJS app in previous articles, which you can find here:

**[Creating the API # [Tutorial-1]](https://dev.to/kamruzzaman/building-a-movie-portal-api-with-laravel-using-the-service-pattern-35i3)
[Configure AI Prompt # [Tutorial-2]](https://dev.to/kamruzzaman/setting-up-ai-prompt-in-nuxtjs-16e6)
[Designing the UI # [Tutorial-3]](https://dev.to/kamruzzaman/laravel-api-integration-in-nuxtjs-b89)**

Linux is a popular and widely used server operating system. In this tutorial, we will be using Ubuntu 22.04.3. I assume you are familiar with Linux, so let's get started.

**Prerequisites** Before we begin, ensure you have the following:
   1.A remote server (VPS)
   2.A domain name

**Step 1**: Check your VPS for the following software and versions. Install them if they are not already present.
   1.nginx -v
   2.php -v
   3.mysql
   4.composer -v
   5.phpMyAdmin (optional)
   6.node -v
   7.npm -v
   8.git --version
   9.pm2 –version

**Step 2: Connect Your Domain to Your Server**
Go to your domain manager, then to the DNS Manager, and set up your IP address. First, create a sub-domain for the Laravel API.


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


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


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

**Note: Your domain setup page may look different from this.**

Then, check your DNS here: https://dnschecker.org/

**Step 3**: Upload Your Laravel and Nuxt App to GitHub

**Step 4**: Server SSH Configuration
Go to your server and check if there is an .ssh folder. If not, create one:

```
sudo mkdir .ssh
```
**Now create a key for your Laravel app:**

```
ssh-keygen -f laravel-movie-api -t ed25519 -C "your_email@example.com"
```
You should now see two files in your **.ssh** folder:
   
   1. laravel-movie-api
   2.laravel-movie-api.pub

Open **laravel-movie-api.pub** and copy the code:

```
cat laravel-movie-api.pub
```

Then, go to your GitHub and open your Laravel project. Click the "Settings" button and paste the key in the key field.


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


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


**Back on your server, create a config file**:

```
touch ~/.ssh/config
```
and add the following code to the config file:

```
Host laravel-movie-api
        HostName github.com
        User your_github_username
        IdentityFile ~/.ssh/laravel-movie-api
        IdentitiesOnly yes

```
Check if your GitHub project connection is okay:

```
ssh -T git@laravel-movie-api
```
If you see a message indicating successful authentication, the connection is okay.
Now, go to your home directory and copy the GitHub link. 


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

Modify this link as shown below, due to the created config file in the **.ssh** folder:

```
Syntax: git clone git@HOST:GITHUB_USERNAME/REPO_NAME
Example: git clone git@laravel-movie-api:your_github_username/laravel-movie-api.git

```
Move the cloned project to the **/var/www** folder:

```
sudo mv laravel-movie-api /var/www
```
Navigate to the **www** folder, then to the **laravel-movie-api** folder, and execute the following commands:

```
cp .env.example .env 
composer install --optimize-autoloader --no-dev
npm install
php artisan key:generate

# Set Permission for storage and bootstrap/cache Folder
sudo chown -R www-data:www-data storage
sudo chown -R www-data:www-data bootstrap/cache
# Add your User and web server user to www-data group
sudo usermod -a -G www-data your_username
sudo usermod -a -G www-data nginx
# Set storage's File Permission to 644
sudo find storage -type f -exec chmod 644 {} \;
# Set storage's Folder Permission to 775
sudo find storage -type d -exec chmod 775 {} \;
Or
sudo chmod -R 775 storage/
# Create Symbolic Link at public/storage which points to the storage/app/public directory.
php artisan storage:link

```

**Step 5: Upload Your MySQL Database to the Server**

**Step 6: Configure Nginx for Laravel**
Go to the Nginx folder and create a configuration file for your Laravel app:

```
cd /etc/nginx/sites-available
sudo nano laravel-movie-api

```
Add the following configuration

```
server{
    listen 80;
    listen [::]:80;
    server_name laravel-movie-api.yourdomain.com www.laravel-movie-api.yourdomain.com;
    root /var/www/laravel-movie-api/public;
    index index.php index.html;
    location / {
         try_files $uri $uri/ /index.php$is_args$args;
    }
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    }
}

```

Enable the virtual host or create a symbolic link of the virtual host file:

```
sudo ln -s /etc/nginx/sites-available/laravel-movie-api /etc/nginx/sites-enabled/laravel-movie-api
```
Check if the configuration is correct:

```
sudo nginx -t
```

Restart Nginx:

```
sudo service nginx restart
```

**Step 7: Check Your Sub-Domain**
Open your browser and check if your sub-domain is working without errors.
**Step 8: Set Up Nuxt App**
Go to your domain manager, then to the DNS Manager, and set up your IP address for the NuxtJS app. Use this app on your main domain. 

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

Then check your DNS here: https://dnschecker.org/

**Step 9: Server SSH Configuration for Nuxt App**

Repeat the SSH key generation and GitHub configuration steps as done for the Laravel app, but this time for your NuxtJS app. Remember to replace the relevant names and paths.

```
ssh-keygen -f nuxt-movie-ui-with-laravel-api -t ed25519 -C "your_email@example.com" 
```
now you can see two file in your **.ssh** folder
   1.nuxt-movie-ui-with-laravel-api
   2.nuxt-movie-ui-with-laravel-api.pub
Now open  **nuxt-movie-ui-with-laravel-api.pub** file and copy code. 
	

```
cat nuxt-movie-ui-with-laravel-api.pub
```
Then go to your github and open your Nuxt project. Click Settings button

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

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

Go to your server and open config file

```
Sudo nano ~/.ssh/config
```
and add this code into config file

```
Host laravel-movie-api
        HostName github.com
        User kamruzzamanripon
        IdentityFile ~/.ssh/ laravel-movie-api
        IdentitiesOnly yes

Host nuxt_movie
        HostName github.com
        User kamruzzamanripon
        IdentityFile ~/.ssh/nuxt-movie-ui-with-laravel-api
        IdentitiesOnly yes

```
Now check your github project connection is ok. Here is code 

```
ssh -T git@nuxt_movie
```

Now go to your Server home directory and copy github link

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

Past your terminal but don’t press enter. Suppose we got this link
```
git@github.com:kamruzzamanripon/nuxt-movie-ui-with-laravel-api.git
``` 
here we modify this link because we created a config file in **.ssh** folder. Here is the modified code

```
Syntax:- git clone git@HOST:GITHUB_USERNAME/REPO_NAME
Example:- git clone git@nuxt_movie: kamruzzamanripon/nuxt-movie-ui-with-laravel-api.git

```
Your server clones this project. Now you move this file to your **/var/www** folder

```
Sudo mv nuxt-movie-ui-with-laravel-api  /var/www
```
Go to www/folder. And then go nuxt-movie-ui-with-laravel-api folder. Command below line

```
npm install
npm run build
sudo nano ecosystem.config.js

```
**# Write below code in ecosystem.config.js file**

```
module.exports = {
  apps : [
      {
        name: "myapp",
        script: ".output/server/index.mjs",
        port: 3001
      }
  ]
}


```

**Restart Nginx:**
```
sudo service nginx restart
```
**Start the app using pm2:**

```
pm2 start ecosystem.config.js
pm2 save
pm2 status

```
**Step 11: Configure Nginx for Nuxt App**

Go to the Nginx folder and create a configuration file for your Nuxt app:

```
cd /etc/nginx/sites-available
sudo nano nuxt-movie-ui-with

```
Add the following configuration:

```
server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.com www.yourdomain.com;
    location / {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

```
Enable the virtual host or create a symbolic link of the virtual host file:

```
sudo ln -s /etc/nginx/sites-available/nuxt-movie-ui-with-laravel-api /etc/nginx/sites-enabled/nuxt-movie-ui-with-laravel-api
```
Check if the configuration is correct:

```
sudo nginx -t
```
Restart Nginx:

```
sudo service nginx restart
```
**Step 12: Check Your Domain**
Open your browser and check if your domain is working without errors.


**Step 13: Update your .env file**
Open your laravel-movie-api .env file

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

update as require
Now open nuxt-movie-ui-with-laravel-api .env file and update

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

Congratulations! You have successfully deployed a NuxtJS app and Laravel API on a Linux server.


**Remark on Git Cloning:**
It's important to note that we used SSH for git cloning instead of HTTPS. This choice is strategic for ease of future development. Imagine you've made some changes to your project locally. With SSH, all you need to do to update your project on the server is a simple **git push** from your local machine, followed by a **git pull** on the server. This process updates your app with the latest changes. Using HTTPS wouldn't offer this straightforward workflow, as it would require repeating the entire process from the beginning for every update.
Furthermore, you can streamline the process even more by implementing auto-deployment. With this setup, any update you push to GitHub automatically reflects on your server. This automation can be achieved through GitHub Actions. In a subsequent tutorial, I plan to delve into the features of GitHub Actions and how you can use them for auto-deployment.
Stay tuned for that, and in the meantime, enjoy the benefits of easy project updates with SSH!


**All Episodes**
[Creating the API # [Tutorial-1]](https://dev.to/kamruzzaman/building-a-movie-portal-api-with-laravel-using-the-service-pattern-35i3)
[Configure AI Prompt # [Tutorial-2]](https://dev.to/kamruzzaman/setting-up-ai-prompt-in-nuxtjs-16e6)
[Designing the UI # [Tutorial-3]](https://dev.to/kamruzzaman/laravel-api-integration-in-nuxtjs-b89)
[Setting up on an Linux Server # [Tutorial-4]](https://dev.to/kamruzzaman/deploy-a-nuxtjs-app-and-laravel-api-on-a-linux-server-54bh)