How to configure single instance Beanstalk Node.js app without ELB? - node.js

I am migrating an app to Beanstalk, and I want to make it clear that the following questions are only about single instance configuration without using Elastic Load Balancer.
Current configuration:
Node.js app running on ports 8081 (HTTP) and 8082 (HTTPS)
Node.js serving static files under /server/public at /
Node.js serving APIs at /api
My basic question is, how do I get incoming traffic to 80 being redirected to 8081? What settings and where do I have to do? Do I need to set up a proxy, such as Nginx, and if I do, what kind of settings do I have to do? I tried going through AWS documentation, but it contains mostly information on setting up Elastic Load Balancer (ELB), and in this case I especially want to set up the system without ELB.
The next question is, what settings and where do I have to do if I wanted to terminate HTTPS on Nginx proxy? I tried the official instructions, but couldn't get them working.

Yeah you can setup nginx as a proxy to pass all requests on port 80 (or 443) to the respective nginx port. Like, :
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://APP_PRIVATE_IP_ADDRESS:8081;
}

Related

Hosting Vue app with Nginx and Express api on same host. Do I need two SSL certs, how to configure nginx?

I have an Ubuntu VPS, and I have dockerized a simple Vue App, which is served by Nginx. I have set up SSL for it.
On same host, I have a container running Nodejs Express, which is routing simple queries to MySql database. Express is listening port 8080.
Everything works invidually - I can access the site with 443, and separately I can access the rest api with http://domain:8080 in Postman.
I have however been stuck with how to get Express to listen for https requests so I can use the rest api within the site.
Do I need another SSL cert for the Express? Or is enough if I bypass some url to the localhost:8080? Obviously I still want the site to be accessible with https://domain
What did I miss? Or did I miss it totally?
What I tried was something like:
location /api {
proxy_pass http://localhost:8080;
}
Within both 80 and 443 nginx listeners.
I however always get 502 badateway, if I try to access https://domain/api/foo. I expected it to return response from http://domain:8080/foo.
What I was doing wrong was that the nginx container passed proxy to localhost, which of course I realized a bit late that was pointing to nginx container localhost, not the actual host.
I rewrote my compose.yml, the containers are now in the same network, which provides access to nodejs container in the nginx conf.
Now it works as expected.

Is there a way to "host" an existing web service on port X as a network path of another web service on port 80?

What I'm trying to do is create an access website for my own services that run on my linux server at home.
The services I'm using are accessible through <my_domain>:<respective_port_num>.
For example there's a plex instance which is listening on port X and transmission-remote (a torrenting client) listening on port Y and another custom processing service on port Z
I've created a simple website using python flask which I can access remotely which redirects paths to ports (so <my_domain>/plex turns into <my_domain>:X), is there a way to display these services on the network paths I've assigned to them so I don't need to open ports for each service? I want to be able to channel an existing service on :X to <my_domain>/plex without having to modify it, I'm sure it's possible.
I have a bit of a hard time to understand your question.
You certainly can use e.g. nginx as a reverse proxy in front of your web application, listen to any port and then redirect it to the upstream application on any port - e.g. your Flask application.
Let's say, my domain is example.com.
I then can configure e.g. nginx to listen on port 80 (and 443 for SSL), and then proxy all requests to e.g. port 8000, where Flask is running locally.
Yes, this is called using nginx as a reverse proxy. It is well documented on the internet and even the official docs. Your nginx.conf would have something like:
location /my/flask/app/ {
# Assuming your flask app is at localhost:8000
proxy_pass http://localhost:8000;
}
From user's perspective, they will be connecting to your.nginx.server.com/my/flask/app/. But behind the scenes nginx will actually forward the request to your app, and serve its response back to the user.
You can deploy nginx as a Docker container, I recommend doing this as it will keep the local files and configs separate from your own work and make it easier for you to fiddle with it as you learn. Keep in mind that nginx is only HTTP though. You can't use it to proxy things like SSH or arbitrary protocols (not without a lot of hassle anyway). If the services generate their own URLs, you might also need to configure them to anticipate the nginx redirects.
BTW, usually flask is not served directly to the internet, but instead nginx talks to something like Gunicorn to handle various network related concerns: https://vsupalov.com/what-is-gunicorn/

