Host multiple websites using Node.js Express - node.js
I am having problems configuring two different Node.js applications with different domains. Have two directories
"/abc/" -> express-admin setup (backend) -> admin.abc.com
and
"/xyz/" -> express setup (frontend) -> abc.com
I need admin.abc.com to point to express-admin setup and abc.com to express setup. I have vhost installed and both the site listens to port 80.
Have added
app.use(vhost('abc.com', app)); // xyz/app.js file
app.use(vhost('admin.abc.com', app)); // abc/app.js file
My problems:
forever is installed, whenever i start both the apps, the second one is always stopped. I tried using different port for both apps but still having the same error. Individually they run without problems.
I think my setup is too complicated for domain forwarding. Any better suggestions? May be I have a master app.js file which I can use to route the domains to their respective apps without using the app.js of each applications.
I am not sure how you are using the vhost. First of all with vhost approach, you need to run only one express app. Not two. Here is an example.
var express = require('express');
var vhost = require('vhost');
/*
edit /etc/hosts:
127.0.0.1 api.mydomain.local
127.0.0.1 admin.mydomain.local
*/
// require your first app here
var app1 = require("./app1");
// require your second app here
var app2 = require("./app2");
// redirect.use(function(req, res){
// if (!module.parent) console.log(req.vhost);
// res.redirect('http://example.com:3000/' + req.vhost[0]);
// });
// Vhost app
var appWithVhost = module.exports = express();
appWithVhost.use(vhost('api.mydomain.local', app1)); // Serves first app
appWithVhost.use(vhost('admin.mydomain.local', app2)); // Serves second app
/* istanbul ignore next */
if (!module.parent) {
appWithVhost.listen(8000);
console.log('Express started on port 8000');
}
You just need to run the main express app with vhost enabled using forever.
You're hosting the applications on the same port, using the same network interface. So when the second app starts, it will always find the port in use. If you want to use multiple applications on the same port, they each need to have their own network interface. When using vhost, you would still need to listen on a different port for each app. See this example for details. If you would like your apps to be completely independent, you're better off using node-http-proxy. This allows you to host a proxy on port 80 which forwards requests to express apps listening on different ports. If one of these apps crashes, it will not crash the other app, unlike the vhosts approach. This post gives an example of the implementation using node-http-proxy.
Thanks #veggiesaurus for pointing up to node-http-proxy. Apologies for posting late.
Here is how I solved my problem using node-http-proxy
Folder Structure:
www/
server.js
abc/ [express setup]
app.js
xyz/ [express-admin setup]
node_modules/express-admin/app.js
"abc" and "xyz" have there own setup and running on port x.x.x.x:3001 and x.x.x.y:3002
I installed node-http-proxy and added server.js file with following codes. Referred this link
var http = require('http');
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxy();
var options = {
'abc.com': 'http://x.x.x.x:3001',
'xyz.com': 'http://x.x.x.y:3002'
}
http.createServer(function(req, res) {
proxy.web(req, res, {
target: options[req.headers.host]
});
}).listen(80);
Finally, used forever to run all 3 apps setup to run forever in port 3001, 3002 and 80.
const express = require("express");
const app = express();
const fs = require('fs');
app.use((req, res, next) => {
let reqDomain = req.get("host");
if (reqDomain.indexOf(":") > -1) {
reqDomain = reqDomain.split(":")[0];
}
if(reqDomain.endsWith(".local")) {
reqDomain = reqDomain.substring(0, reqDomain.length - 6);
}
const domainPath = "public/" + reqDomain;
let filePath = domainPath + req.originalUrl;
filePath = fs.lstatSync(filePath).isDirectory() ? filePath + "/index.html" : filePath;
console.log(__dirname + "/" + filePath);
res.sendFile(filePath, { root: __dirname });
});
const port = process.env.PORT || 80;
app.listen(port, () => console.log("Server Started on Port " + port));
Inside public directory put you folder like 'my-first-website.com', 'my-second-website.com'
To test locally add following in /etc/hosts
127.0.0.1 my-first-website.com.local
127.0.0.1 my-second-website.com.local
Related
how do I override the default port of 3000 for NodeJS within an Electron app?
I have an Electron app that uses an Angular frontend served at port 4201 and a NodeJS backend. I want to make the app work multi-instance, which would require changing ports (I'm not sure yet whether to do this randomly or some other way). While it's easy to change the frontend from one port to another, the NodeJS backend remains at port 3000 no matter what I do. What, if anything can I do to move it? In Main.js I've tried ... var routes = require('./backend_routes/query'); //importing route routes(backend); //register the route backend.listen(3001); var win, serve; var args = process.argv.slice(1); serve = args.some(function (val) { return val === '--serve'; }); ... and the backend just keeps listening at port 3000. EDIT: There was a question about the code in backend_routes/query . This is that code: //all the backend routes are specified here 'use strict'; module.exports = function(app) { var query = require('../backend_controllers/query'); var reports = require('../backend_controllers/reports'); //Routes app.route('/query').get(query.execute); app.route('/databaselist').get(query.databaselist); app.route('/redodatabaseconnection').get(query.redodatabaseconnection); app.route('/lookupcollections').get(query.lookupcollections); app.route('/lookupcollection').get(query.lookupcollection); app.route('/showhistory').get(query.showhistory); ... }
Simple subdomain with Express
I am trying to use Express as my server in MEAN stack on AWS. However I've ran into a issue trying to setup subdomains. I have my main domain name domain.com and id like to have app.domain.com.. However I've tried everything I've found online to write the functionality into the server.js file and nothing works. How can I easily accomplish this to make the second function instead of loading on Port 8000 load up at my app.domain.com sub domain? Thanks in advance! var express = require('express'); // Main Website var web = express(); web.get('/', function (req, res){ res.sendFile('/web/index.html', { root: '.' }) }); var port = 9000; web.listen(port); console.log('Web Listening on port', port); //Main Application var app = express(); app.get('/', function (req, res){ res.sendFile('/app/index.html', { root: '.' }) }); var port = 8000; app.listen(port); console.log('Web Listening on port', port); Update: I tried using Vhost here but it loads the same thing for both the main domain and the sub domain and so it does not work. here is the code I used: var express = require('express'); var connect = require('connect'); var http = require('http'); var vhost = require('vhost'); // Main Website var web = express(); web.get('/', function (req, res){ res.sendFile('/web/index.html', { root: '.' }) }); var port = 9000; web.listen(port); console.log('Web Listening on port', port); //Main Application var app = connect() app.use(vhost('app.domain.com', function (req, res) { res.sendFile('/app/index.html', { root: '.' }) httpServer.emit('request', req, res) })) app.listen(8000) I don't really need these to be on separate ports that was just something I was trying originally. But either way does not work still..
There's no need for any thing outside of node.js serving on one port. It's just a matter of routing based on the http header. var express = require('express'); var http = require('http'); var vhost = require('vhost'); // Main Website var webapp = express(); webapp.get('/', function (req, res){ res.sendFile('/web/index.html', { root: '.' }); }); //Main Application var mainapp = express(); mainapp.use(function (req, res) { res.sendFile('/app/index.html', { root: '.' }); })); //Virtual Routing Application var app = express(); app.use(vhost('app.domain.com', webapp)); app.use(vhost('domain.com', mainapp)); app.use(vhost('www.domain.com', mainapp)); app.listen(9000);
Since you're using AWS, you can use Application Load Balancer to achieve your goals. Setup an ALB, and point both domains to the ALB CNAME. Then you will need to create 2 target groups, one for app.domain.com and another one for domain.com. Target Group: App protocol: HTTP port: 8000 Target Group: Web protocol: HTTP port: 9000 Attach your EC2 instance to both target groups Target group > Targets > Edit > Add to registered Finally you will have to add an HTTP listener to your ALB, and setup the rules to forward each domain to its target group. After the rules are set, when you enter to app.domain.com the ALB will forward the request to your express app listening on port 8000, and when browsing domain.com the one listening on port 9000 will be used.
If you are using Route53 I recommend you to use Records Set to redirect both domain and subdomain to the same ec2 instance via the ip address then you can use ngix like the comments say in this post enter link description here Using the load balancer (ALB) generates montly the minimum cost of 21.96USD but using Route53 it is minimum of 1USD or less. If you dont want to use a proxy like nginx you can have s3 website hosting with a low cost, arround 6USD and the route 53 routing by 1USD minimum per month and if you have REST API services you can call from front end to your instance depending the site accessed with no problems. Regards,
nodejs server remote connection
I just want a simple http server to control GET and POST request. I made one using nodejs and express. It works great at localhost. But it's not possible to connect this server remotely. I also set static ip address and port forwarding but it's still not possible. I tried port number 80 and 9000 both are set port forwarding. Can any one help me? var http = require("http"); var express = require("express"); var app = express(); var port = 80; app.get('/', function (req,res) { console.log('app.get'); res.send('abc'); }); app.post('/test', function(req,res) { console.log('app.post'); }); http.createServer(app).listen(port,function () { console.log('createServer'); });
use different routes for different ports in express app
Is it possible in express/node app to have different routes configured to different ports? Example: '/foo/bar' accessible to only localhost:3000 '/bar/foo' accessible to only localhost:3002
Yes, but you just create two servers, each on its own port and then create an express app object for each server and register routes for the desired server on the appropriate app object. A given server only listens on one port. const express = require('express'); // first server const app3000 = express(); app3000.get('/bar/foo', function(req, res) { // code here for port 3000 handler }); app3000.listen(3000); // second server const app3002 = express(); app3002.get('/foo/bar', function(req, res) { // code here for port 3002 handler }); app3002.listen(3002);
nodejs app works locally but not when deployed
I'm using iisnode to host a node app. I'm having trouble actually deploying it under my domain name. Here's the main file with two different starting points. The un-commented code is just a simple server that works correctly when accessed via my domain (so iisnode is mapping and handling the node app correctly). The commented code is the entry point for the express app I am working on, and this works when I view from a local host, but when attempting to access via my domain I receive a 'cannot GET application.js' error. var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello, world!'); }).listen(process.env.PORT); //require('./app/init'); //var server = require('./app/server'); //module.exports = server.start(process.env.NODE_ENV); Here is my server.js file. I think its a routing issue, I've substitued a console.log function for the indexRoute function, and it never fires. But I still don't understand why this works correctly accessing via localhost but not under my domain. var express = require('express'); var routes = require('./routes'); var app = express(); function createApplication(environment) { app.get('/', routes.indexRoute); app.listen(process.env.PORT); return app; } module.exports.start = createApplication; I can message a git link for full app if anyone is interested.
Try specifying that you want to listen from all IP addresses, not just localhost by adding '0.0.0.0' as a parameter to listen. Also add a callback to see what happened. app.listen(process.env.PORT, '0.0.0.0', function(err) { console.log("Started listening on %s", app.url); });