how to develop a node.js app which supports multitenancies - node.js

I have a requirement that I want to serve multiple sites(host names) with the same port number.
These sites share the same code files, while only differ in that they have different site configurations and file upload folders.
basically it's just a cms which can host various domains, and usually each domain will have its own themes and configurations and of course db connections.
is there anybody who can give me some directions on this? Thanks very
much.

var subdomains = require('express-subdomains')
, express = require('express')
, app = Express.createServer()
// example: api.example.com/user -> '/api/user'
subdomains
.use('api')
.use('other.vanity.domain')
app.use(subdomains.middleware)
app.get('/api/user' function (req, res, next) {
// ..
})
app.listen()
https://github.com/tblobaum/express-subdomains

Each site should have it's own process and port, and you should proxy requests depending on the hostname.
You can use node-http-proxy or bouncy for proxy each site to its specific port. Another option is to use Express's vhost feature: https://github.com/visionmedia/express/blob/master/examples/vhost/app.js

You can easily support multiple domains from a single HTTP server codebase (see virtual hosting), you will just need to implement logic in your handlers to inspect the request host (e.g. in the Host HTTP header) and act conditionally based on its value. Then you can have any number of DNS names point to your server and act differently on them.
Here's an example:
http.createServer(function (request, response) {
var host = request.headers['Host'];
if (host == 'domain1.com') {
// Execute logic based on that host.
} else if (host == 'domain2.com') {
// Execute other logic...
}
}).listen(8080);

Related

How to get IP address of Computer, in which the node js server runs, to use in react application?

I wanna get the IP address of the computer that the node js server runs in, in order to use the correct URLs of the server inside React application.
for example when I fetch a "http://localhost:<port>/api" from another device in the same network it doesn't work.
I tried to provide the computer IP address manually, but after sometime, a day or two, the IP changes and then I have to open provide the IP address again.
so, I'm asking if there's a way to provide the IP address dynamically to React application?
You can either use the Node networkInterfaces Out Of the Box feature, or use a package that handles parsing request and extracting data for you.
const os = require('os');
const networkInterfaces = os.networkInterfaces();
console.log(networkInterfaces);
If you do not want to parse the response yourself - have a look at highly popular package: request-ip.
https://www.npmjs.com/package/request-ip
const requestIp = require('request-ip');
// inside middleware handler
const ipMiddleware = function(req, res, next) {
const clientIp = requestIp.getClientIp(req);
next();
};
for anyone facing the same problem, I found a simple solution which is to specify a "proxy" in package.json file of the React application:
in package.json file
...
"proxy": "http://192.xxx.xx.xxx:<port>"
...
this way you're telling react to proxy the requests to the backend server when making a request for example to "/api/v1" instead of specifying the whole url like this "http://192.xxx.xx.xxx:<port>/api/v1"
and whenever the IP changes you just edit the "proxy" value and restart the dev server.

express: getting the URL of the running instance globally

I am using express 4.x and I want to know if there is a way to get the URL (for instance localhost:7777 or mydomain.com) during the run-time?
I have several requests, where I need to return images saved on the same server with the full URL, but the IP address / port is changing, therefore I would like a solution, where I can save the URL globally. (not within a get/... request)
I believe you access the app instance:
var app = express();
....
app.address() //address
app.port() // port

How to bind a domain name to expressjs application

