Deploy Nuxt.js with Laravel Backend on Forge
Mostafa Akram • August 1, 2021
devops laravelDeploying 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
- The
client
directory is where your Vue.js files nuxt.config.js
is the configuration file for Nuxt.jsecosystem.config.js
is your PM2 configuration file (will get back to this again)
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.
- The
name
is the name of your app that will appear for the process. if you have multiple apps on the same server by thus you can distinguish between them - The
script
is telling PM2 which script file we need to run, in this case itsnuxt.js
script - The
args
tells PM2 what arguments to pass to the defined script, we need it to passstart
as an argument, so the result would be./node_modules/nuxt/bin/nuxt.js start
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