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

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

Related

Deploying Sveltekit app proxying api to a backend on different port

I have developed a sveltekit app. During a development phase, I use a Vote configuration to proxy my api to a backend on same domain but different port. It works perfectly but when I compile for deployment the proxy stopped working. I saw that vite provides proxy only during development. How can I have a proxy also in production? Do I need an express project to host my compiled sveltekit app and proxy routes to the backend?
Ok I think I got it.
As mentioned in the official sveltekit node adapter
https://github.com/sveltejs/kit/tree/master/packages/adapter-node
I need to create a custom server for example using expressjs. From there using the http proxy I'm able to forward all the routes /api to the backend on port 3001
import { handler } from './build/handler.js';
import express from 'express';
import proxy from 'express-http-proxy';
const app = express();
const port = 3000;
const backend = 3001;
app.use('/api', proxy(`http://localhost:${backend}`));
app.use(handler);
app.listen(port, () => {
console.log(`Wine Diagnostic Frontend listening on port ${port}`);
console.log(`Reverse proxy forwarding to port ${backend}`);
});
As the guide says, the important thing to do after the sveltekit project is compiled, is to use the handler.js and not app.js in order to use a custom server.

React Front-end connecting to Java Backend on Gitpod HTTPS

I have a project which I have dockerised here: https://github.com/redis-projects/redis-movies/tree/gitpod
I am in the process of trying to get it to work correctly on GitPod, however I am having issues with the frontend react app hitting the backend java service. The react app is running in my local browser so I am confused by which network settings I should use and how to correctly configure.
The docker-compose file when used locally can simply use localhost:8080 to interact with the backend services, but GitPod generates a unique domain over HTTPS. Currently this causes the issues:
Mixed Content: The page at '<URL>' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '<URL>'. This request has been blocked; the content must be served over HTTPS.
This is self-explanatory, I cant make HTTP requests when the site is loaded via HTTPS. & even if I could, its pointing # localhost so the service wont resolve.
How can I setup my docker-compose + gitpod configuration to correctly configure the React URL
Currently use env vars:
REACT_APP_MOVIE_SERVICE_HOST=localhost
REACT_APP_MOVIE_SERVICE_PORT=8080
and this simply builds a url like so (apiConfig.js): http://${process.env.REACT_APP_MOVIE_SERVICE_HOST}:${process.env.REACT_APP_MOVIE_SERVICE_PORT}
Assuming that the backend services are exposed via a public endpoint, I will need to handle any CORs issues since these services are no longer 'local'?

Ngrok and webhooks

I got a problem on my app, and i'm newbie on this tehcnology ...
I have an express app on a heroku url (https://my-website.heroku.com)
I've also this project on a localhost. I want to use the prismic webhook to do some stuff when a document is published.
I try to use ngrok to:
connect it to the heroku website
detect when my /webhook route is called on the heroku app to dispatch it on my localhost server (which is the same project, but I don't know how to do this with ngrok (I used some commands but nothing happen :/ )
Can you help me please ? Thank you !
I might be misunderstanding your use case, but it sounds like what you're wanting to do is handle or detect an incoming request to your heroku app and then proxy or forward that request to your localhost.
One way to handle this would be to -- in response to the original event or request -- then make a second request like a POST request to the Ngrok URL linked to your localhost machine from your heroku app. Ngrok itself is not a real proxy server, it just links two instances of URL/DOMAIN:PORT to each other where one of these runs in the Ngrok cloud service.
So in the code you have handling or receiving the webhook request on the heroku app, you could there make, say, a POST request to the Ngrok URL for your localhost and that request would be forwarded to your localhost machine. I'm not sure what data or information you want to see in localhost but you could pass along any incoming request data in the POST body to your localhost Ngrok URL and then see the same data locally.

Blazor Server Side + Apache + Azure AD

I'm integrating Azure AD into a server side blazor application. It works locally (using https), however when I deploy it to production, the redirect URI in the URL is HTTP, not HTTPS, which then once I log in, Microsoft say the redirect URI isn't valid.
I'm running a VM using Ubuntu and Apache, which is forwarding anything from port 80 to port 443 using a Lets Encrypt certificate, however when it sends the user to Microsoft to login, the redirect URI is http://mydomain.tld, rather than https://mydomain.tld. I think it's because the URL it's running on locally is http://localhost:9000 - But when I put it to https://localhost:9000, it throws an exception on start up as it doesn't have a certificate and as I'm not running on a development machine, I don't really want to install the net core SDK and create dev certificate.
I've seen a few people put this in their code to solve it, however my requests are still going through to Azure AD with a HTTP redirect URI:
var fordwardedHeaderOptions = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
};
fordwardedHeaderOptions.KnownNetworks.Clear();
fordwardedHeaderOptions.KnownProxies.Clear();
app.UseForwardedHeaders(fordwardedHeaderOptions);
Any ideas on how to fix it? I can't imagine I'm the first to be using Blazor behind Apache and connecting via openid.
Two options:
1.Set up Redirect URIs: http://localhost/****
2.Edit the Manifest like below:

Different ports for frontend and backend. How to make a request?

Using Angular-CLI as a frontend. 4200 port
Using Express as a backend. 8080 port
Directories look like:
Application
- backend
- ...Express architecture
- frontend
-...Angular2 architecture
So I'm running two projects, two commanders, one for frontent, second one for backend. node app.js for backend (8080), ng serve for frontent (4200).
Let's assume that I have a layer in backend which returns some string.
app.get('/hello', function(req, res) {
res.send("Hello!");
}
How can I make a request from frontend to backend and get that string? I don't want to know how exactly should I use Angular2 because that's not the point. I'm asking, what technology should I use to be able connect these two (frontent and backend) sides on different ports. If I just run them and make a request from frontend, I'll get an error because it can't find /hello url.
Your request to /hello means an absolute path inside the application running the angular application, so the request goes to http://localhost:4200/hello. Your angular application just doesn't know about the express application you want to target.
absolute urls
If you want to access the hello route on the other (express) application, you need to explicitly specify this by referencing http://localhost:8080/hello.
cors
Doing it this way, the correct application is targeted, but you will likely run into CORS issues, because the browser will prevent the javascript code obtained from localhost:4200 to access a server at localhost:8080. This is a security feature of your browser. So if you want to allow the code at 4200 to access the backend at 8080 your backend can whitelist this so called origin. For details see http://enable-cors.org/ and a corresponding express middleware you could use to support cors in your backend (https://www.npmjs.com/package/cors).
Using this approach has two downsides in my opinion. First, you need a way to tell your frontend under which absolute url it can reach the backend. This must be configurable because you need different urls for dev, staging and production. You then also need a way to manage all your whitelisted urls because the frontend in production will have a different url than when running the frontend in development. This can get pretty cumbersome to handle.
proxying your backend
A better approach in my opinion is to handle this in your infrastructure by proxying the backend in your frontend application. With proxying you basically tell your frontend server that all requests to some url should be passed through to another application. In your case this could probably mean, that for example you configure a proxy for the path /api/ to proxy the application on localhost:8080. The server then doesn't try to find a url like /api/hello on your frontend application but forwards your request to localhost:8080/hello. In your angular application you then don't need to care about the url of your backend and you can then always do a request to a url like /api/some-express-route.
For this to work you need to configure your angular dev server to proxy the requests. For details on how to do this, please see the docs at https://angular.io/guide/build#proxying-to-a-backend-server. When going to production, you can do this by configuring your web server, e.g. nginx to proxy the requests.