Simple subdomain with Express - node.js

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,

Related

Express launching Angular application

I have an express server setup online which loads multiple ports and those ports are setup on subdomains for example. port 9000 loads the main domain.com port 8000 loads the main application at "app.domain.com" port 1000 loads "signup.domain.com" and the build version of the app is on port 8500 "build.domain.com".
The application is an Angular application however when I go to load the Angular app it loads on port 4200 or it says 8500 is in use. So currently I am loading that in express like so:
// Build Application - In Development
var appbuild = express();
appbuild.get('/', function (req, res){
res.sendFile('/app/build/myapp/src/index.html', { root: '.' })
});
var port = 8500;
appbuild.listen(port);
console.log('Build App Listening on port', port);
So my question is in Express how can I instead of writing sendfile command make it launch the angular app in that location on port 8500 so my subdomain names will work. The reason I'm asking this is because right now all it does is load the index file but angular or the app isn't running so i just see source code that says app-root and a blank white page.
Thank you in advance.
Robert
--- Update. I've decided to post the entire Express file. My issue is trying to load a angular app on port 8500 from the subfolder upon booting of express. Here is the full server.js code:
// server.js
const express = require('express'),
path = require('path'),
bodyParser = require('body-parser'),
cors = require('cors'),
mongoose = require('mongoose'),
config = require('../config/DB');
mongoose.Promise = global.Promise;
mongoose.connect(config.DB).then(
() => {console.log('Database is connected') },
err => { console.log('Can not connect to the database'+ err)}
);
// 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('Main App Listening on port', port);
// Build Application - In Development
var appbuild = express();
appbuild.get('/', function (req, res){
res.sendFile('/app/build/myapp/src/index.html', { root: '.' })
});
var port = 8500;
appbuild.listen(port);
console.log('Build App Listening on port', port);
// Sign up Portal
var sign = express();
sign.get('/', function (req, res){
res.sendFile('/signup/index.html', { root: '.' })
});
var port = 10000;
sign.listen(port);
console.log('Sign Up Portal Listening on port', port);
Refer to this link https://malcoded.com/posts/angular-backend-express
Update your code to the following:
const express = require('express');
const app = express();
app.listen(8500, () => {
console.log('Server started!');
});
You need to build the angular app if your angular version not 1.x
ng build
Also, I think this question is similar to your question:
Not able to view Angular app via express/heroku?

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);

Host multiple websites using Node.js Express

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

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);
});

Resources