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
Related
I have deployed my Node JS app onto Google Cloud App Engine, and I can successfully add my custom domain for my app.
Let say my custom domain is example.com.
Now I can browse my app via example.com & www.example.com, it works as expected. But I find that I can still browse my app through the default domain.
https://[project-id].appspot.com
I want to disable the default domain, is it possible to do that?
You cannot disable that default domain. You would have to write a redirect script. You can test for "appspot" in the request's HTTP_HOST, and test for "AppEngine-Google" in the request's HTTP_USER_AGENT, to determine if it is an internal request.
Also, internal functions, like cron jobs and task queues, run on that domain, so be careful what you do. Task queues will fail given a 301.
After considering GAEfan suggestion, I have made some change on the router logic. If the host name is ended with "appspot.com" and the user agent is included "AppEngine-Google", it will redirect to my custom domain.
router.get('/', function(req, res, next) {
if(req.get("host").endsWith(GOOGLE_APP_SPOT) &&
req.get("User-Agent").includes(GOOGLE_USER_AGENT))
{
var redirectURL = url.format({
protocol: req.protocol,
host: CUSTOM_DOMAIN,
pathname: req.originalUrl
});
res.redirect(redirectURL);
}
res.render('templateName', viewModel);
});
You can do it just using the dispatch.yaml file from App Engine, list all your domains there, but not the *.appspot.com one. Google will show a 404 route when you try to access that.
EDIT: Not possible anymore, check comments.
Checkout the official reference.
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.
We have a base domain of http://api.mysite.com. This should serve as the front door for all our APIs. Let's say we have two different APIs accessed with the following url structure:
http://api.mysite.com/launchrockets
http://api.mysite.com/planttrees
These are totally different. With regards running this on Heroku it seems we have two options.
1) Put everything inside one application on Heroku. This feels wrong (very wrong) and could lead to a higher chance of changes in one API inadvertently breaking the other.
2) Have 3 different Heroku apps. The first as a proxy (http://mysite-api-proxy.herokuapp.com) that will look at the incoming request and redirect to http://planttrees.herokuapp.com or http://launchrockets.herokuapp.com using a module like bouncy or http-proxy.
I'm leaning towards option 2 but I am concerned about managing the load on the proxy app. For web frameworks that have a synchronous architecture this approach would be disastrous. Yet with node.js using the cluster module and being asynchronous I think this may scale okay.
I've seen similar questions asked before but most related to synchronous frameworks where option 2 would definitely be a poor choice. This question is specific to node and how it would perform.
Thoughts on best way to architect this?
I implemented simple demo project to achieve multi-app structure.
https://github.com/hitokun-s/node-express-multiapp-demo
With this structure, you can easily set up and maintain each app independently.
I hope this would be a help for you.
Here is a blog post I wrote trying to answer this question. There are many options but you have decide what is right for your app and architecture.
http://www.tehnrd.com/host-multiple-node-js-apps-on-the-same-subdomain-with-heroku/
Similar to #TehNrd, I'm using a proxy. However this approach doesn't require multiple heroku apps, just one:
On your web app:
var express = require('express')
, url = require('url')
, api_app = require('../api/server') //this is your other apps index.js or server.js
, app = express()
, httpProxy = require('http-proxy')
, apiport = parseInt(process.env.PORT)+100 || 5100 //this works!
;
// passes all api requests through the proxy
app.all('/api*', function (req, res, next) {
api_proxy.web(req, res, {
target: 'http://localhost:' + apiport
});
});
On your API server:
var express = require('express');
var app = express();
var port = parseInt(process.env.PORT)+100 || 5100;
...
...
app.listen(port);
I'm facing the following situation. In order to further modulize my software development, I've written a few standard modules stand alone. Think for instance of an login module based upon Express and Passport, allowing users to login with all kinds of social services. The module also contains UI for user management, login, registration, profile, etc.
Now, the thing I'm trying to do is to just drop the Auth app folder (containing the express app, all it's routes, views, models, settings and dependecies) into another Express app (for instance, a CMS) and then load it with something like require('./lib/auth/app.js'). I know this is possible, take a look at Kue.
How would I go about doing this? And how do I manage namespacing problems? I could of cours append /auth/ to each route, but I can imagine the settings (app.use()'s) and public folder would conflict with the 'parent' app.js' settings and public folder.
Thanks in advance,
Fabian
Think I found my answer. So, I found this question, and this one. Guess my terminology was off.
I solved my problem by doing a few things. First of all, I changed all routes and url's to be "namespaced" (not really, but this does the job). All routes now have /auth/ in front of them. I did the same to all links, so that's all working.
Next, I removed the server part from my app.js. So, in stead of doing:
require('http').createServer(app).listen(app.get('port'));
I just do:
module.exports = app;
And I add some custom methods to the app object:
app.isLoggedIn = auth.isLoggedIn;
app.notLoggedIn = auth.notLoggedIn;
Then, in my root app, I just do the following to load the auth app in. Routing, public files, and all other stuff happens magically. pretty cool.
var auth = require('./vendor/auth/app');
var app = express();
app.configure(function() {
app.use(auth); // use our auth app
// do a lot of root-app related stuff...
});
Things still to do:
My auth app uses some session stuff. According to the second link, if I understand correctly, the app.use(session...) stuff in my auth app gets overridden by app.use. Also, I want to define an EJS helper to generate my urls (something like site_url('/facebook/callback') which then points to /auth/facebook/callback). Finally, I need to include settings from my root app. I'm thinking of wrapping my entire app.js (in auth) in a function, to which I pass a config object. Like this:
module.exports = function(config) {
var app = express();
app.set('config', config);
// various app settings, routes, etc
// return app so it's available in my root.
return app;
}
I hope this helps, if you need a bit more information I'll see if I can post some code to a gist. just let me know!
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);