How to bind a domain name to expressjs application.My application is running on servername:1001
I want to bind it to www.domainname.com. How can I do this in the application.
I'm searching for the same answer.
I have just been using app.use('/', router) with a processor that then checks the domain off the req object.
router.get('*', (req, res, next) => {
let path = req.path.replace(/^\//g,'').replace(/\/$/g,'');
let domain = req.headers.host.split(':')[0];
domain = domain.replace(/^www\./g,'');
});
This is the closest thing I've been able to come with to actually using express routes per domain. On my own, 4 years ago.
Now there seems to be this VHOST module:
http://expressjs.com/en/resources/middleware/vhost.html
-Robert
Your DNS record you should use CNAME. As a value you should use the domain your hosting provider gave you ex. myapp.herokuapp.com(which on heroku side point to servername:1001).
If you are using hosting like heroku, you should setup to accept traffic for your application for that specific domain. That last configuration is being made on heroku management site.

Generating subdomains on the fly

I am working on a MEAN application which provides people with their own unique sub-domain as part of their sign-up process. How to I do this?
I am open minded regarding what cloud services I use, I am impressed by Digital Ocean for example but it could equally be AWS. So long as it is scalable.
So how can you generate bobsmith.nicksamazingnewapp.com for example when Bob signs up with us? and for him to be able to use it right-away?
Virtual hosts are the way to go. Have a look at this new librabry for express I came across the other day. You are simply using the vhost middleware. https://github.com/expressjs/vhost
Here is a code sample from their site
// create main app
var app = connect()
// add vhost routing to main app for mail
app.use(vhost('mail.example.com', mailapp))
// route static assets for "assets-*" subdomain to get
// around max host connections limit on browsers
app.use(vhost('assets-*.example.com', staticapp))
fyi, if you are using mean.io then you need to add your middlware in the config/express.js file
I think the best solution would be to have a wildcard for subdomains so anything*.nicksamazingnewapp.com would be traped and then a server side you can decide to where it will point
app.get('/', function(req, res) {
var hostname = req.headers.host.split(":")[0];
if(hostname == "sub1.domain.com")
res.send("this is sub1 response!");
else if(hostname == "sub2.domain.com")
res.send("this is sub2 response!");
});
credits for code goes to #Jazor
you can also try a module https://www.npmjs.org/package/subdomain

How to combine two Node.js App server together.

I have two apps. which current run in two different ports.
script1.js:
var express = require('express'),
app = require('express').createServer(
express.cookieParser(),
// Parses x-www-form-urlencoded request bodies (and json)
express.bodyParser()
)
;
app.get('/s1/output', function(sReq, sRes){
// set cookie
sRes.send('<div>Out from 1!</div>');
});
app.listen(3000);
and here is script2.js
var express = require('express'),
app = require('express').createServer(
express.cookieParser(),
// Parses x-www-form-urlencoded request bodies (and json)
express.bodyParser()
)
;
app.get('/s2/output', function(sReq, sRes){
// set cookie
sRes.send('<div>Out from 2!</div>');
});
app.listen(3001);
ok.. it runs separately on two different ports and have no problem.
Now. the story is that, I can only use port 80 for production. System Admin doesn't want to open 3000 nor other ports.
Instead of merging code. (in fact, my real code is a lot. and have different config settings for script1 and script2), what can I do to make both of them on port 80? but calling /s1/output will go to script1, and /s2/output will go to script2?
I am thinking about having another scripts. script80.js that runs on port 80.
and it require both script1, and script2.
But, the question is, what should I export from script 1 and script2? should I:
define all get / post methods, and then,
module.exports.app =app?
and in script80.js, should I do soemthing like that:
app.get('/s1/*', function (res, req)) {
// and what do now? app1(res) ?
}
mmmm
If you have domains or subdomains pointing to this server, you can also use the vhost middleware:
app.use(express.vhost('s1.domain.com', require('s1').app));
app.use(express.vhost('s2.domain.com', require('s2').app));
app.listen(80);
Complete example: https://github.com/expressjs/express/blob/master/examples/vhost/index.js
You can use nginx listening on port 80 and reverse proxying traffic to the 2 different express app servers behind it.
location /s1/ {
rewrite /s1(.*) $1 break;
proxy_pass http://localhost:3000;
}
location /s2/ {
rewrite /s2(.*) $1 break;
proxy_pass http://localhost:3001;
}
You could also code this by hand in express as you are asking about, but why reinvent the wheel?

Resources