Setting up a website template system in node.js / hapi - virtual hosts - hapi.js

I am working to build a web application that can direct various domain names to template sites in hapi / node. Any suggestions on how I might best set this up would be appreciated. What I've tried is below:
Server 1 has a web application with template websites at /site1, /site2 etc.
Server 2 is a proxy server to direct domains to their proper place. I attempted to use node-http-proxy (https://github.com/nodejitsu/node-http-proxy#setup-a-basic-stand-alone-proxy-server) but it does not support proxying to a specific path, only a url.
//does not work
{
"domain1.com": "http://www.server1.com/site1,
"domain2.com": "http://www.server1.com/site1,
"domain3.com": "http://www.server1.com/site2
}
var server = http.createServer(function(req, res) {
proxy.web(req, res, { target: endpoints[req.headers.host] });
});

Related

How do I make a reverse proxy with nginx on my dockerized express server?

I currently have two docker containers:
- Frontend, which is ran with the flag -p 80:3000 to map my react app to my domain to serve the content
- Backend, which is ran with the flag -p 3001:3001 to map my backend(nodejs/express) to port 3001, where i will access the API routes
When my backend container is running, I can, for example, run curl localhost:3001/example and it will GET the api response back.
My problem is that I have just set up CloudFlare for my domain, so I now have HTTPS enabled, which Express does not support right out of the box (I also tried createServer with https, it didn't work). After doing some research, I discovered that I should be making a reverse proxy with nginx to have those HTTPS requests work with my HTTP server. Is this possible? Currently my backend won't work on my deployed website when I access the HTTPS routes and try to call to it. How do I go about setting up the reverse proxy to allow the HTTPS requests to go into HTTP ? Should I be somehow getting SSL certificate information and putting it somewhere as well? I've been trying to look up tutorials online, but none seem to address something like this from what I could find. Additionally, I found someone on SO that was having a similar problem, but it was never solved. here
For reference, here's a snippet of my backend if that's useful:
const express = require("express");
const webserver = express();
const cors = require("cors");
const mysql = require("mysql");
//connection pool creation
..
webserver.use(cors());
webserver.use(express.json());
// api routes
..
webserver.listen(PORT, () => {
console.log(`[Express] Server running on ${PORT}`);
});

Chrome bypassing server when making static requests to localhost

I have a node express app with middleware that's intercepting all calls before it serves static content:
app.use((req, res, next) => {
console.log(`Request: ${req.url}`)
next()
})
app.use('/', express.static('public'))
The public directory serves up a static website.
I get the initial document request logged when loading the site for the first time, but when I click a link on the site the static HTML content IS loaded, BUT
the chrome dev tools don't show any network request
the express middleware doesn't log any request
I'm trying to debug this middleware (there's additional logic to add), but Chrome isn't even making the request to the localhost express server and seemingly just loads the content direct from disk.
How can I get Chrome to send all localhost requests to the express server?

How do I serve an express + vue app on same domain in Heroku

I have a backend api in express and a front end in vue.js with typescript.
In my development environment, the front end talks to the backend via a proxy server defined in the vue.config.js file...
module.exports = {
devServer: {
proxy: {
"^/api": {
target: 'http://localhost:3002',
changeOrigin: true,
pathRewrite: {"^/api": "/"}
},
}
}
}
So, my front end expects to be served on [address] and it is expecting the express application to be at [address]/api on the SAME address/url.
I was able to achieve this on Digital Ocean App Platform by setting up 2 'components', a backend served from '/api' and a front end component with the Vue.js stuff in it served from '/' on the same domain.
How can I achieve this in Heroku?
I have seen a lot of people (e.g. https://www.youtube.com/watch?v=W-b9KGwVECs) suggest using a build step that builds the front end, copies the static assets back up into a 'public' folder and then uses express to serve the static assets as well as the rest api using this...
app.use(express.static(__dirname + '/public/'));
But is this really the best way to do it? Seems to me like now Express is responsible for the front end and the backend when they should be seperate concerns. Also, what about scaling the back vs the front?, does this work for CDNs?
This seems like such a common use case for something like Heroku, maybe I am just missing something obvious.

NextJS API route conflict

I have been transitioning to NextJS from CRA. I'm re-implementing authentication using SSR, and I would like to use NextJS built-in API routes to set HTTPOnly cookies.
There is a weird problem where my backend base URL is https://somesite.com/api and my frontend's - https://somesite.com/. This means that NextJS built-in API routes will be in conflict with my own backend.
I have been researching online and couldn't find any way on changing routing in NextJS, and I don't want to change base URL of my backend, since there are other services depending on it.
Has anyone had the same issue? How can I resolve this issue?
Try next.js rewrite
Rewrites allow you to map an incoming request path to a different destination path. Docs
Check Live Example here: https://stackblitz.com/edit/nextjs-rewrite
If Path is /api it'll point to JSON placeholder APIs.(ex. /api/todos)
module.exports = {
async rewrites() {
return [
{
source: '/api/:slug*',
destination: 'https://jsonplaceholder.typicode.com/:slug*'
}
];
}
};

Use KeystoneJS as a blog, but only part of the webapp

I've got a NodeJS + Angular + MySQL webapp. Is there a way I could use KeystoneJS for blog only?
I am currently serving some pages as static Express pages, and some as an Angular App with UI Router's HTML5 mode enabled.
// Serves static pages generated by Express
app.use('/staticPage', staticPage);
app.use('/anotherStaticPage', anotherStaticPage);
// Serves Angular App
app.all('/*', function(req, res, next) {
res.sendFile(__dirname + '/ui/index.html');
});
/*
Need a way to also serve a blog powered by KeystonJS
It should be accessed at /blog/:postTitle
*/
If possible, I prefer to keep my existing set-up and simply add Keystone on top of it.
There are two ways you can do so.
(1) install keystone, and inside keystones index router, add your two static routers and one app router too.
(2) Add keystone to existing Express App.
However irrespective of keystoneJS. you have to remove generic handler for angularApp.
app.all('/app/*', function(req, res, next) {...});
Or else new blog related router has to be added above Angular, as you are doing so far.