Hosting two logically separate apps on one node.js server? - node.js

Currently I have two apps each with their own node.js server, that means there is a lot of duplication, the node_modules are similar, the configuration is similar.
One app is served on the main domain, and the other is served on a sub domain.
The biggest thing is the sessions are separate, so I can't log into one and be logged into both.
How do I create one server to work for app.example.com and example.com so that they share common node_modules and configuration, but I can tailor specific needs for each app in that server?

You may want to look into Nginx, it will allow you to proxy_pass both subdomains to different ports. Here's the sort of setup you will need.
server {
listen 80;
server_name app.example.com;
access_log off;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
proxy_connect_timeout 300;
}
}

Related

URLs Breaking When Hosting Remote Servers Front-End Website on Nginx Proxy

We built an Nginx Server for acting as Edge Proxy for all the ligth weight front-end websites built on different small VMware instances.
The idea is to access the remote server's website like so:
https://nginxserver.mydomain.com/dev/marketing/
And the remote server is configured as upstream in Nginx's config directories:
upstream marketing-dev {
zone marketing-dev-service 64k;
server someserver.mydomain.com:8443;
sticky cookie srv_id expires=1h;
}
And the remote server's dev-marketing.conf file looks like this:
location /dev/marketing/ {
access_log /var/log/nginx/marketing-dev-access.log main;
error_log /var/log/nginx/marketing-dev-debug.log debug;
proxy_pass https://marketing-dev/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
When I access the URL, site loads fine, and I can browse to almost all locations and pages within.
Except for few!!
It is dropping the location /dev/marketing/ in the URL and takes me directly to https://nginxserver.mydomain.com/ or takes me to locations by skipping the path.
For example, https://nginxserver.mydomain.com/aboutus instead of https://nginxserver.mydomain.com/dev/marketing/aboutus
Anyway to overcome this?

How do i configure nginx (and strapis) to correctly serve two strapi instances on the same server?

i want to host two small websites, both made with strapi backend and react frontend, on my server which is a digital ocean droplet.
I already configured nginx in order to work for one of the websites and everything is working correctly. I can access strapi from site1.com/dashboard and my queries point to site1.com/api/graphql. I followed some tutorials for that.
Here are the nginx files i added:
/etc/nginx/sites-available/site1.com:
server {
listen 80;
listen [::]:80;
root /var/www/site1.com/react;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name site1.com www.site1.com;
location /api/ {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://strapi;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass_request_headers on;
}
location /dashboard {
proxy_pass http://strapi/dashboard;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass_request_headers on;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.html;
}
}
file /etc/nginx/conf.d/upstream.conf:
upstream strapi {
server 127.0.0.1:1337;
}
What i now want to do is to deploy another website to the same server and configure nginx to serve it as well (on another domain, for example site2.com).
So i added the nginx virtual server file for the second website, copying the first one and changing the domain name and root directory.
The site 2 frontend is now working correctly and accessible on its domain.
However when i start the site 2 strapi instance it says the port 1337 is already in use (obviously, it is used by site 1 strapi instance that is running with pm2). So i changed the port in strapi config to be 1338 (is it ok?) but now i don't know what do to in nginx in order to serve the two different strapi instances on different domains.
The hostname you are using for the proxy_pass directive is the upstream name you defined in the separate config file. This is basically an indirection to one or more real backends. In your case that's the application running on port 1337 on the same machine. It could also be a list of external domains where nginx takes care to distribute the load to.
Your approach with additional virtual hosts already looks good. The frontend that already "works" under site2 is probably the old instance served under the new domain if your proxy_pass directive still points to http://strapi for site2 (which probably still resolves to `localhost:1337).
As you already mentioned, a second instance of the backend needs to run on a different port. The port number you use is not really important as you will control this with your upstream configuration. Just make sure to not use a port number below 1024 (which requires root permissions), don't conflict with other processes on the system (you will notice) and as best practice, don't use port numbers that are default for some other protocols (maybe check this list).
To fix your setup, just define a second upstream like the first one but pointing to the new url e.g. localhost:1338 and then reference this new name in the proxy_pass directive of site2.
Technically, with just one backend per upstream, you could also skip the upstream part completely and reference the URL directly in the proxy_pass directives, but using a shorthand name can also support readability of your configuration.

How to setup nginx for multiple nodejs apps on a server (using socket.io with namespaces)

We have a nodejs app that currently uses socket.io ( with namespaces ). This app is used as a dashboard for a specific financial market. Each instance of app subscribe to a specific market data and provides a dashboard. Initially we were running 3 separate instances of this app configured for 3 separate markets on the server, all binding to separate ports for serving requests.
Since we plan to add more markets it makes sense to have a reverse proxy server where a single port (along with separate URI for each market) can be used. However, setting up nginx has been a nightmare for various reasons.
(a) each instance of app for a market can be in different development stage and hence can have different static files. Managing all static file via nginx seems painful ? What can be done to leave handling of the static files with the app itself.
(b) socket.io communication is a failure. We tried to look into network communication and it seems it keeps on getting 404 page not found error when trying to connect to socket.io server. Not sure why it is connecting via http::/localhost/server.io/ instead of ws://localhost/server.io/ ? Can somebody point us to a similar example ? Anything that needs to be taken care of ?
IN our case we have been trying the following inside nginx sites-available/default
location /app/ {
proxy_pass http://localhost:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
}
Using nginx as a reversed proxy should not give you a hard time. The great thing about nginx is that you can have multiple projects on the same server with different domains.
Here is an example of nginx with multiple projects:
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://localhost:3000;
#Rember to set the header like this otherwise the socket might not work.
proxy_set_header X-Real-Ip $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
server {
listen 80;
server_name subdomain.yourdomain.com;
location / {
proxy_pass http://localhost:3001;
}
}
I'm not sure why your socket should fail. Perhaps the mistake is that you try to define the route on the client site. Try having the javascript like this:
var socket = io();
or if your socket runs on one of your other applications:
var socket = io('http://yourdomain.com');
And remember that your changes should be added to sites-enabled instead of sites-avaible

Serve static site and node app on port 80 with nginx?

So now I am serving my backend app on mysite:4300 and my static site on mysite:80. This is okay but causes a few problems, one being SSL I would have to get two signed certificates, at least I think.
Another problem which is CORS, it's not a big issue my express app is configured to allow CORS, but I would like to serve it all under one origin.
Here is how my nginx config looks.
I created inside /etc/nginx/conf.d/mysite.com.conf
server {
listen 80;
server_name mysite.com;
location / {
proxy_pass http://localhost:3100; //node js port
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
So basically the above allows me to serve my nodejs app (running with forever.js) for port :3100 on port :80.
This hijacks my static site, obviously but I was wondering how I could possibly configure it to serve on mysite.com/myApp
My Question
How do I configure nginx to serve as a proxy not to mysite.com:80 but mysite.com:80/myApp so I can serve my static website on mysite.com:80?
Do I need to rethink how I am using the proxy, or is there a configuration method I can use?
P.S Following this tut https://www.digitalocean.com/community/tutorials/how-to-host-multiple-node-js-applications-on-a-single-vps-with-nginx-forever-and-crontab
Maybe I need to configure DNS records, or create a subdomain?
Solution: I ended up using a subdomain, but I think it's pretty much the same concpet.
Thanks to #Peter Lyons I have this server block
server {
listen 80;
server_name app.mysite.com;
location / {
root /var/www/mySite/public_html;
proxy_pass http://localhost:3100;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location #app {
proxy_pass http://localhost:3100;
}
}
It wasn't working until I added a root and location #app so now it works fine on port:80 so no more having a port number exposed in the url. Hopefully I can setup SSL for this now!
I think I am going to try and serve it like this mysite.com/myApp to test it, might be handy in the future.
P.S I may also avoid using the subdomain, because it still is considered Cross origin Are AJAX calls to a sub-domain considered Cross Site Scripting?
I may want to allow my app to communicate with my site, and avoiding CORS might make it easier. That is if mysite.com/myAPP is not considered CORS either. We will see.
Try: proxy_pass http://localhost:3100/myApp$uri;, which I think should do what you want.
When I want nginx to serve static files, I use try_files like this:
location / {
root /path/to/my/app/wwwroot;
try_files $uri $uri.html $uri/index.html #app;
}
location #app {
proxy_pass http://localhost:3100;
}

nginx manage local servers depends on income domain name

I have a few applications that are running localy in defferents ports, how can I configure NGINX server for forwarding request from port 80 to my application depends on income domain name. For example 2 local apps named 'app1' on port 8181 , and if request comes from http://app1.com - nginx forwards to http://localhost:8181
I've looked at nginx docs, I ask for your examples if someone did this.
Thanks
Assuming you want to create a reverse proxy, my method is to first configure the following reverse proxy settings in a new file called /etc/nginx/reverse-proxy.conf:
# Serve / from local http server.
# Just add the following to individual vhost configs:
# proxy_pass http://localhost:3001/;
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
Then, for each reverse proxy I'm configuring, I add an appropriately-named configuration file in /etc/nginx/sites-enabled with the following:
server {
server_name app1.com;
server_name www.app1.com;
location / {
include /etc/nginx/reverse-proxy.conf;
proxy_pass http://localhost:8181/;
}
}
You can create as many server blocks as you like and point them at different local (or even remote) application servers. You can also add location blocks to serve different URLs within the same domain statically, or from different local application servers.
(You can also just roll all the configuration into /etc/nginx/nginx.conf, but I find it easier to separate configuration out into multiple files.)
I managed to do this easily by following this tutorial.
Create a new file in /etc/nginx/conf.d/ called your-domain.com.conf and put this in it:
server {
listen 80;
server_name your-domain.conf.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:2368;
}
}
Then restart nginx
sudo service nginx restart

Resources