Deploy Nuxt.js with Laravel Backend on Forge cover image Photo by Muhannad Ajjan on Unsplash

Deploy Nuxt.js with Laravel Backend on Forge

Mostafa Akram • August 1, 2021

devops laravel

Deploying a server side rendering Nuxt.js app with a Laravel api backend on Laravel Forge was not a straight forward process. So here is what my collegues and I have done.

The App

We have a Laravel backend app that has explored its apis under /api/*, we have Laravel Nova installed for admin panel and of course a Nuxt.js frontend app.

This article shows deploying Nuxt.js for server side rendering not static generated. Which means that Node.js server is required.

From the docs:

Server-side rendering (SSR), is the ability of an application to contribute by displaying the web-page on the server instead of rendering it in the browser. Server-side sends a fully rendered page to the client; the client's JavaScript bundle takes over which then allows the Vue.js app to hydrate.

If you want to deploy a static generated Nuxt.js app where node is not required check out Deploying Your Nuxt.js Site To Laravel Forge by James Brooks.

The Project

The Structure

Your Laravel project folder structure will look something like this:

-- Your Project
    -- app 
    -- client
    -- // other laravel directories 
    -- package.json
    -- tailwind.config.js
    -- nuxt.config.js
    -- ecosystem.config.js
    -- // other files 

Configure Nuxt.js

Set the source directory in nuxt.config.js to the path of the client directory


export default { srcDir: "client/" }

Set your build directory to be inside client directory

export default {
    buildDir: "client/.nuxt"
}

By default, the Nuxt.js development server port is 3000. You can also change the port number from the default port if needed

export default {
    server: {
        port: 3000
    }
}

Check out the docs for more configurations available.

Scripts

As mentioned in the docs:

You should have these commands in your package.json:

{
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate"
  }
}

Let's remove generate as we are not going to use it and one more for production deployment so that package.json scripts will be:

{
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "prod": "nuxt build && pm2 restart ./ecosystem.config.js"
  }
}

The Server

PM2

PM2 is a process management to manage node.js on the server.

Deploying using PM2 (Process Manager 2) is a fast and easy solution for hosting your universal Nuxt application on your server

So make sure you have installed it on the server.

PM2 is configured using ecosystem.config.js:

module.exports = {
    apps: [
        {
            name: 'your-app-name',
            script: './node_modules/nuxt/bin/nuxt.js',
            args: 'start',
            port: 3000, // yoru app port 
            instances: 'max',
            exec_mode: 'cluster',
            cwd: './client'
        }
    ]
};

This will handle running node on the server and execute the start command.

Learn more about configuration file from here.

Configure Nginx on the Server

Update your nginx configuration on Forge as mentioned in the docs here.

The issue is if you have done only these, all of your requests to the server will be proxied to http://127.0.0.1:3000 to the node.js server even your apis and nova routes. But we need to only proxy the frontend routes to http://127.0.0.1:3000 and keep others as they are. So lets update our configurations under Location / { ... } add:

location ~ ^/(api|nova|nova-vendor|nova-api|vendor) {
        try_files $uri/ /index.php?$query_string;
        location ~* \.(jpg|jpeg|gif|css|png|js|ico|html|svg)$ {
        }
}

This will tel nginx that any route that include api, nova, nova-vendor, nova-api or vendor dont proxy it to http://127.0.0.1:3000 but send it to index.php and let Laravel handle it.

This line location ~* \.(jpg|jpeg|gif|css|png|js|ico|html|svg)$ assure that all of your assets including nova's that are not frontend related accessed correctly.

Deployment script

Add to your deployment script on Forge

npm install && npm run prod

Remember npm run prod from package.json will execute

nuxt build && pm2 restart ./ecosystem.config.js

It will build your app by runningnuxt build and then restart PM2 by running pm2 restart ./ecosystem.config.js.

Deploy

Deploy your app and that's it, now you have Nuxt.js app with Laravel backend deployed on Laravel Forge.

Thanks for reading i hope you liked it
Drop me a message at @mostafakram 👋 and let me know what you think
If you found any mistake or issue please report it on Github