How to run multiple nuxt instances using expressjs vhost feature

2k Views Asked by At

I am trying to run 2 or more nuxt apps using expressjs and its vhost feature. My aim is to run multiple nuxt apps assigned to different domains in one single port.

Here is what I tried.

  1. I set up 2 nuxt sample apps
  2. I set up expressjs with vhost module added to the package.json
  3. Here is the content of server.js for expressjs

    var vhost = require("express");
    var vhost = require("vhost");
    
    var app = (module.exports = express());
    
    var app_one = require("./app_one/server/index.js");
    var app_two = require("./app_two/server/index.js");
    
    app
        .use(vhost("appone.com", app_one.start_app_one))
        .use(vhost("apptwo.com", app_two.start_app_two))
        .listen(3000);
    
  4. Then I added index.js under server directory in both of the applications.

App One

const express = require("express");
const consola = require("consola");
const {
  Nuxt,
  Builder
} = require("nuxt");
const app = express();

// Import and Set Nuxt.js options
const config = require("../nuxt.config.js");
config.dev = process.env.NODE_ENV !== "production";

async function start() {
  // Init Nuxt.js
  const nuxt = new Nuxt(config);

  const {
    host,
    port
  } = nuxt.options.server;

  // Build only in dev mode
  await nuxt.ready();

  // Give nuxt middleware to express
  app.use(nuxt.render);

  // Listen the server
  app.listen(port, host);
  consola.ready({
    message: `Server listening on http://${host}:${port}`,
    badge: true
  });
}

exports.start_app_one = function () {
  start();
};

App Two

const express = require("express");
const consola = require("consola");
const {
  Nuxt,
  Builder
} = require("nuxt");
const app = express();

// Import and Set Nuxt.js options
const config = require("../nuxt.config.js");
config.dev = process.env.NODE_ENV !== "production";

async function start() {
  // Init Nuxt.js
  const nuxt = new Nuxt(config);

  const {
    host,
    port
  } = nuxt.options.server;

  await nuxt.ready();

  // Give nuxt middleware to express
  app.use(nuxt.render);

  // Listen the server
  app.listen(port, host);
  consola.ready({
    message: `Server listening on http://${host}:${port}`,
    badge: true
  });
}

exports.start_app_two = function () {
  start();
};

Then I run node server.js. When I try to access appone.com:3000 it just shows nuxt loading webpage and stops there. No errors or no messages inside console. I am stuck at this point, Can someone help me?

1

There are 1 best solutions below

0
On BEST ANSWER

So I made it work. Here is how I did it.

  1. set up 2 nuxt sample apps
  2. I set up expressjs with vhost module added to the package.json

Here is the content of server.js for expressjs

const express = require('express')
var vhost = require('vhost')
const app = express()
const port = 3000

const appone = require('./app_one/server/index.js')
const apptwo = require('./app_two/server/index.js')

// app.get('/', (req, res) => res.send('Hello dear world, this is the host app to show vhost capabilities!'))
app
    .use(vhost('appone.com', appone))
    .use(vhost('apptwo.com', apptwo))
    .listen(3000);

// app.listen(port, () => console.log(`Example app listening on port ${port}!`))
  1. Created 2 nuxt with expressjs server using the command below

    npx create-nuxt-app <project-name>

  2. Edited the server/index.js files from both apps remove the app.listen part as we are already listening in the needed port and host using the expressjs server.js file.

Here is the index.js file from both apps.

const express = require("express");
const consola = require("consola");
const { Nuxt, Builder } = require("nuxt");
const app = express();

// Import and Set Nuxt.js options
const config = require("../nuxt.config.js");
config.dev = process.env.NODE_ENV !== "production";

async function start() {
  // Init Nuxt.js
  const nuxt = new Nuxt(config);

  const { host, port } = nuxt.options.server;

  // Build only in dev mode
  if (config.dev) {
    const builder = new Builder(nuxt);
    await builder.build();
  } else {
    await nuxt.ready();
  }
  // Give nuxt middleware to express
  app.use(nuxt.render);

  // Listen the server
  // port = 3005
  // app.listen(port, host)
  // consola.ready({
  //   message: \`Server listening on http://${host}:${port}\`,
  //   badge: true
  // })
}
start();
module.exports = app;
  1. Now I went to each app-specific folders and I run the below command to build the files

    npm run build

  2. Once that's done for both apps. I added changed the package.json file of the app with expressjs vhost set up.

I included the modules needed by my child apps because it was not working without those for some reason.

{
  "name": "webclient_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^0.19.0",
    "express": "^4.17.1",
    "node-fetch": "^2.6.0",
    "nuxt": "^2.10.2",
    "vhost": "^3.0.2",
    "vue-meta": "^2.3.1"
  }
}
  1. Then I changed the nuxt.config.js files from both child apps to include the build directory. I needed to change the build directory to the relative path from the expressjs vhost setup app. So I added this config option as the last item in the config files of both child apps.

For the first app

buildDir: "app_one/.nuxt"

For the second app.

buildDir: "app_two/.nuxt"
  1. After this, I ran node server.js and both apps were accessible from their respective domains ie appone.com:3000 and apptwo.com:3000 without any issues