Node - Set virtual host on local computer

I'm trying to set virtual host on my local machine for my Node (Express) project. But I cant figure out how to avoid port number
This is what I had entered on my /etc/hosts file.
192.168.151.207 www.potato.com
192.168.151.207 www.tomato.com
I can access site by www.potato.com:3000 but I want it to be simply www.potato.com.
I was Googling for last few days but all most all the solution says to use Nginx for reverse proxy. I also read somewhere that if I use Nginx I can't use Socket. And socket is something which I have to use in next phase of the project.
Any help is heartily appreciated.
Did you try virtualhost npm package?
Make your HTTP server hostname-aware very simply.
You define the handler for each server name, and that will return the
final handler to be passed to your HTTP server.
Works fine with Express.
You only need to use nginx or any orther proxy solution (there are nodejs modules too you could integrate with your application) if you want serve each virtualhost with different applications (because they cannot listen to the same port).
Here the answer to my question. I use Nginx only and setup a reverse proxy.
First on my /etc/hosts file I add the domain which I want to use.
127.0.0.1 tomato.com
This means whenever I open this URL "tomato.com" browser will change for 127.0.0.1. But my Express server is running on 127.0.0.1:3000. Now we need to point 127.0.0.1 to 127.0.0.1:3000. Using Nginx we can configure this. Below given line of code does this. /etc/nginx/sites-available/tomato.conf
server_name tomato.com;
location / {
proxy_pass "http://127.0.0.1:3000/"
}
For more detail check this post from Digitalocean

Forward HTTPS traffic thru Nginx without SSL certificate

I want to use Nginx to expose my NodeJS server listening on port 443.
I don't want to manage the SSL certificate with Nginx. I would rather do that on the NodeJS server using the SNICallback option of https.createServer.
How do I setup the nginx.conf to support this?
You're looking for ssl pass-through. You'll set up your nginx to use TCP load balancing (even if you only have one server it's still thought of as load balancing) and ssl passthrough.
Note that nginx will be unable to access any of the content and that you will lose almost all of the advantages of using a proxy other than the ability to do load balancing.
See these instructions for a specific configuration example.
You can configure nginx to pass the encrypted traffic to the node.js server.
stream {
server {
listen 443;
proxy_pass your.node.js:443;
}
}
Note that you will have no access-log or any other means of access to the data.

How can I serve some URLs from express.js by making requests to another web application?

I have written some code using express.js which I'd like to put on the same HTTP port as a web application implemented with another technology (in this case, Django). I don't want to have to redirect user browsers to another port since if I do they might bookmark URLs with the other port, and then I lose the ability to reconfigure the arrangements later. So, I'd like express.js to serve HTTP on its port, fulfilling some paths I specify by making HTTP requests to a secondary web application which is being served on another port.
Is there any middleware or other technique for express.js which will serve certain paths by making HTTP requests to other servers?
(The stackoverflow question How to make web service calls in Expressjs? is relevant but only discusses GET and I will have some POST requests to forward.)
Whilst it is possible to make POST request with node, I think the pattern you're describing is better suited to using a a server like nginx or apache in front of both node.js and django, and proxying requests to whichever port is appropriate based on the request.
Typically, both django and node.js would listen on whichever ports you want them to listen on, while nginx listens on port 80. You then define a virtual host in nginx that forwards certain requests to node.js and certain requests to django.
Here are the nginx docs on using proxy_pass.
Here is an example, modified from the nginx Full Example:
server { # simple reverse-proxy
listen 80;
server_name domain2.com www.domain2.com;
# serve static files
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
root /var/www/virtual/big.server.com/htdocs;
}
# pass requests for dynamic content to django
location /djangostuff {
proxy_pass http://127.0.0.1:8080;
}
# pass requests for node
location /nodestuff {
proxy_pass http://127.0.0.1:8081;
}
}
With node-http-proxy only a single call to app.use is required to reverse proxy all unhandled requests, like this:
var app = express.createServer();
# my app.get bindings
app.use(require('http-proxy').createServer(80, 'other-server-address'));
app.listen(80);

Resources