Sunday, September 7, 2025Deploy Nuxt 3 with Node and Nginx
Keven Client A. Cataluña @LinkedIn
Introduction

This guide explains how to deploy a Nuxt 3 application using Node.js and Nginx. It covers building the application, resolving dependency issues, managing the Node.js process with PM2, updating the default Nginx site configuration, and verifying if the deployment is working correctly.

Steps1. Clone the Nuxt project into the web root directory
/var/www/html
    git clone git@github_development:kevenclient/get-go.git
  
2. Enable the server-side rendering (SSR)
nuxt.config.ts
    // https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  ...
  ssr: true,
})
  
3. Build the project
/var/www/html/get-go
    npm run build
  
4. Inline the lru-cache dependency in Nitro configuration (To fix the CommonJS/ESM import error) Error
    file:///var/www/html/get-go/.output/server/chunks/nitro/nitro.mjs:1
import process from 'node:process';globalThis._importMeta_=globalThis._importMeta_||{url:"file:///_entry.js",env:process.env};import { LRUCache } from 'lru-cache';
                                                                                                                                      ^^^^^^^^
SyntaxError: Named export 'LRUCache' not found. The requested module 'lru-cache' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'lru-cache';
const {url:"file:///_entry.js",env:process.env};import { LRUCache } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:182:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:266:5)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:644:26)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:98:5)

Node.js v23.11.1
  
    file:///var/www/html/get-go/.output/server/chunks/nitro/nitro.mjs:1
import process from 'node:process';globalThis._importMeta_=globalThis._importMeta_||{url:"file:///_entry.js",env:process.env};import { LRUCache } from 'lru-cache';
                                                                                                                                      ^^^^^^^^
SyntaxError: The requested module 'lru-cache' does not provide an export named 'LRUCache'
    at ModuleJob._instantiate (node:internal/modules/esm/module_job:182:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:266:5)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:644:26)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:98:5)

Node.js v23.11.1
  
Solution
nitro.config.ts
    export default defineNitroConfig({
  externals: {
    inline: ['lru-cache'],
  },
})
  
5. Verify the build output
/var/www/html/kakeibo
    node .output/server/index.mjs
  
6. Install the latest version of PM2 globally
    npm install pm2@latest -g
  
7. Create a PM2 configuration file with the following content
ecosystem.config.cjs
    module.exports = {
  apps : [{
    name: 'get-go.dev',
    script: './.output/server/index.mjs',
  }],
}
  
8. Start the application with PM2
    pm2 start ecosystem.config.cjs
  
      [PM2][WARN] Applications get-go.dev not running, starting...
  [PM2] App [get-go.dev] launched (1 instances)

  ┌────┬────────────────────┬──────────┬─────────┬───────────┬──────────┬──────────┐
  │ id │ name               │ mode     │ restart │ status    │ cpu      │ memory   │
  ├────┼────────────────────┼──────────┼─────────┼───────────┼──────────┼──────────┤
  │ 0  │ get-go.dev         │ fork     │ 0       │ online    │ 0%       │ 744.0kb  │
  └────┴────────────────────┴──────────┴─────────┴───────────┴──────────┴──────────┘
  
9. Update the default Nginx site configuration
/etc/nginx/sites-available/default
    # Default server configuration
server {
  listen 80 default_server;
  listen [::]:80 default_server;

  # Add index.php to the list if you are using PHP
  index index.html index.htm index.nginx-debian.html;

  server_name _;

  location / {
    proxy_pass http://localhost:3000;
    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;
  }
}
  
10. Test the Nginx configuration
    sudo nginx -t
  
      nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
  nginx: configuration file /etc/nginx/nginx.conf test is successful
  
11. Reload Nginx to apply the changes
    sudo systemctl reload nginx
  
12. Verify the deployment by navigating to https://get-go.dev and you should see the Nuxt 3 project